diff options
Diffstat (limited to 'kbarcode/gnubarcode.cpp')
-rw-r--r-- | kbarcode/gnubarcode.cpp | 348 |
1 files changed, 348 insertions, 0 deletions
diff --git a/kbarcode/gnubarcode.cpp b/kbarcode/gnubarcode.cpp new file mode 100644 index 0000000..6f69644 --- /dev/null +++ b/kbarcode/gnubarcode.cpp @@ -0,0 +1,348 @@ +/*************************************************************************** + gnubarcode.cpp - description + ------------------- + begin : + copyright : (C) 2005 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 "gnubarcode.h" + +#ifdef _ENABLE_NATIVE_GNU_BARCODE + +#include <barcode.h> +#include "barkode.h" +#include <string.h> +#include <ctype.h> + +#include <qfont.h> +#include <qpainter.h> +#include <qpaintdevicemetrics.h> + +#include <klocale.h> + +#define FONT_SPACE (2*m_scaley) +#define SHRINK_AMOUNT 0.15 +#define MUL_FACTOR 10 + +GnuBarcode::GnuBarcode() + : BarkodeEngine() +{ + m_item = NULL; + m_size = QSize( 0, 0 ); + + m_scalex = 1.0; + m_scaley = 1.0; + + m_font_size = 10; +} + +GnuBarcode::~GnuBarcode() +{ + if( m_item ) + Barcode_Delete( m_item ); +} + +void GnuBarcode::update( const QPaintDevice* device ) +{ + QString val = barkode->parsedValue(); + m_valid = false; + + if( m_item ) + { + qDebug("Deleting"); + Barcode_Delete( m_item ); + m_item = NULL; + } + + if( val.isEmpty() ) + return; + + char* value = new char[val.length()+1]; + strncpy( value, val.latin1(), val.length()+1 ); + value[val.length()] = '\0'; + + m_item = Barcode_Create( value ); + if( !m_item ) + { + Barcode_Delete( m_item ); + m_item = NULL; + delete [] value; + return; + } + + if( Barcode_Encode( m_item, Barkode::internalType( barkode->type() ) ) == -1 ) + { + Barcode_Delete( m_item ); + m_item = NULL; + + delete [] value; + return; + } + + delete [] value; + + QPaintDeviceMetrics metrics( device ); + m_scalex = (double)metrics.logicalDpiX() / (double)QPaintDevice::x11AppDpiX(); + m_scaley = (double)metrics.logicalDpiY() / (double)QPaintDevice::x11AppDpiY(); + + // 72.0 is the postscript resolution generated by GNU barcode + m_scale_ps_x = (double)metrics.logicalDpiX() / 72.0; + m_scale_ps_y = (double)metrics.logicalDpiY() / 72.0; + +/* m_scalex *= m_scale_ps_x; + m_scaley *= m_scale_ps_y;*/ + + m_font_size = (int)(barkode->fontsize() * barkode->scaling() * m_scaley); + setupSize(); + m_valid = true; +} + +const QSize GnuBarcode::size() const +{ + if( m_size.isNull() ) + return QSize( 100, 80 ); + else + return m_size; +} + +void GnuBarcode::drawBarcode( QPainter & painter, int x, int y ) +{ + int dx = x + barkode->quietZone(); + int dy = y + barkode->quietZone(); + + if( !m_item ) + { + barkode->drawInvalid( painter, x, y ); + return; + } + + painter.save(); + painter.scale( m_scalex, m_scaley ); + + // based on David J. Humphreys barcode-svg + // Draw the bars + drawBars( &painter, (int)(dx/m_scalex), (int)(dy/m_scaley) ); + + // Only scale for the bars, text should be scaled + // correctly by Qt on Qt >= 3.3.2 + painter.restore(); + + // draw the text + if( barkode->textVisible() ) + drawText( &painter, dx, dy ); +} + +void GnuBarcode::setupSize() +{ + m_bar_height = (int)(barkode->barHeight() * barkode->scaling() * barkode->cut()); + m_barcode_height = m_bar_height; + if( barkode->textVisible() ) + m_barcode_height += (int)(m_font_size/2 + FONT_SPACE*2); + + unsigned int width = drawBars( 0 , 0, 0 ); + unsigned int twidth = drawText( 0, 0, 0 ); + + //if(m_item->height == 0) + m_item->height = m_barcode_height + (2 * barkode->quietZone()); + + width = ( width > twidth ? width : twidth ); + width += 2* barkode->quietZone(); + + //if(m_item->width == 0) + m_item->width = width; + + m_size.setWidth( (int)(m_item->width * m_scalex) ); + m_size.setHeight( (int)(m_item->height * m_scaley) ); +} + +int GnuBarcode::drawBars( QPainter* painter, int x, int y ) +{ +#if 0 + int height = 0; // height of the bar to draw + int xpos = 0; // Where the current box is drawn + int current = 0; + unsigned int i = 0; + + qDebug("Partial=%s\n", m_item->partial ); + for( i = 0; i < strlen(m_item->partial); i++) + { + current = (int)m_item->partial[i] - ASCII_ZERO; + /* Guide bar */ + if(current > 9) + { + height = m_barcode_height; + current = (int)m_item->partial[++i] - ASCII_ZERO; + i++; /* Skip the following 'a' */ + } + else + height = m_bar_height; + + current *= barkode->scaling(); + + if( current < 0 ) + { + qDebug("current < 0: %i", current ); + current = 0; + break; + } + + if( i % 2) + { + painter.fillRect( x + xpos, y, current, height, barkode->foreground() ); + } + + xpos += current; + } +#endif + int xpos; + int mode = '-'; // text below bars + char *ptr; + int i, j; + int x0, yr, y0; + + xpos = m_item->partial[0]-'0'; + + for (ptr = m_item->partial+1, i=1; *ptr; ptr++, i++) + { + /* special cases: '+' and '-' */ + if (*ptr == '+' || *ptr == '-') + { + mode = *ptr; /* don't count it */ i++; continue; + } + /* j is the width of this bar/space */ + if (isdigit (*ptr)) + j = *ptr-'0'; + else + j = *ptr-'a'+1; + + j = (int)( j * barkode->scaling() ); + if (i%2) + { + x0 = xpos + j/2; + y0 = y; + yr = m_barcode_height; + + if( barkode->textVisible() ) + { + // leave space for text + if (mode == '-') + { + // text below bars + if( isdigit( *ptr ) ) + yr = m_bar_height; + else + yr = m_barcode_height; + } else { /* '+' */ + // text above bars + // TODO: this needs testing and a GUI + if( isdigit( *ptr ) ) + yr = m_bar_height; + else + { + yr = m_barcode_height; + y0 += (m_barcode_height - m_bar_height); + } + } + } + + if( painter ) + { + painter->fillRect( x + x0, y0, j, yr, barkode->foreground() ); + } + //qDebug("Bar = %i", j ); + } + xpos += j; + } + + return xpos; +} + +int GnuBarcode::drawText( QPainter* painter, int x, int y ) +{ +#if 0 + unsigned int infosz = strlen( m_item->textinfo ); + unsigned int correction = 0; // This correction seems to be needed to align text properly + unsigned int j = 0; + unsigned int i = 0; + int prev_x = 0; + int xpos = 0; + + double dub1, fsize; + char printer; + char *temp_info = new char[infosz+1]; + + painter.setFont( QFont( "Helvetica", 12 ) ); + while(i < infosz) + { + for(j = 0; m_item->textinfo[i + j + 1] != ' ' && + m_item->textinfo[i + j + 1] != '\0';j++); /* Empty loop, just increment j */ + j ++; + strncpy(temp_info, (m_item->textinfo + i),j); + sscanf(temp_info, "%lf:%lf:%c", &dub1, &fsize, &printer); + i += j; + + xpos = (int)dub1; + //if((xpos - prev_x) >= 10) + //correction += 2; + + prev_x = xpos; + painter.drawText( x + ((xpos-correction) * m_scalex), + y + ((m_bar_height + (unsigned int)(barkode->fontsize()/ 2) + FONT_SPACE) * m_scaley), + QChar( printer ) ); + } + delete [] temp_info; +#endif + + double f1, f2; + int y0; + char* ptr; + char c; + + int mode = '-'; + for (ptr = m_item->textinfo; ptr; ptr = strchr(ptr, ' ')) + { + while (*ptr == ' ') + ptr++; + if (!*ptr) + break; + if (*ptr == '+' || *ptr == '-') + { + mode = *ptr; continue; + } + + if (sscanf(ptr, "%lf:%lf:%c", &f1, &f2, &c) != 3) + { + fprintf(stderr, "barcode: impossible data: %s\n", ptr); + continue; + } + + if( mode == '-' ) + { + // text below bars + y0 = y + (int)(m_bar_height * m_scaley + m_font_size - FONT_SPACE); + } + else + y0 = (int)(y + FONT_SPACE); + + if( painter ) + { + painter->setFont( QFont( "Helvetica", m_font_size ) ); + painter->drawText( x + (int)(f1 * m_scalex * barkode->scaling() ), y0, QChar( c ) ); + } + } + + return x; +} + +#endif // _ENABLE_NATIVE_GNU_BARCODE + |