/*************************************************************************** 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 #include "barkode.h" #include #include #include #include #include #include #define FONT_SPACE (2*m_scaley) #define SHRINK_AMOUNT 0.15 #define MUL_FACTOR 10 GnuBarcode::GnuBarcode() : BarkodeEngine() { m_item = NULL; m_size = TQSize( 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 TQPaintDevice* device ) { TQString val = barkode->parsedValue(); m_valid = false; if( m_item ) { tqDebug("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; TQPaintDeviceMetrics metrics( device ); m_scalex = (double)metrics.logicalDpiX() / (double)TQPaintDevice::x11AppDpiX(); m_scaley = (double)metrics.logicalDpiY() / (double)TQPaintDevice::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 TQSize GnuBarcode::size() const { if( m_size.isNull() ) return TQSize( 100, 80 ); else return m_size; } void GnuBarcode::drawBarcode( TQPainter & 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 TQt on TQt >= 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( TQPainter* 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; tqDebug("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 ) { tqDebug("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() ); } //tqDebug("Bar = %i", j ); } xpos += j; } return xpos; } int GnuBarcode::drawText( TQPainter* 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( TQFont( "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), TQChar( 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( TQFont( "Helvetica", m_font_size ) ); painter->drawText( x + (int)(f1 * m_scalex * barkode->scaling() ), y0, TQChar( c ) ); } } return x; } #endif // _ENABLE_NATIVE_GNU_BARCODE