Generar Código de barras

Generar Código de barras

Postby EASYSOFT » Wed Dec 04, 2024 6:07 pm

Buenas tardes.
Tengo una cadena de cuarenta caracteres con la cual genero el código de barras pero este no se puede leer
Ej.
2811202401170435441200110020020000000324126153317
utilizo este código que encontré en este foro
nAncho := 1.5 // es el alto
nAlto := 0.03 // largo del codigo
cFile := ltrim(rtrim(cfile))

c_Code128( Ren_,9.2,cFile, oPrn,'C',,.T.,nAlto,nAncho)

Por favor si alguién me ayuda
Gracias
Saludos
Oscar
Fwh 10.4, bcc55
EASYSOFT
 
Posts: 190
Joined: Sat Oct 22, 2005 1:17 pm
Location: Quito - Ecuador

Re: Generar Código de barras

Postby EASYSOFT » Wed Dec 04, 2024 6:32 pm

EL código que necesito generar es
GS1 – 128

Gracias
Saludos
Oscar
Fwh 10.4, bcc55
EASYSOFT
 
Posts: 190
Joined: Sat Oct 22, 2005 1:17 pm
Location: Quito - Ecuador

Re: Generar Código de barras

Postby JoseAlvarez » Wed Dec 04, 2024 7:00 pm

Saludos.

Entiendo que el codigo se genera y se imprime,

No lo lee el lector optico al pasarlo?

Si ese es el problema, trata probarlo imprimiendo en un papel de calidad o etiqueta lisa. Muchas veces sobre papel bond no funciona.

Me refiero en caso de que estes probando sobre papel bond y una impresora de tinta normal.
"Los errores en programación, siempre están entre la silla y el teclado..."

Fwh 19.06 32 bits + Harbour 3.2 + Borland 7.4 + MariaDB + TDolphin

Carora, Estado Lara, Venezuela.
User avatar
JoseAlvarez
 
Posts: 805
Joined: Sun Nov 09, 2014 5:01 pm

Re: Generar Código de barras

Postby karinha » Wed Dec 04, 2024 7:18 pm

EASYSOFT wrote:EL código que necesito generar es
GS1 – 128

Gracias


Este código de barras, fivewin aún no lo ha predicho. Quizás el maestro RAO lo haga en el futuro. Vea si puede encontrar un programa de terceros y actívelo a través de FiveWin.

Regards, saludos.
João Santos - São Paulo - Brasil - Phone: +55(11)95150-7341
User avatar
karinha
 
Posts: 7872
Joined: Tue Dec 20, 2005 7:36 pm
Location: São Paulo - Brasil

Re: Generar Código de barras

Postby karinha » Wed Dec 04, 2024 7:39 pm

João Santos - São Paulo - Brasil - Phone: +55(11)95150-7341
User avatar
karinha
 
Posts: 7872
Joined: Tue Dec 20, 2005 7:36 pm
Location: São Paulo - Brasil

Re: Generar Código de barras

Postby Danielmaximiliano » Wed Dec 04, 2024 11:34 pm

karinha wrote:Recordé un detalle: no estoy seguro, pero tal vez BARLIB.LIB tenga el código 128, pero no sé si es GSI.

Regards, saludos.


aqui una descripcion de GS1
https://hmgforum.com/viewtopic.php?f=9&t=2449
dentro del foro hay 2 simples codigos de verificacion para EAN13 GS1 si necesitan ayuda veo como subir un simple codigo Harbour
Danielmaximiliano
 
Posts: 26
Joined: Tue Mar 20, 2012 11:06 pm

Re: Generar Código de barras

Postby Danielmaximiliano » Wed Dec 04, 2024 11:48 pm

karinha wrote:
EASYSOFT wrote:EL código que necesito generar es
GS1 – 128

Gracias


Este código de barras, fivewin aún no lo ha predicho. Quizás el maestro RAO lo haga en el futuro. Vea si puede encontrar un programa de terceros y actívelo a través de FiveWin.

Regards, saludos.

Dejo este codigo de nuestro Guru en el foro HMG Dr.Claudio Soto
Code: Select all  Expand view  RUN

/*----------------------------------------------------------------------------
 HMG - Harbour Windows GUI library source code

 Copyright 2002-2017 Roberto Lopez <mail.box.hmg@gmail.com>
 http://sites.google.com/site/hmgweb/

 Head of HMG project:

      2002-2012 Roberto Lopez <mail.box.hmg@gmail.com>
      http://sites.google.com/site/hmgweb/

      2012-2017 Dr. Claudio Soto <srvet@adinet.com.uy>
      http://srvet.blogspot.com

 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.

 This program is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

 You should have received a copy of the GNU General Public License along with
 this software; see the file COPYING. If not, write to the Free Software
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA (or
 visit the web site http://www.gnu.org/).

 As a special exception, you have permission for additional uses of the text
 contained in this release of HMG.

 The exception is that, if you link the HMG library with other
 files to produce an executable, this does not by itself cause the resulting
 executable to be covered by the GNU General Public License.
 Your use of that executable is in no way restricted on account of linking the
 HMG library code into it.

 Parts of this project are based upon:

    "Harbour GUI framework for Win32"
    Copyright 2001 Alexander S.Kresin <alex@belacy.belgorod.su>
    Copyright 2001 Antonio Linares <alinares@fivetech.com>
    www - http://www.harbour-project.org

    "Harbour Project"
    Copyright 1999-2008, http://www.harbour-project.org/

    "WHAT32"
    Copyright 2002 AJ Wos <andrwos@aust1.net>

    "HWGUI"
    Copyright 2001-2008 Alexander S.Kresin <alex@belacy.belgorod.su>

---------------------------------------------------------------------------*/


