Logo Search packages:      
Sourcecode: facturalux version File versions  Download package

FLCodBar.cpp

/***************************************************************************
                          FLCodBar.cpp  -  description
                             -------------------
    begin                : Die Apr 23 2002
    copyright            : (C) 2002 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 "FLCodBar.h"
#include "../barcode/barcode.h"

#define SHRINK_AMOUNT 0.15          /* shrink bars to account for ink spreading */
#define FONT_SCALE    0.95          /* Shrink fonts just a hair */

int standards[] = {
#ifdef DOMINIK_MODE
  BARCODE_ANY,                            /* choose best-fit */
#endif
  BARCODE_EAN,
  BARCODE_UPC,                            /* upc == 12-digit ean */
  BARCODE_ISBN,                           /* isbn numbers (still EAN13) */
  BARCODE_39,                             /* code 39 */
  BARCODE_128,                            /* code 128 (a,b,c: autoselection) */
  BARCODE_128C,                           /* code 128 (compact form for digits) */
  BARCODE_128B,                           /* code 128, full printable ascii */
  BARCODE_I25,                            /* interleaved 2 of 5 (only digits) */
  BARCODE_128RAW,                   /* Raw code 128 (by Leonid A. Broukhis) */
  BARCODE_CBR,                            /* Codabar (by Leonid A. Broukhis) */
  BARCODE_MSI,                            /* MSI (by Leonid A. Broukhis) */
  BARCODE_PLS,                            /* Plessey (by Leonid A. Broukhis) */
  BARCODE_93                              /* code 93 (by Nathan D. Holmes) */
};

FLCodBar::FLCodBar (barcodeData * data)
{
  init (data->value, data->type, data->margin, data->scale, data->text, data->fg, data->bg);
}

FLCodBar::FLCodBar (QString value, int type, int margin, double scale, bool text_flag, QColor fg, QColor bg)
{
  init (value, type, margin, scale, text_flag, fg, bg);
}

void
FLCodBar::init (QString value, int type, int margin, double scale, bool text_flag, QColor fg, QColor bg)
{
  char *barvalue = new char[value.length ()];
  struct Barcode_Item *bci;

  (void) qstrcpy (barvalue, (const char *) value);
  if (!barvalue)
      {
        qDebug ("NOT BARVALUE");
        return;
      }

  bci = Barcode_Create (barvalue);

  Barcode_Encode (bci, type); // type = standards[type] sometimes
  if (!bci->partial || !bci->textinfo)
      {
        valid = false;
        Barcode_Delete (bci);
        return;
      }

  bci->xoff = 0;
  bci->yoff = 0;
  bci->margin = margin;
  bci->scalef = scale;
  render (bci, text_flag, fg, bg);
  Barcode_Delete (bci);
  valid = true;
}

FLCodBar::~FLCodBar ()
{
}

/*--------------------------------------------------------------------------
 *
 *  Some of this code is borrowed from the postscript renderer (ps.c)
 *  from the GNU barcode library:
 *
 *     Copyright (C) 1999 Alessaandro Rubini (rubini@gnu.org)
 *     Copyright (C) 1999 Prosa Srl. (prosa@prosa.it)
 *
 *     Modified by (c) 2002 Dominik Seichter (domseichter@web.de)
 *--------------------------------------------------------------------------*/
