/*************************************************************************** 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 #include #include #include #include #include #include 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= 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; }