#require "hbzebra"
#include "hmg.ch"

FUNCTION  HMG_CreateBarCode( cCode, cType, nLineWidth, nLineHeight, lShowdigits, cImageFileName, aBarColor, aBackColor, lCheckSum, lWide2_5, lWide3 )

   LOCAL hBitmap, cTextCode, nFlags
   DEFAULT nLineWidth := 2
   DEFAULT nLineHeight := 100
   DEFAULT aBarColor := BLACK
   DEFAULT aBackColor := WHITE
   DEFAULT lCheckSum := .f.
   DEFAULT lWide2_5 := .f.
   DEFAULT lWide3 := .f.
   DEFAULT lShowDigits := .f.
   DEFAULT cImageFileName := ''

   nFlags := 0
   IF lChecksum
      nFlags := nFlags + HB_ZEBRA_FLAG_CHECKSUM
   ENDIF
   IF lWide2_5
      nFlags := nFlags + HB_ZEBRA_FLAG_WIDE2_5
   ENDIF
   IF lWide3
      nFlags := nFlags + HB_ZEBRA_FLAG_WIDE3
   ENDIF

   IF nFlags == 0
      nFlags := Nil
   ENDIF

   cTextCode   := ""
   hBitmap := HMG_Zebra_CreateBitmapBarCode ( aBarColor, aBackColor, nLineWidth, nLineHeight, cType, cCode, nFlags, lShowdigits, @cTextCode )

   IF hBitmap == 0
      RETURN hBitmap
   ENDIF

   IF HMG_len( cImageFileName ) <> 0
      BT_BitmapSaveFile( hBitmap, cImageFileName, BT_FILEFORMAT_PNG )
      BT_BitmapRelease ( hBitmap )
      RETURN 1
   ENDIF

RETURN hBitmap




*-----------------------------------------------------------------------------------------------------------------------*
FUNCTION HMG_Zebra_CreateBitmapBarCode (aBarColor, aBackColor, nLineWidth, nLineHeight, cType, cCode, nFlags, lShowdigits, cTextCode)
*-----------------------------------------------------------------------------------------------------------------------*
LOCAL hBitmap:=0, hZebra
LOCAL hDC, BTstruct, nFontSize
LOCAL cFont := 'Arial'
LOCAL nSizeWidth, nSizeHeight

   SWITCH cType
   CASE "EAN13"      ; hZebra := hb_zebra_create_ean13( cCode, nFlags )   ; EXIT
   CASE "EAN8"       ; hZebra := hb_zebra_create_ean8( cCode, nFlags )    ; EXIT
   CASE "UPCA"       ; hZebra := hb_zebra_create_upca( cCode, nFlags )    ; EXIT
   CASE "UPCE"       ; hZebra := hb_zebra_create_upce( cCode, nFlags )    ; EXIT
   CASE "CODE39"     ; hZebra := hb_zebra_create_code39( cCode, nFlags )  ; EXIT
   CASE "ITF"        ; hZebra := hb_zebra_create_itf( cCode, nFlags )     ; EXIT
   CASE "MSI"        ; hZebra := hb_zebra_create_msi( cCode, nFlags )     ; EXIT
   CASE "CODABAR"    ; hZebra := hb_zebra_create_codabar( cCode, nFlags ) ; EXIT
   CASE "CODE93"     ; hZebra := hb_zebra_create_code93( cCode, nFlags )  ; EXIT
   CASE "CODE11"     ; hZebra := hb_zebra_create_code11( cCode, nFlags )  ; EXIT
   CASE "CODE128"    ; hZebra := hb_zebra_create_code128( cCode, nFlags ) ; EXIT
   CASE "PDF417"     ; hZebra := hb_zebra_create_pdf417( cCode, nFlags ); nLineHeight := nLineWidth * 3 ; lShowDigits := .f.; EXIT
   CASE "DATAMATRIX" ; hZebra := hb_zebra_create_datamatrix( cCode, nFlags ); nLineHeight := nLineWidth ; lShowDigits := .f.; EXIT
   CASE "QRCODE"     ; hZebra := hb_zebra_create_qrcode( cCode, nFlags ); nLineHeight := nLineWidth ; lShowDigits := .f.; EXIT
   ENDSWITCH

   IF hZebra != NIL
      IF hb_zebra_geterror( hZebra ) == 0
         cTextCode   := hb_zebra_getcode (hZebra)
         nSizeWidth  := HMG_Zebra_GetWidth  (hZebra, nLineWidth, nLineHeight, NIL)
         nSizeHeight := HMG_Zebra_GetHeight (hZebra, nLineWidth, nLineHeight, NIL) + IIF( lShowDigits, ( nLineWidth * 10 ) + 20, 0 )
         hBitmap := BT_BitmapCreateNew ( nSizeWidth, nSizeHeight, aBackColor )
         hDC := BT_CreateDC ( hBitmap, BT_HDC_BITMAP, @BTstruct)
         HMG_Zebra_Draw ( hZebra, hDC, aBarColor, 0, 0, nLineWidth, nLineHeight, NIL )
         IF lShowDigits
            nFontSize := ( ( nSizeWidth / HMG_LEN(cTextCode))/ 96 * 72 * 1 )
            BT_DrawText ( hDC, nSizeHeight - (( nLineWidth * 10 ) + 20 ) + 5, nSizeWidth/2, cTextCode, cFont, nFontSize, aBarColor, aBackColor, ,BT_TEXT_CENTER )
         ENDIF
         BT_DeleteDC (BTstruct)
      ELSE
         MsgInfo ("Type "+ cType + CRLF +"Code "+ cCode+ CRLF+ "Error  "+LTrim(hb_valtostr(hb_zebra_geterror(hZebra))))
      ENDIF
      hb_zebra_destroy (hZebra)
   ELSE
      MsgStop("Invalid barcode type !", cType)
   ENDIF
