/*************************************************************************** purepostscript.cpp - description ------------------- begin : Mon Jan 2 2006 copyright : (C) 2006 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 "purepostscript.h" #include "barkode.h" #include #include #include #include #include #include #define MAX_LINE_LENGTH 256 #define BEGIN_TEMPLATE "--BEGIN TEMPLATE--" #define END_TEMPLATE "--END TEMPLATE--" TQString PurePostscriptBarcode::s_path = TQString(); PurePostscriptOptions::PurePostscriptOptions() : BarkodeEngineOptions() { defaults(); } const BarkodeEngineOptions& PurePostscriptOptions::operator=( const BarkodeEngineOptions& rhs ) { const PurePostscriptOptions* ps = (dynamic_cast(&rhs)); m_check = ps->m_check; return *this; } void PurePostscriptOptions::defaults() { m_check = false; } void PurePostscriptOptions::load( const TQDomElement* tag ) { m_check = (bool)tag->attribute( "pure.check", "0" ).toInt(); } void PurePostscriptOptions::save( TQDomElement* tag ) { tag->setAttribute( "pure.check", (int)m_check ); } PurePostscriptBarcode::PurePostscriptBarcode() : PixmapBarcode() { bool append = false; TQString line; if( s_path.isNull() ) { tqDebug( "Cannot locate barcode writer in pure postscript." ); return; } TQFile pureFile( s_path ); if( pureFile.open( IO_ReadOnly ) ) { while( pureFile.readLine( line, MAX_LINE_LENGTH ) != -1 ) { if( append ) { if( line.contains( END_TEMPLATE ) ) break; m_program.append( line ); } if( !append && line.contains( BEGIN_TEMPLATE ) ) append = true; } pureFile.close(); } } PurePostscriptBarcode::~PurePostscriptBarcode() { } void PurePostscriptBarcode::init() { if( s_path.isNull() ) { // first look at the default location const char* default_barcode = "/usr/share/libpostscriptbarcode/barcode.ps"; if( TQFile::exists( default_barcode ) ) s_path = default_barcode; else s_path = locate( "data", "kbarcode/barcode.ps" ); } if( !TQFile::exists( s_path ) ) s_path = TQString(); } #define START_TOKEN "% --" #define BEGIN_ENCODER "BEGIN ENCODER " #define DESCRIPTION "DESC: " #define EXAMPLE "EXAM: " void PurePostscriptBarcode::initInfo( TBarcodeInfoList* info ) { PurePostscriptBarcode::init(); TQFile pureFile( s_path ); if( pureFile.open( IO_ReadOnly ) ) { TQString encoder; TQString description; TQString example; TQString line; while( pureFile.readLine( line, MAX_LINE_LENGTH ) != -1 ) { /* % --BEGIN ENCODER ean13-- % --DESC: EAN-13 % --EXAM: 977147396801 */ if( line.startsWith( START_TOKEN ) ) { // remove all whitespaces on the line ending (and '-') line = line.stripWhiteSpace(); line = line.right( line.length() - TQString( START_TOKEN ).length() ); if( line.startsWith( BEGIN_ENCODER ) ) { encoder = line.right( line.length() - TQString( BEGIN_ENCODER ).length() ); if( encoder.endsWith( "--" ) ) encoder = encoder.left( encoder.length() - 2 ); } else if( line.startsWith( DESCRIPTION ) ) description = line.right( line.length() - TQString( DESCRIPTION ).length() ); else if( line.startsWith( EXAMPLE ) ) { example = line.right( line.length() - TQString( EXAMPLE ).length() ); // we should have a complete encoder now. info->append( Barkode::createInfo( TQString("ps_") + encoder, description, PURE_POSTSCRIPT, PUREADV | COLORED ) ); } } } pureFile.close(); } } bool PurePostscriptBarcode::hasPurePostscriptBarcode() { return !s_path.isNull(); } void PurePostscriptBarcode::createProgram( TQString & prg ) { const PurePostscriptOptions* options = (dynamic_cast(barkode->engine()->options())); TQString type = barkode->type().right( barkode->type().length() - 3 ); TQString opt; opt.sprintf( "%s %s barcolor=%02X%02X%02X showbackground backgroundcolor=%02X%02X%02X textcolor=%02X%02X%02X", barkode->textVisible() ? "includetext" : "", options && options->checksum() ? "includecheck" : "", barkode->foreground().red(), barkode->foreground().green(), barkode->foreground().blue(), barkode->background().red(), barkode->background().green(), barkode->background().blue(), barkode->textColor().red(), barkode->textColor().green(), barkode->textColor().blue() ); prg = "%!PS-Adobe-2.0 EPSF-2.0\n%%EndComments\n%%EndProlog\n"; prg += m_program; prg += TQString("20 20 moveto\n(%1) (%2) %3 barcode\n") .arg( barkode->parsedValue() ) .arg( opt ).arg( type ); } TQRect PurePostscriptBarcode::bbox( const char* postscript, long postscript_size ) { const char* gs_bbox = "gs -sDEVICE=bbox -sNOPAUSE -q %1 -c showpage quit 2>&1"; char* buffer = NULL; long len = 0; TQRect size; KTempFile psfile( TQString(), ".ps" ); psfile.file()->writeBlock( postscript, postscript_size ); psfile.file()->close(); if( !readFromPipe( TQString( gs_bbox ).arg( psfile.file()->name() ).latin1(), &buffer, &len ) || !len ) { psfile.unlink(); return TQRect( 0, 0, 0, 0 ); } else psfile.unlink(); size = PixmapBarcode::bbox( buffer, len ); free( buffer ); return size; } bool PurePostscriptBarcode::createPostscript( char** postscript, long* postscript_size ) { TQString cmd; if( m_program.isEmpty() ) return false; createProgram( cmd ); *postscript_size = cmd.length(); *postscript = (char*)malloc( sizeof(char) * *postscript_size ); if( !*postscript ) return false; memcpy( *postscript, cmd.latin1(), *postscript_size ); return true; }