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.
kbarcode/kbarcode/imageitem.cpp

308 lines
7.9 KiB

/***************************************************************************
imageitem.h - description
-------------------
begin : Do Sep 9 2004
copyright : (C) 2004 by Dominik Seichter
email : domseichter@web.de
***************************************************************************/
/***************************************************************************
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 "imageitem.h"
#include "tokenprovider.h"
#include <qbuffer.h>
#include <qdom.h>
#include <qimage.h>
#include <qpaintdevicemetrics.h>
#include <qpainter.h>
#include <klocale.h>
#include <kmdcodec.h>
ImageItem::ImageItem()
: DocumentItem()
{
init();
}
ImageItem::~ImageItem()
{
}
void ImageItem::init()
{
m_rotation = 0.0;
m_mirror_h = false;
m_mirror_v = false;
m_scaling = eImage_Original;
setBorder( false );
setRect( QRect( 0, 0, 20, 20 ) );
}
void ImageItem::draw(QPainter* painter)
{
createImage();
painter->save();
painter->drawPixmap( rect().x(), rect().y(), m_tmp );
painter->restore();
DocumentItem::drawBorder(painter);
}
void ImageItem::drawZpl( QTextStream* stream )
{
createImage();
QBuffer buffer;
if( buffer.open( IO_WriteOnly ) )
{
// TODO: bmp????
QImageIO io( &buffer, "PNG" );
QImage image = m_tmp.convertToImage();
// create a black and white image
io.setImage( image.convertDepth( 1 ) );
io.write();
buffer.close();
QByteArray data = buffer.buffer();
*stream << ZPLUtils::fieldOrigin( rect().x(), rect().y() );
*stream << "~DYD,p,P," << QString::number( data.size() ) + ",0,";
for( unsigned int i=0;i<data.size();i++)
*stream << data[i];
}
}
void ImageItem::drawIpl( QTextStream*, IPLUtils* )
{
qDebug("ImageItem is not implemented for IPL!");
}
void ImageItem::drawEPcl( QTextStream* stream )
{
createImage();
// you can access m_tmp (which is a QPixmap now)
// m_tmp is an image which has all transformations
// (i.e. rotation, scaling, flipping) already apllied
QImage si = m_tmp.convertToImage();
int width = si.width();
int height = si.height();
int c;
char out;
for( int buf=0; buf < 3; buf++ ){
*stream << QString("GS %1 32 %1 %1 %1 %1 ")
.arg(buf).arg(rect().x()).arg(rect().y()).arg(width).arg(height);
for( int i=width-1; i >= 0; i-- ){
for( int j=0; j < height; j++ ){
if( buf == 0 )
c = qBlue(si.pixel(i,j)); // Yellow
else if( buf == 1 )
c = qGreen(si.pixel(i,j)); // Magenta
else if( buf == 2 )
c = qRed(si.pixel(i,j)); // Cyan
// printer has 5-bits per color - drop 3
// we also need to subtract from 255 to convert from RGB to CMY
out = (0xff - c) >> 3;
*stream << out;
}
}
*stream << "\r\n";
}
}
void ImageItem::loadXML(QDomElement* element)
{
QByteArray out;
if( !element->text().isEmpty() )
{
KCodecs::base64Decode( element->text().utf8(), out );
m_pixmap.loadFromData( out, "PNG" );
}
m_expression = element->attribute( "expression", QString::null );
m_scaling = (EImageScaling)element->attribute( "scaling", "0" ).toInt();
m_mirror_h = (bool)element->attribute("mirror_horizontal", "0" ).toInt();
m_mirror_v = (bool)element->attribute("mirror_vertical", "0" ).toInt();
m_rotation = element->attribute("rotation", "0.0").toDouble();
DocumentItem::loadXML(element);
updateImage();
}
void ImageItem::saveXML(QDomElement* element)
{
QBuffer buf;
if( !m_pixmap.isNull() )
{
if(!buf.open( IO_WriteOnly ))
return;
m_pixmap.save( &buf, "PNG" );
buf.close();
element->appendChild( element->ownerDocument().createCDATASection( KCodecs::base64Encode( buf.buffer(), true ) ) );
}
element->setAttribute( "expression", m_expression );
element->setAttribute( "scaling", (int)m_scaling );
element->setAttribute( "mirror_horizontal", m_mirror_h );
element->setAttribute( "mirror_vertical", m_mirror_v );
element->setAttribute( "rotation", m_rotation );
DocumentItem::saveXML(element);
}
void ImageItem::setExpression( const QString & ex )
{
m_expression = ex;
updateImage();
}
void ImageItem::setPixmap( const QPixmap & pix )
{
m_pixmap = pix;
updateImage();
}
const QPixmap & ImageItem::pixmap()
{
return m_pixmap;
}
void ImageItem::setScaling( EImageScaling scaling )
{
m_scaling = scaling;
updateImage();
}
EImageScaling ImageItem::scaling() const
{
return m_scaling;
}
void ImageItem::updateImage()
{
m_tmp.resize( QSize(0,0) );
}
void ImageItem::createImage()
{
if( m_tmp.isNull() )
{
QImage img;
if( m_pixmap.isNull() )
img.load( tokenProvider() ? tokenProvider()->parse( m_expression ) : m_expression );
else
img = m_pixmap.convertToImage();
if( !img.isNull() )
{
if( m_rotation != 0.0 )
{
QWMatrix matrix;
matrix.rotate( m_rotation );
img = img.xForm( matrix );
}
// scale with high quality on the printer
// but use faster scaling for onscreen operations
if( m_scaling != eImage_Original )
{
if( DocumentItem::paintDevice()->isExtDev() )
img = img.smoothScale( rect().width(), rect().height(),
(m_scaling == eImage_Scaled ? QImage::ScaleMin : QImage::ScaleFree) );
else
img = img.scale( rect().width(), rect().height(),
(m_scaling == eImage_Scaled ? QImage::ScaleMin : QImage::ScaleFree) );
}
else
{
// we have to scale because of the bigger printer resolution
if( DocumentItem::paintDevice()->isExtDev() )
{
QPaintDeviceMetrics metrics( DocumentItem::paintDevice() );
img = img.smoothScale( (int)(img.width() * ((double)metrics.logicalDpiX()/QPaintDevice::x11AppDpiX())),
(int)(img.height() * ((double)metrics.logicalDpiY()/QPaintDevice::x11AppDpiY())),
QImage::ScaleMin );
}
}
if( m_mirror_h || m_mirror_v )
img = img.mirror( m_mirror_h, m_mirror_v );
m_tmp.convertFromImage( img );
}
else
{
// The expression does not return a valid image path
// or the user did not specify a image to load
// make sure that we do not get a 0 0 0 0 rectangle
QRect myrect( 0, 0, rect().width() ? rect().width() : 100 , rect().height() ? rect().height() : 80 );
m_tmp.resize( rect().width(), rect().height() );
QPainter painter( &m_tmp );
painter.fillRect( myrect, Qt::white );
painter.setPen( QPen( Qt::red, 2 ) );
painter.drawRect( myrect );
painter.drawLine( 0, 0, myrect.width(), myrect.height() );
painter.drawLine( 0, myrect.height(), myrect.width(), 0 );
painter.setPen( Qt::black );
painter.drawText( 0, painter.fontMetrics().lineSpacing(), i18n("Expression: ") + m_expression );
painter.end();
}
}
}
void ImageItem::setRotation( double rot )
{
if( m_rotation <= 360.0 && m_rotation >= -360.0 )
{
m_rotation = rot;
updateImage();
}
}
double ImageItem::rotation() const
{
return m_rotation;
}
void ImageItem::setMirrorHorizontal( bool b )
{
m_mirror_h = b;
updateImage();
}
bool ImageItem::mirrorHorizontal() const
{
return m_mirror_h;
}
void ImageItem::setMirrorVertical( bool b )
{
m_mirror_v = b;
updateImage();
}
bool ImageItem::mirrorVertical() const
{
return m_mirror_v;
}