RETURN hBitmap


*-----------------------------------------------------------------------------------------------*
FUNCTION HMG_Zebra_Draw ( hZebra, hDC, aBarColor, nRow, nCol, nLineWidth, nLineHeight, iFlags )
*-----------------------------------------------------------------------------------------------*
   IF hb_zebra_GetError( hZebra ) != 0
      RETURN HB_ZEBRA_ERROR_INVALIDZEBRA
   ENDIF
//     hb_zebra_draw ( hZebra,   bCodeBlock,                                                           dX,   dY,     dWidth,     dHeight, iFlags )
RETURN hb_zebra_draw ( hZebra, {| x, y, w, h | BT_DrawFillRectangle ( hDC, y, x, w, h, aBarColor )}, nCol, nRow, nLineWidth, nLineHeight, iFlags )


*-----------------------------------------------------------------------------------------------*
FUNCTION HMG_Zebra_GetWidth (hZebra, nLineWidth, nLineHeight, iFlags)
*-----------------------------------------------------------------------------------------------*
LOCAL x1:= 0, y1 := 0, nBarWidth := 0, nBarHeight := 0
   // always --> nBarHeight = nLineHeight
   IF hb_zebra_GetError( hZebra ) != 0
      RETURN HB_ZEBRA_ERROR_INVALIDZEBRA
   ENDIF
// hb_zebra_draw ( hZebra,   bCodeBlock,                                            dX, dY,     dWidth,     dHeight, iFlags )
//   hb_zebra_draw ( hZebra, {| x, y, w, h | nBarWidth:=x+w-x1, nBarHeight:=y+h-y1 }, x1, y1, nLineWidth, nLineHeight, iFlags )
//REPORT BUG FOR EDK
hb_zebra_draw ( hZebra, {| x, y, w, h | nBarWidth:=MAX(x+w-x1, nBarWidth), nBarHeight:=MAX(y+h-y1, nBarHeight) }, x1, y1, nLineWidth, nLineHeight, iFlags )

RETURN nBarWidth


*-----------------------------------------------------------------------------------------------*
FUNCTION HMG_Zebra_GetHeight (hZebra, nLineWidth, nLineHeight, iFlags)
*-----------------------------------------------------------------------------------------------*
LOCAL x1:= 0, y1 := 0, nBarWidth := 0, nBarHeight := 0
   // always --> nBarHeight = nLineHeight
   IF hb_zebra_GetError( hZebra ) != 0
      RETURN HB_ZEBRA_ERROR_INVALIDZEBRA
   ENDIF
// hb_zebra_draw ( hZebra,   bCodeBlock,                                            dX, dY,     dWidth,     dHeight, iFlags )
//   hb_zebra_draw ( hZebra, {| x, y, w, h | nBarWidth:=x+w-x1, nBarHeight:=y+h-y1 }, x1, y1, nLineWidth, nLineHeight, iFlags )
//REPORT BUG FOR EDK
   hb_zebra_draw ( hZebra, {| x, y, w, h | nBarWidth:=MAX(x+w-x1, nBarWidth), nBarHeight:=MAX(y+h-y1, nBarHeight) }, x1, y1, nLineWidth, nLineHeight, iFlags )
RETURN nBarHeight

 
Danielmaximiliano
 
Posts: 26
Joined: Tue Mar 20, 2012 11:06 pm

Re: Generar Código de barras SOLUCIONADO

Postby EASYSOFT » Thu Dec 05, 2024 1:45 pm

Buenos días.

Gracias por sus respuestas, lo solucioné con code128 de Enrico Maria Giordano que
encontre en el foro.

Saludos.
Saludos
Oscar
Fwh 10.4, bcc55
EASYSOFT
 
Posts: 190
Joined: Sat Oct 22, 2005 1:17 pm
Location: Quito - Ecuador

Re: Generar Código de barras

Postby nageswaragunupudi » Thu Dec 05, 2024 3:43 pm

Does this work?

Code: Select all  Expand view  RUN
#include "fivewin.ch"

REQUEST FWZEBRA

function Main()

   local cText    := "2811202401170435441200110020020000000324126153317"
   local oDlg

   DEFINE DIALOG oDlg SIZE 400,200 PIXEL TRUEPIXEL RESIZABLE
   ACTIVATE DIALOG oDlg CENTERED ON PAINT ;
      oDlg:SayBarCode( cText, { 50,20,130,380 }, "128" )

return nil
Regards

G. N. Rao.
Hyderabad, India
User avatar
nageswaragunupudi
 
Posts: 10690
Joined: Sun Nov 19, 2006 5:22 am
Location: India

Re: Generar Código de barras

Postby leandro » Thu Dec 05, 2024 5:36 pm

