Code: Select all | Expand
#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'
Code: Select all | Expand
//---------------------------------
#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