void
FLCodBar::render (struct Barcode_Item *bci, bool text_flag, QColor fg, QColor bg)
{
  int barlen, i, j;
  double scale, x, x0, y0, yr, f1, f2;
  char *o, c;
  int mode = '-';                   /* text below bars */

  scale = bci->scalef;

  /* First calculate barlen */
  barlen = bci->partial[0] - '0';
  for (o = bci->partial + 1; *o != 0; o++)
      if (isdigit (*o))
        barlen += *o - '0';
      else if ((*o != '+') && (*o != '-'))
        barlen += *o - 'a' + 1;

  /* The width defaults to "just enough" */
  bci->width = (int) (barlen * scale + 1);

  /* But it can be too small, in this case enlarge and center the area */
  if (bci->width < barlen * scale)
      {
        int wid = (int) (barlen * scale + 1);

        bci->xoff -= (int) ((wid - bci->width) / 2);
        bci->width = wid;
        /* Can't extend too far on the left */
        if (bci->xoff < 0)
            {
              bci->width += -bci->xoff;
              bci->xoff = 0;
            }
      }

  /* The height defaults to 80 points (rescaled) */
  if (!bci->height)
      bci->height = (int) (80 * scale);

  /* If too small (5 + text), reduce the scale factor and center */
  i = 5 + 10 * ((bci->flags & BARCODE_NO_ASCII) == 0);
  if (bci->height < i * scale)
      {
        double scaleg = ((double) bci->height) / i;
        int wid = (int) (bci->width * scaleg / scale);

        bci->xoff += (int) ((bci->width - wid) / 2);
        bci->width = wid;
        scale = scaleg;
      }

  p.resize (bci->width + (bci->margin * 2), bci->height + (bci->margin * 2));

  p.fill (bg);
  QPainter painter (&p);

//    painter.rotate( angle );
  /* Now traverse the code string and create a list of lines */
  x = bci->margin + (bci->partial[0] - '0') * scale;
  for (o = bci->partial + 1, i = 1; *o != 0; o++, i++)
      {
        /* special cases: '+' and '-' */
        if (*o == '+' || *o == '-')
            {
              mode = *o;                  /* don't count it */
              i++;
              continue;
            }
        /* j is the width of this bar/space */
        if (isdigit (*o))
            j = *o - '0';
        else
            j = *o - 'a' + 1;

        if (i % 2)
            {                                   /* bar */
              x0 = x + (j * scale) / 2;
              y0 = bci->margin;
              yr = bci->height;
              if (text_flag)
                  {                             /* leave space for text */
                    if (mode == '-')
                        {
                          /* text below bars: 10 or 5 points */
                          yr -= (isdigit (*o) ? 10 : 5) * scale;
                        }
                    else
                        {                       /* '+' */
                          /* above bars: 10 or 0 from bottom,
                             and 10 from top */
                          y0 += 10 * scale;
                          yr -= (isdigit (*o) ? 20 : 10) * scale;
                        }
                  }

              for (int i = 0; i <= (int) ((j * scale) - SHRINK_AMOUNT); i++)
                  {
                    painter.setPen (QPen (fg, 1));
                    painter.drawLine ((int) x0 + i, (int) y0, (int) x0 + i, (int) yr);
                  }

            }
        x += j * scale;
      }

  /* Now the text */
  mode = '-';                             /* reinstantiate default */
  if (text_flag)
      {
        for (o = bci->textinfo; o; o = strchr (o, ' '))
            {
              while (*o == ' ')
                  o++;
              if (!*o)
                  break;
              if (*o == '+' || *o == '-')
                  {
                    mode = *o;
                    continue;
                  }
              if (sscanf (o, "%lf:%lf:%c", &f1, &f2, &c) != 3)
                  {
                    qDebug ("impossible data: %s", o);
                    continue;
                  }
              int cy;

              if (mode == '-')
                  cy = (int) (bci->margin + bci->height - 8 * scale);
              else
                  cy = bci->margin;

              QFont f ("Helvetica", (int) (f2 * FONT_SCALE * scale));

              painter.setFont (f);
              painter.drawText ((int) (f1 * scale + bci->margin), cy, QString (QChar (c)));
            }
      }
}

QPixmap FLCodBar::pixmap ()
{
  return p;
}

int
FLCodBar::convertType (QString type)
{
  type = type.lower ();
  if (type == "any")
      return BARCODE_ANY;
  else if (type == "ean")
      return BARCODE_EAN;
  else if (type == "upc")
      return BARCODE_UPC;
  else if (type == "isbn")
      return BARCODE_ISBN;
  else if (type == "code39")
      return BARCODE_39;
  else if (type == "code128")
      return BARCODE_128;
  else if (type == "code128c")
      return BARCODE_128C;
  else if (type == "code128b")
      return BARCODE_128B;
  else if (type == "codei25")
      return BARCODE_I25;
  else if (type == "code128raw")
      return BARCODE_128RAW;
  else if (type == "cbr")
      return BARCODE_CBR;
  else if (type == "msi")
      return BARCODE_MSI;
  else if (type == "pls")
      return BARCODE_PLS;
  else if (type == "code93")
      return BARCODE_93;
  else
      return BARCODE_ANY;
}

int
FLCodBar::index2type (int index)
{
  return standards[index];
}

int
FLCodBar::type2index (int type)
{
  for (unsigned int i = 0; i < sizeof (standards); i++)
      if (standards[i] == type)
        return i;
  return -1;
}

int
FLCodBar::width ()
{
  return p.width ();
}

int
FLCodBar::height ()
{
  return p.height ();
}

void
FLCodBar::fillDefault (barcodeData * data)
{
  data->bg = Qt::white;
  data->fg = Qt::black;
  data->margin = 10;
  data->text = false;
  data->value = "EXAMPLE";
  data->type = BARCODE_39;
  data->scale = 1;
}

void
FLCodBar::print (barcodeData * data)
{
  qDebug ("Value=%s\nMargin=%i\nScale=%f\nTextFlag=%i\nType=%i", (const char *) data->value, data->margin, data->scale, data->text, data->type);
}

Generated by  Doxygen 1.6.0   Back to index