Este ejemplo esta en la carpeta de samples
barcod01.prg
Code: Select all  Expand view  RUN

#include "fivewin.ch"

REQUEST FWZEBRA

static cName, cCity, cCountry, cItem

//----------------------------------------------------------------------------//

function Main()

   local oDlg, oCode, oSay, oSay2, oSay3, oFont

   SetGetColorFocus()

   cName    := PadR( "Antonio Linares", 20 )
   cCity    := PadR( "Marbella", 20 )
   cCountry := PadR( "Spain", 20 )
   cItem    := "123456789012"

   DEFINE FONT oFont NAME "TAHOMA" SIZE 0,-14
   DEFINE DIALOG oDlg SIZE 600,800 PIXEL TRUEPIXEL FONT oFont ;
      TITLE "TSAYBARCODE CONTROL"

   @ 080, 40 SAY "PDF417" SIZE 100,26 PIXEL OF oDlg

   @ 050,150 SAYBARCODE oSay2 ;
      TEXT "Address :" + CRLF + cName - CRLF - cCity - CRLF - cCountry ;
      TYPE "PDF417" SIZE 400,80 PIXEL OF oDlg UPDATE

   @ 240, 40 SAY "Name    :" GET cName    SIZE 300,24 PIXEL OF oDlg VALID ( oDlg:Update(), .t. )
   @ 270, 40 SAY "City    :" GET cCity    SIZE 300,24 PIXEL OF oDlg VALID ( oDlg:Update(), .t. )
   @ 300, 40 SAY "Country :" GET cCountry SIZE 300,24 PIXEL OF oDlg VALID ( oDlg:Update(), .t. )
   @ 330, 40 SAY "Item    :" GET cItem    SIZE 200,24 PIXEL OF oDlg VALID ( oDlg:Update(), .t. ) ;
                                          PICTURE "999999999999" RIGHT
   @  230,450 SAYBARCODE oSay ;
      TEXT "Address :" + CRLF + cName - CRLF - cCity - CRLF - cCountry ;
      TYPE "QR-CODE" SIZE 100,100 PIXEL OF oDlg ;
      UPDATE

   @ 400,040 SAYBARCODE TEXT cName - "," - cCity ;
      TYPE "CODE128" SIZE 500,50 PIXEL OF oDlg UPDATE

   @ 480,040 SAY "CODE128" SIZE 520,24 PIXEL OF oDlg CENTER

   @ 550,040 BTNBMP PROMPT "PRINT" SIZE 200,60 PIXEL OF oDlg FLAT ACTION PrintBarCodes()

   @ 650,350 SAY "Item : EAN13" SIZE 200,24 PIXEL OF oDlg CENTER

   @ 700,350 SAYBARCODE TEXT cItem ;
      TYPE "EAN13" SIZE 200,50 PIXEL OF oDlg UPDATE

   ACTIVATE DIALOG oDlg CENTERED
   RELEASE FONT oFont

return nil

//----------------------------------------------------------------------------//

function PrintBarCodes()

   local oPrn, oFont

   PRINT oPrn PREVIEW
   DEFINE FONT oFont NAME "TAHOMA" SIZE 0,-14 OF oPrn

   PAGE

   @ 1, 1 PRINT TO oPrn TEXT "PDF417" INCHES FONT oFont

   @ 1.25, 1 PRINT TO oPrn TEXT "Address :" + CRLF + cName - CRLF - cCity - CRLF - cCountry ;
      AS BARCODE TYPE "PDF417" SIZE 4, 0.75 INCHES

   @ 3.00, 1 PRINT TO oPrn TEXT cName    INCHES FONT oFont
   @ 3.30, 1 PRINT TO oPrn TEXT cCity    INCHES FONT oFont
   @ 3.60, 1 PRINT TO oPrn TEXT cCountry INCHES FONT oFont
   @ 3.90, 1 PRINT TO oPrn TEXT cItem    INCHES FONT oFont

   @ 3.00,5.00 PRINT TO oPrn TEXT "Address :" + CRLF + cName - CRLF - cCity - CRLF - cCountry ;
      AS BARCODE TYPE "QR-CODE" SIZE 1.2,1.2 INCHES

   @ 5.5, 1 PRINT TO oPrn TEXT TRIM( cName ) ;
      AS BARCODE TYPE "CODE128" SIZE 4,1 INCHES

   @ 9, 4 PRINT TO oPrn TEXT cItem AS BARCODE TYPE "EAN13" ;
      SIZE 4,1 INCHES

   ENDPAGE

   ENDPRINT

   RELEASE FONT oFont

return nil

//----------------------------------------------------------------------------//


 
Saludos
LEANDRO AREVALO
Bogotá (Colombia)
https://hymlyma.com
https://hymplus.com/
leandroalfonso111@gmail.com
leandroalfonso111@hotmail.com

[ Embarcadero C++ 7.60 for Win32 ] [ FiveWin 23.07 ] [ xHarbour 1.3.0 Intl. (SimpLex) (Build 20230914) ]
User avatar
leandro
 
Posts: 1688
Joined: Wed Oct 26, 2005 2:49 pm
Location: Colombia

Re: Generar Código de barras

Postby nageswaragunupudi » Thu Dec 05, 2024 5:48 pm

This is the same as the above sample
Regards

G. N. Rao.
Hyderabad, India
User avatar
nageswaragunupudi
 
Posts: 10690
Joined: Sun Nov 19, 2006 5:22 am
Location: India

