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 <tqbuffer.h>
#include <tqdom.h>
#include <tqimage.h>
#include <tqpaintdevicemetrics.h>
#include <tqpainter.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( TQRect( 0, 0, 20, 20 ) );
}
void ImageItem::draw(TQPainter* painter)
{
createImage();
painter->save();
painter->drawPixmap( rect().x(), rect().y(), m_tmp );
painter->restore();
DocumentItem::drawBorder(painter);
}
void ImageItem::drawZpl( TQTextStream* stream )
{
createImage();
TQBuffer buffer;
if( buffer.open( IO_WriteOnly ) )
{
// TODO: bmp????
TQImageIO io( &buffer, "PNG" );
TQImage image = m_tmp.convertToImage();
// create a black and white image
io.setImage( image.convertDepth( 1 ) );
io.write();
buffer.close();
TQByteArray data = buffer.buffer();
*stream << ZPLUtils::fieldOrigin( rect().x(), rect().y() );
*stream << "~DYD,p,P," << TQString::number( data.size() ) + ",0,";
for( unsigned int i=0;i<data.size();i++)
*stream << data[i];
}
}
void ImageItem::drawIpl( TQTextStream*, IPLUtils* )
{
tqDebug("ImageItem is not implemented for IPL!");
}
void ImageItem::drawEPcl( TQTextStream* stream )
{
createImage();
// you can access m_tmp (which is a TQPixmap now)
// m_tmp is an image which has all transformations
// (i.e. rotation, scaling, flipping) already apllied
TQImage si = m_tmp.convertToImage();
int width = si.width();
int height = si.height();
int c;
char out;
for( int buf=0; buf < 3; buf++ ){
*stream << TQString("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 = tqBlue(si.pixel(i,j)); // Yellow
else if( buf == 1 )
c = tqGreen(si.pixel(i,j)); // Magenta
else if( buf == 2 )
c = tqRed(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(TQDomElement* element)
{
TQByteArray out;
if( !element->text().isEmpty() )
{
KCodecs::base64Decode( element->text().utf8(), out );
m_pixmap.loadFromData( out, "PNG" );
}
m_expression = element->attribute( "expression", TQString() );
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(TQDomElement* element)
{
TQBuffer 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 TQString & ex )
{
m_expression = ex;
updateImage();
}
void ImageItem::setPixmap( const TQPixmap & pix )
{
m_pixmap = pix;
updateImage();
}
const TQPixmap & 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( TQSize(0,0) );
}
void ImageItem::createImage()
{
if( m_tmp.isNull() )
{
TQImage 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 )
{
TQWMatrix 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 ? TQ_ScaleMin : TQ_ScaleFree) );
else
img = img.scale( rect().width(), rect().height(),
(m_scaling == eImage_Scaled ? TQ_ScaleMin : TQ_ScaleFree) );
}
else
{
// we have to scale because of the bigger printer resolution
if( DocumentItem::paintDevice()->isExtDev() )
{
TQPaintDeviceMetrics metrics( DocumentItem::paintDevice() );
img = img.smoothScale( (int)(img.width() * ((double)metrics.logicalDpiX()/TQPaintDevice::x11AppDpiX())),
(int)(img.height() * ((double)metrics.logicalDpiY()/TQPaintDevice::x11AppDpiY())),
TQ_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
TQRect myrect( 0, 0, rect().width() ? rect().width() : 100 , rect().height() ? rect().height() : 80 );
m_tmp.resize( rect().width(), rect().height() );
TQPainter painter( &m_tmp );
painter.fillRect( myrect, TQt::white );
painter.setPen( TQPen( TQt::red, 2 ) );
painter.drawRect( myrect );
painter.drawLine( 0, 0, myrect.width(), myrect.height() );
painter.drawLine( 0, myrect.height(), myrect.width(), 0 );
painter.setPen( TQt::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;
}