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/purepostscript.cpp

241 lines
7.2 KiB

/***************************************************************************
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 <stdlib.h>
#include <tqdom.h>
#include <tqfile.h>
#include <tqtextstream.h>
#include <kstandarddirs.h>
#include <tdetempfile.h>
#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<const PurePostscriptOptions*>(&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<const PurePostscriptOptions*>(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;
}