Re: Generar Código de barras

Postby nageswaragunupudi » Thu Dec 05, 2024 5:50 pm

EASYSOFT wrote:EL código que necesito generar es
GS1 – 128

Gracias


If EAN128 ia ok for you FWH provides. I do not know GS1-128
Regards

G. N. Rao.
Hyderabad, India
User avatar
nageswaragunupudi
 
Posts: 10690
Joined: Sun Nov 19, 2006 5:22 am
Location: India

Re: Generar Código de barras

Postby nageswaragunupudi » Thu Dec 05, 2024 5:52 pm

Dejo este codigo de nuestro Guru en el foro HMG Dr.Claudio Soto


All these codes are available through FWH also please.
Regards

G. N. Rao.
Hyderabad, India
User avatar
nageswaragunupudi
 
Posts: 10690
Joined: Sun Nov 19, 2006 5:22 am
Location: India

Re: Generar Código de barras

Postby EASYSOFT » Thu Dec 05, 2024 6:40 pm

Mr. Rao
Voy a probar el código que propone
muchas gracias
Saludos
Oscar
Fwh 10.4, bcc55
EASYSOFT
 
Posts: 190
Joined: Sat Oct 22, 2005 1:17 pm
Location: Quito - Ecuador

Re: Generar Código de barras

Postby Adolfredo Martinez » Sat Dec 07, 2024 11:35 pm

Tambien tuve ese problema para poder hacer el codigo de barra gs1-128, ya que utiliza otros parametros, para distinguirlo del code-128, el amigo Daniel Garcia gil hizo unas adaptacion que necesita el gs1-128,para que funcionara modifico el hzebra.prg:

Code: Select all  Expand view  RUN
#include "FiveWin.ch"

REQUEST FWZEBRA


function Main()

   local oPrn,cTexto2
   local cText,oFont
   local cCodigo:=space(13)
   local cFactura:=space(12)
   local cValor:=0
   local cFecha:=space(8)

   cCodigo    := "7709998978584"
   cFactura   := "202400124317"
   cValor     := 244478
   cFecha     := "20240831"


    cText := chr(0xf1) + "415" + cCodigo + "8020" + cFactura + chr(0xf1) + "3900" + STRTRAN(STR(cValor ,10)," ","0") + chr(0xf1) + "96" + cFecha
    cTexto2 := "(415)"+cCodigo+"(8020)"+cFactura+"(3900)"+STRTRAN(STR(cValor,10)," ","0")+"(96)"+cFecha

   DEFINE FONT oFont NAME "TAHOMA"          SIZE -20.5, 50  OF oPrn



 PRINT oPrn NAME "Impresión en Vertical.." PREVIEW
 oPrn:SetPage(5)  // LEGAL

 PAGE

      @11.3, 5 PRINT TO oPrn TEXT cText AS BARCODE TYPE "CODE128" ; //"ITF" ;
      SIZE 12, 1 CM COLOR CLR_BLACK //PINSIZE 5

      @ 12.0, 4.8 PRINT TO oPrn TEXT cTexto2 ;
      SIZE 11, 1 CM FONT oFont ALIGN "C"



   ENDPAGE
   ENDPRINT

return nil

#include 'hbzebra.prg'
 


Este es el hzebra:
Code: Select all  Expand view  RUN

//---------------------------------
#pragma BEGINDUMP
#include <hbzebra.h>
#include <hbvm.h>

// Since the FNCn characters are not ASCII, define versions here to
// simplify encoding strings that include them.
#define CODE128_FNC1 '\xf1'
// #define CODE128_FNC1 29
#define CODE128_FNC2 '\xf2'
#define CODE128_FNC3 '\xf3'
#define CODE128_FNC4 '\xf4'

HB_SIZE code128_estimate_len(const char *s);
PHB_ZEBRA code128_encode_raw(const char *s, HB_SIZE nLen, HB_SIZE maxlength);

#define CODE128_QUIET_ZONE_LEN 10
#define CODE128_CHAR_LEN 11
#define CODE128_STOP_CODE_LEN 13

#define CODE128_START_CODE_A 103
#define CODE128_START_CODE_B 104
#define CODE128_START_CODE_C 105

#define CODE128_MODE_A 'a'
#define CODE128_MODE_B 'b'
#define CODE128_MODE_C 'c'

#define CODE128_MIN_ENCODE_LEN (CODE128_QUIET_ZONE_LEN * 2 + CODE128_CHAR_LEN * 2 + CODE128_STOP_CODE_LEN)

static const unsigned short s_code[] = {
    00633, /*           00 */
    00663, /* !    !    01 */
    01463, /* "    "    02 */
    00311, /* #    #    03 */
    00611, /* $    $    04 */
    00621, /* %    %    05 */
    00231, /* &    &    06 */
    00431, /* '    '    07 */
    00461, /* (    (    08 */
    00223, /* )    )    09 */
    00423, /* *    *    10 */
    00443, /* +    +    11 */
    00715, /* ,    ,    12 */
    00731, /* -    -    13 */
    01631, /* .    .    14 */
    00635, /* /    /    15 */
    00671, /* 0    0    16 */
    01471, /* 1    1    17 */
    01163, /* 2    2    18 */
    00723, /* 3    3    19 */
    01623, /* 4    4    20 */
    00473, /* 5    5    21 */
    00563, /* 6    6    22 */
    01667, /* 7    7    23 */
    00627, /* 8    8    24 */
    00647, /* 9    9    25 */
    01447, /* :    :    26 */
    00467, /* ;    ;    27 */
    00547, /* <    <    28 */
    01147, /* =    =    29 */
    00333, /* >    >    30 */
    01433, /* ?    ?    31 */
    01543, /* @    @    32 */
    00305, /* A    A    33 */
    00321, /* B    B    34 */
    01421, /* C    C    35 */
    00215, /* D    D    36 */
    00261, /* E    E    37 */
    01061, /* F    F    38 */
    00213, /* G    G    39 */
    00243, /* H    H    40 */
    01043, /* I    I    41 */
    00355, /* J    J    42 */
    01615, /* K    K    43 */
    01661, /* L    L    44 */
    00335, /* M    M    45 */
    01435, /* N    N    46 */
    01561, /* O    O    47 */
    01567, /* P    P    48 */
    01613, /* Q    Q    49 */
    01643, /* R    R    50 */
    00273, /* S    S    51 */
    01073, /* T    T    52 */
    01673, /* U    U    53 */
    00327, /* V    V    54 */
    01427, /* W    W    55 */
    01507, /* X    X    56 */
    00267, /* Y    Y    57 */
    01067, /* Z    Z    58 */
    01307, /* [    [    59 */
    01367, /* \    \    60 */
    01023, /* ]    ]    61 */
    01217, /* ^    ^    62 */
    00145, /* _    _    63 */
    00605, /* NUL   `   64 */
    00151, /* SOH   a   65 */
    01411, /* STX   b   66 */
    00641, /* ETX   c   67 */
    01441, /* EOT   d   68 */
    00115, /* ENQ   e   69 */
    00415, /* ACK   f   70 */
    00131, /* BEL   g   71 */
    01031, /* BS    h   72 */
    00541, /* HT    i   73 */
    01141, /* LF    j   74 */
    01103, /* VT    k   75 */
    00123, /* FF    l   76 */
    01357, /* CR    m   77 */
    00503, /* SO    n   78 */
    01361, /* SI    o   79 */
    00745, /* DLE   p   80 */
    00751, /* DC1   q   81 */
    01711, /* DC2   r   82 */
    00475, /* DC3   s   83 */
    00571, /* DC4   t   84 */
    01171, /* NAK   u   85 */
    00457, /* SYN   v   86 */
    00517, /* ETB   w   87 */
    01117, /* CAN   x   88 */
    01733, /* EM    y   89 */
    01573, /* SUB   z   90 */
    01557, /* ESC   {   91 */
    00365, /* FS    |   92 */
    01705, /* GS    }   93 */
    01721, /* RS    ~   94 */
    00275, /* US   DEL  95 */
    01075, /* FNC3 FNC3 96 */
    00257, /* FNC2 FNC2 97 */
    01057, /* ShiB ShiA 98 */
    01735, /* CodC CodC 99 */
    01675, /* CodB FNC4 CodB 100 */
    01727, /* FNC4 CodA CodA 101 */
    01657, /* FNC1 FNC1 FNC1 102 */
    00413, /* Start Code A   103 */
    00113, /* Start Code B   104 */
    00713  /* Start Code C   105 */        
};

struct code128_step
{
  int prev_ix;            // Index of previous step, if any
  const char *next_input; // Remaining input
  unsigned short len;     // The length of the pattern so far (includes this step)
  char mode;              // State for the current encoding
  signed char code;       // What code should be written for this step
};

struct code128_state
{
  struct code128_step *steps;
  int allocated_steps;
  int current_ix;
  int todo_ix;
  int best_ix;

  HB_SIZE maxlength;
};

HB_SIZE code128_estimate_len(const char *s)
{
  return CODE128_QUIET_ZONE_LEN + CODE128_CHAR_LEN  // start code
         + CODE128_CHAR_LEN * (strlen(s) * 11 / 10) // contents + 10% padding
         + CODE128_CHAR_LEN                         // checksum
         + CODE128_STOP_CODE_LEN + CODE128_QUIET_ZONE_LEN;
}

static unsigned char code128_switch_code(char from_mode, char to_mode)
{
  switch (from_mode)
  {
  case CODE128_MODE_A:
    switch (to_mode)
    {
    case CODE128_MODE_B:
      return 100;
    case CODE128_MODE_C:
      return 99;
    }

  case CODE128_MODE_B:
    switch (to_mode)
    {
    case CODE128_MODE_A:
      return 101;
    case CODE128_MODE_C:
      return 99;
    }

  case CODE128_MODE_C:
    switch (to_mode)
    {
    case CODE128_MODE_B:
      return 100;
    case CODE128_MODE_A:
      return 101;
    }
  }

  return 0;
}

static signed char code128a_ascii_to_code(char value)
{
  if (value >= ' ' && value <= '_')
    return value - ' ';
  else if (value >= 0 && value < ' ')
    return value + 64;
  else if (value == CODE128_FNC1)
    return 102;
  else if (value == CODE128_FNC2)
    return 97;
  else if (value == CODE128_FNC3)
    return 96;
  else if (value == CODE128_FNC4)
    return 101;
  else
    return -1;
}

static signed char code128b_ascii_to_code(char value)
{
  if (value >= 32) // value <= 127 is implied
    return value - 32;
  else if (value == CODE128_FNC1)
    return 102;
  else if (value == CODE128_FNC2)
    return 97;
  else if (value == CODE128_FNC3)
    return 96;
  else if (value == CODE128_FNC4)
    return 100;
  else
    return -1;
}

static signed char code128c_ascii_to_code(const char *values)
{
  if (values[0] == CODE128_FNC1)
    return 102;

  if (values[0] >= '0' && values[0] <= '9' &&
      values[1] >= '0' && values[1] <= '9')
  {
    char code = 10 * (values[0] - '0') + (values[1] - '0');
    return code;
  }

  return -1;
}

static int code128_do_a_step(struct code128_step *base, int prev_ix, int ix)
{
  struct code128_step *previous_step = &base[prev_ix];
  struct code128_step *step = &base[ix];

  char value = *previous_step->next_input;
  // NOTE: Currently we can't encode NULL
  if (value == 0)
    return 0;

  step->code = code128a_ascii_to_code(value);
  if (step->code < 0)
    return 0;

  step->prev_ix = prev_ix;
  step->next_input = previous_step->next_input + 1;
  step->mode = CODE128_MODE_A;
  step->len = previous_step->len + CODE128_CHAR_LEN;
  if (step->mode != previous_step->mode)
    step->len += CODE128_CHAR_LEN; // Need to switch modes

  return 1;
}

static int code128_do_b_step(struct code128_step *base, int prev_ix, int ix)
{
  struct code128_step *previous_step = &base[prev_ix];
  struct code128_step *step = &base[ix];

  char value = *previous_step->next_input;
  // NOTE: Currently we can't encode NULL
  if (value == 0)
    return 0;

  step->code = code128b_ascii_to_code(value);
  if (step->code < 0)
    return 0;

  step->prev_ix = prev_ix;
  step->next_input = previous_step->next_input + 1;
  step->mode = CODE128_MODE_B;
  step->len = previous_step->len + CODE128_CHAR_LEN;
  if (step->mode != previous_step->mode)
    step->len += CODE128_CHAR_LEN; // Need to switch modes

  return 1;
}

static int code128_do_c_step(struct code128_step *base, int prev_ix, int ix)
{
  struct code128_step *previous_step = &base[prev_ix];
  struct code128_step *step = &base[ix];

  char value = *previous_step->next_input;
  // NOTE: Currently we can't encode NULL
  if (value == 0)
    return 0;

  step->code = code128c_ascii_to_code(previous_step->next_input);
  if (step->code < 0)
    return 0;

  step->prev_ix = prev_ix;
  step->next_input = previous_step->next_input + 1;

  // Mode C consumes 2 characters for codes 0-99
  if (step->code < 100)
    step->next_input++;

  step->mode = CODE128_MODE_C;
  step->len = previous_step->len + CODE128_CHAR_LEN;
  if (step->mode != previous_step->mode)
    step->len += CODE128_CHAR_LEN; // Need to switch modes

  return 1;
}

static struct code128_step *code128_alloc_step(struct code128_state *state)
{
  struct code128_step *step;
  if (state->todo_ix >= state->allocated_steps)
  {
    state->allocated_steps += 1024;
    state->steps = (struct code128_step *)hb_xrealloc(state->steps, state->allocated_steps * sizeof(struct code128_step));
  }

  step = &state->steps[state->todo_ix];

  hb_xmemset(step, 0, sizeof(*step));
  return step;
}

static void code128_do_step(struct code128_state *state)
{
  struct code128_step *step = &state->steps[state->current_ix];
  char mode;
  int mode_c_worked = 0;

  if (*step->next_input == 0)
  {
    // Done, so see if we have a new shortest encoding.
    if ((step->len < (unsigned short)state->maxlength) ||
        (state->best_ix < 0 && step->len == (unsigned short)state->maxlength))
    {
      state->best_ix = state->current_ix;

      // Update maxlength to avoid considering anything longer
      state->maxlength = step->len;
    }
    return;
  }

  // Don't try if we're already at or beyond the max acceptable
  // length;
  if (step->len >= (unsigned short)state->maxlength)
    return;
  mode = step->mode;

  code128_alloc_step(state);
 

  // Always try mode C
  if (code128_do_c_step(state->steps, state->current_ix, state->todo_ix))
  {
    state->todo_ix++;
    code128_alloc_step(state);
    mode_c_worked = 1;
  }

  if (mode == CODE128_MODE_A)
  {
    // If A works, stick with A. There's no advantage to switching
    // to B proactively if A still works.
    if (code128_do_a_step(state->steps, state->current_ix, state->todo_ix) ||
        code128_do_b_step(state->steps, state->current_ix, state->todo_ix))
      state->todo_ix++;
  }
  else if (mode == CODE128_MODE_B)
  {
    // The same logic applies here. There's no advantage to switching
    // proactively to A if B still works.
    if (code128_do_b_step(state->steps, state->current_ix, state->todo_ix) ||
        code128_do_a_step(state->steps, state->current_ix, state->todo_ix))
      state->todo_ix++;
  }
  else if (!mode_c_worked)
  {
    // In mode C. If mode C worked and we're in mode C, trying anything
    // else is pointless since the mode C encoding will be shorter and
    // there won't be any mode switches.

    // If we're leaving mode C, though, try both in case one ends up
    // better than the other.
    if (code128_do_a_step(state->steps, state->current_ix, state->todo_ix))
    {
      state->todo_ix++;
      code128_alloc_step(state);
    }
    if (code128_do_b_step(state->steps, state->current_ix, state->todo_ix))
    {
      state->todo_ix++;
    }
  }
}

PHB_ZEBRA code128_encode_raw(const char *szCode, HB_SIZE nLen, HB_SIZE maxlength)
{
  PHB_ZEBRA pZebra;
  struct code128_state state;
  HB_SIZE i, j;
  int csum;
  HB_SIZE num_codes;
  unsigned char * codes;
  struct code128_step *step;

  const HB_SIZE overhead = CODE128_QUIET_ZONE_LEN + CODE128_CHAR_LEN // checksum
                           + CODE128_STOP_CODE_LEN + CODE128_QUIET_ZONE_LEN;
  pZebra = hb_zebra_create();
  pZebra->iType = HB_ZEBRA_TYPE_CODE128;

  if (maxlength < overhead + CODE128_CHAR_LEN + CODE128_CHAR_LEN)
  {
    // Need space to encode the start character and one additional
    // character.
    pZebra->iError = HB_ZEBRA_ERROR_INVALIDCODE;
    return pZebra;
  }

  /* make print string */
  pZebra->szCode = (char *)hb_xgrab(nLen + 1);
  j = 0;
  for (i = 0; i < nLen; i++)
  {
    if ((szCode[i] >= 32 && szCode[i] <= 126))
      pZebra->szCode[j++] = szCode[i];
  }
  pZebra->szCode[j] = '\0';
  printf("codigo %s\n", pZebra->szCode);

  state.allocated_steps = 256;
  state.steps = (struct code128_step *)hb_xgrab(state.allocated_steps * sizeof(struct code128_step));
  state.current_ix = 0;
  state.todo_ix = 0;
  state.maxlength = maxlength - overhead;
  state.best_ix = -1;
  // Initialize the first 3 steps for the 3 encoding routes (A, B, C)
  state.steps[0].prev_ix = -1;
  state.steps[0].next_input = szCode;
  state.steps[0].len = CODE128_CHAR_LEN;
  state.steps[0].mode = CODE128_MODE_C;
  state.steps[0].code = CODE128_START_CODE_C;

  state.steps[1].prev_ix = -1;
  state.steps[1].next_input = szCode;
  state.steps[1].len = CODE128_CHAR_LEN;
  state.steps[1].mode = CODE128_MODE_A;
  state.steps[1].code = CODE128_START_CODE_A;

  state.steps[2].prev_ix = -1;
  state.steps[2].next_input = szCode;
  state.steps[2].len = CODE128_CHAR_LEN;
  state.steps[2].mode = CODE128_MODE_B;
  state.steps[2].code = CODE128_START_CODE_B;

  state.todo_ix = 3;

  // Keep going until no more work
  do
  {
    code128_do_step(&state);
    state.current_ix++;
  } while (state.current_ix != state.todo_ix);

  // If no best_step, then fail.
  if (state.best_ix < 0)
  {
    pZebra->iError = HB_ZEBRA_ERROR_INVALIDCODE;
    return pZebra;
  }

  // Determine the list of codes
  num_codes = state.maxlength / CODE128_CHAR_LEN;
  codes = hb_xgrab( sizeof( unsigned char ) * num_codes );
  step = &state.steps[state.best_ix];

  for (i = num_codes - 1; i > 0; --i)
  {
    struct code128_step *prev_step = &state.steps[step->prev_ix];
    codes[i] = step->code;
    if (step->mode != prev_step->mode)
    {
      --i;
      codes[i] = code128_switch_code(prev_step->mode, step->mode);
      if (codes[i] == 0)
      {
        pZebra->iError = HB_ZEBRA_ERROR_INVALIDCODE;
        return pZebra;
      }
    }
    step = prev_step;
  }
  codes[0] = step->code;
  //

  pZebra->pBits = hb_bitbuffer_create();
  csum = codes[0];

  for (i = 0; i < num_codes; i++)
  {
    hb_bitbuffer_cat_int(pZebra->pBits, s_code[codes[i]], 11);
    csum += i * codes[i];
  }

  // /* checksum */
  hb_bitbuffer_cat_int(pZebra->pBits, s_code[csum % 103], 11);

  hb_bitbuffer_cat_int(pZebra->pBits, 0x1AE3, 13);

  hb_xfree(state.steps);
  hb_xfree( codes );
  return pZebra;
}

HB_FUNC(HB_ZEBRA_CREATE_CODE128)
{
  PHB_ITEM pItem = hb_param(1, HB_IT_STRING);
  char *s = (char *)hb_itemGetCPtr(pItem);
  char raw[4096];
  int width;
  int iCountChar = 0;

  char *p = raw;
  for (; *s != '\0'; s++)
  {
    if (strncmp(s, "[FNC1]", 6) == 0)
    {
      *p++ = CODE128_FNC1;
      s += 5;
    }
    else if (*s != ' ')
    {
      *p++ = *s;
    }
    iCountChar++;
  }
  *p = '\0';

  width = code128_estimate_len(hb_parc(1));

  if (pItem)
    hb_zebra_ret(code128_encode_raw(raw, (HB_SIZE)iCountChar, width));
  else
    hb_errRT_BASE(EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS);
}

#pragma ENDDUMP

 
Adolfredo Martinez
 
Posts: 121
Joined: Fri Feb 15, 2019 1:37 pm
Location: Aracataca-Colombia

Next

Return to FiveWin para Harbour/xHarbour

Who is online

Users browsing this forum: Google [Bot] and 106 guests