📄 prn_buf.c
字号:
///////////////////////////////////////////////////////////////////////////////
// prn_buf.c
//
// Copyright (c) 2004, WeiHua Technology Co., Ltd.
// All rights reserved.
//
// Created by: Chen Huahai 2004-08-20
//
// Desription:
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// 简单说明
// 简介:
// 本文件主要负责将打印字符串转换成点阵缓冲,然后由中断来调度打印.
// 在2004年8月前,只支持整行格式的控制; 现需支持单个字符格式控制,故作修改.
//
// 打印调用过程概述:
// 首先,上层软件将需要打印的字符保存到打印字符缓冲区.
// 然后,调用转换函数,将缓冲区的字符串转换为点阵数据.
// 最后,在中断中负责驱动打印机,把点阵数据打印出来.
//
// 转换过程:
// 1. 原处理模式 (只支持整行格式控制)
// prn_Buf[MAX_PRN_LEN+1] 第一字节表示整行的格式,后续数据则是正常字符.
// 在程序中,基本都采用了直接对prn_Buf操作,而没有采用函数来封装其操作.
//
// 2. 新处理模式 (支持单个字符格式控制, 同时兼容原处理模式)
// (1) prn_Buf[MAX_PRN_LEN+1] 常规模式
// 第一字节表示整行的格式,后续数据则是正常字符.
//
// (2) prnBufFmt[MAX_PRN_LEN*2+2] 标准模式
// 前两个字节表示整行格式及走纸步数(此字节暂未使用,保留),
// 之后,每两个字节表示一个字符,第一个字节表示格式,第二个字节表示字符,
// 若格式为双宽或双宽双高时,则后续两个字节为空.
// (换句话说,每两个字节表示一个实际打印字符,即12点; 双宽时,因其占24点,故占4个字节).
//
// (3) prn_BufEx[MAX_PRN_LEN*2+2] 变通模式
// 考虑到可能的需要,我们还支持变通的格式.
// 前两个字节表示整行格式及走纸步数,
// 格式字节定义为不可打印字符,以区分格式字符和实际字符.
// 默认格式为普通字体,从本缓冲区的第一字节开始,每个格式字节指定了后续的所有连续字符.
// 如: 设 0x11 -- 普通字体, 0x12 -- 双宽字体.
// 'a', 0x12, 'b', 'c', '0x11', 'd', ...
// 则, 'a'为普通字体, 'b','c'为双宽字体, 'd'为普通字体...
// 用此种方式处理,可节省dept/plu/...等的描述符占用空间,有更灵活的应用.
//
// 在转换函数中,将以上几种格式的数据全部转换成统一的第二种格式(即每个字符用两个字节表示),
// 然后,将其转成点阵数据.
//
// 上层调用:
// 1. 原处理模式: 基本上都采用了直接对prn_Buf操作,通过函数来的操作的较少.
//
// 2. 新处理模式:
// (1) 支持原处理模式:
// 这样,不用修改原来的程序. 在处理简单的打印要求时,可以继续采用此种方式.
//
// (2) 标准模式
// 调用已封装的函数加以处理,即不直接操作prn_BufFmt[],而只是传递指定的信息即可.
//
// (3) 扩展模式
// 调用已封装的函数加以处理,有可能用于描述符编程.
//
// 调用举例:
// 1. 兼容原处理模式.
// prn_Str()函数中,用 "Prn_Str(0);" 替代.
// clr_Prn_Buf函数中,增加调用 "Prn_BufFmtClr();"
//
// 2. 新处理模式:
//
// 其它:
// 1. 转换速度: 11M晶振,总线一个等待时,转换速度要超过打印速度,故暂不考虑优化.
//
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// 修改操作步骤 (更新到原WD1项目)
//
// 1. 在项目中加入本文件 prn_buf.c.
//
// 2. 删除以下内容:
// 1) lib.c
// prn_Str() 函数.
// 2) prn_drv.c
// clr_Prn_Buf() 函数.
// 3) ftype.h
// prn_Str(), clr_Prn_Buf() 函数声明.
//
// 3. 增加以下内容:
// 1) ftype.h
// void Prn_Str(byte type);
// void Prn_BufClr(void);
// void Prn_BufFmtClr(void);
// void Prn_InsStr1stSp(const byte *str, byte pos, byte fmt, byte fmt2);
// void Prn_InsMem1stSp(const byte *str, byte len, byte pos, byte fmt, byte fmt2);
// void Prn_InsMem(const byte *str, byte len, byte pos, byte fmt, byte attr);
// void Prn_InsStr(const byte *str, byte pos, byte fmt, byte attr);
// #define prn_Str() Prn_Str(0)
// #define clr_Prn_Buf() Prn_BufClr()
//
// 2) ecrsys.h
// #define FLUSH_LEFT 0
// #define FLUSH_RIGHT 1
// #define FLUSH_MID 2
///////////////////////////////////////////////////////////////////////////////
#include "ecrsys.h"
#include "ftype.h"
#include "data.h"
#include "sysdata.h"
#include <string.h>
#define FLUSH_LEFT 0
#define FLUSH_RIGHT 1
#define FLUSH_MID 2
#define PRN_HEIGHT_24 24
#define PRN_HEIGHT_48 48
#define PRN_HEIGHT_BMP BMP_LINE
#define PRN_DBWD_FREE_BYTE 0xff // 双宽属性后续字节为空.
#define PRN_FMTED_BUF_LEN (MAX_PRN_LEN * 2 + 2)
//#define DOT_BASE (byte *)(0xfc0000 + 0x38000)
#define DOT_DOUBLE_BASE (byte *)(0xfc0000 + 0x38000 + 48 * 256)
void apply_one_line(void);
// public function
void Prn_Str(byte type);
void Prn_BufFmtClr(void);
void Prn_InsStr1stSp(const byte *str, byte pos, byte fmt, byte fmt2);
void Prn_InsMem1stSp(const byte *str, byte len, byte pos, byte fmt, byte fmt2);
void Prn_InsMem(const byte *str, byte len, byte pos, byte fmt, byte attr);
void Prn_InsStr(const byte *str, byte pos, byte fmt, byte attr);
void Prn_InitDesc(byte *obj, byte maxLen, const byte *str, byte fmt, byte fmt2);
void Prn_InsFmtStr(const byte *src, byte pos, byte len, byte attr);
// private function
void Prn_BufCvt(const byte *str);
void Prn_BufFmt(byte *obj, const byte *src);
void Prn_FreeDotBufGet(byte bufInc);
void Prn_Feed(byte step);
void Prn_InsStrEx(byte *obj, const byte *str, byte pos, byte fmt, byte attr);
void Prn_InsMemEx(byte *obj, const byte *str, byte len, byte pos, byte fmt, byte attr);
void Prn_InsMem1stSpEx(byte *obj, byte maxLen, const byte *str, byte len, byte fmt, byte fmt2);
void Prn_FmtImpStr(byte *obj, const byte *src, byte lineFormat);
byte prnBufFmt[PRN_FMTED_BUF_LEN];
///////////////////////////////////////////////////////////////////////////////
// Descript: 初始化缓冲区,使之为全空,且为普通字体.
// In Param: void
// Out Param: void
// Return: void
///////////////////////////////////////////////////////////////////////////////
void Prn_BufClr(void)
{
byte i;
// 清除原处理模式的字符缓冲.
for (i=1; i < PRN_BUF_LEN; i++)
{
prn_Buf[i] = ' ';
}
prn_Buf[0] = NM_FONT_PRN;
Prn_BufFmtClr();
}
///////////////////////////////////////////////////////////////////////////////
// Descript: The printing improved format string copy.
// The improved format string contains double width and normal
// print format.
// In Param: *src -- 上层传递下来的打印缓冲数据, 这个打印缓冲数据中为扩展双宽的描述符格式
// pos -- 字符位置, 1~MAX_PRN_LEN
// len -- 打印长度, 即src的描述符长度.
// attr -- 属性, 靠左, 靠右, 居中对齐等. 目前传入的参数统一为NULL
// Out Param: void
// Return: void
///////////////////////////////////////////////////////////////////////////////
void Prn_InsImpStr(const byte *src, byte pos, byte len, byte attr)
{
byte temp[MAX_PRN_LEN+1];
byte obj[MAX_PRN_LEN*2+1];
byte i;
if (len > MAX_PRN_LEN)
{
len = MAX_PRN_LEN;
}
memcpy(temp, src, len);
temp[len] = 0; // 加入字符串结束标志,因传下来的数据无此标志.
for (i=0; i<MAX_PRN_LEN; i++) // 清空缓冲.
{
obj[i*2] = NM_FONT_PRN;
obj[i*2+1] = ' ';
}
Prn_FmtImpStr(obj, temp, NM_FONT_PRN);
Prn_InsFmtStr(obj, pos, len, attr);
}
///////////////////////////////////////////////////////////////////////////////
// Descript:初始化缓冲区,使之为全空,且为普通字体.
// In Param: void (即prnBufFmt, 原为: *obj -- 打印缓冲区.)
// Out Param: void (即prnBufFmt, 原为: *obj -- 打印缓冲区.)
// Return: void
///////////////////////////////////////////////////////////////////////////////
void Prn_BufFmtClr(void)
{
byte i;
prnBufFmt[0] = PRN_HEIGHT_24;
prnBufFmt[1] = 0; // 暂时未用.
for (i=1; i<=MAX_PRN_LEN; i++)
{
prnBufFmt[i*2] = NM_FONT_PRN;
prnBufFmt[i*2+1] = ' ';
}
}
///////////////////////////////////////////////////////////////////////////////
// Descript: Insert a string, First Char is Special Format.
// In Param: *str -- 插入数据, pos -- 字符位置 (1 ~ MAX_PRN_LEN).
// fmt -- 字符格式, fmt2 -- 第一个字符的格式.
// Out Param: void
// Return: void
///////////////////////////////////////////////////////////////////////////////
void Prn_InsStr1stSp(const byte *str, byte pos, byte fmt, byte fmt2)
{
byte posInc = 1;
if (strlen(str) >= 1)
{
Prn_InsMem(str, 1, pos, fmt2, FLUSH_LEFT);
if ((fmt2 == DB_HTWDT_PRN) || (fmt2 == DB_WIDTH_PRN))
{
posInc = 2;
}
if (strlen(str) > 1)
{
Prn_InsStr(str+1, pos+posInc, fmt, FLUSH_LEFT);
}
}
}
///////////////////////////////////////////////////////////////////////////////
// Descript: Insert a memory, First Char is Special Format.
// In Param: *str -- 插入数据, pos -- 字符位置 (1 ~ MAX_PRN_LEN).
// fmt -- 字符格式,
// fmt2 -- 第一个字符的格式. len -- 插入字符数.
// Out Param: void
// Return: void
///////////////////////////////////////////////////////////////////////////////
void Prn_InsMem1stSp(const byte *str, byte len, byte pos, byte fmt, byte fmt2)
{
byte posInc = 1;
if (len >= 1)
{
Prn_InsMem(str, 1, pos, fmt2, FLUSH_LEFT);
if ((fmt2 == DB_HTWDT_PRN) || (fmt2 == DB_WIDTH_PRN))
{
posInc = 2;
}
if (len > 1)
{
Prn_InsMem(str+1, len-1, pos+posInc, fmt, FLUSH_LEFT);
}
}
}
///////////////////////////////////////////////////////////////////////////////
// Descript: Cash,Change等可编程描述符,全清时重置,将字符串转换为打印格式字符串保存.
// In Param: *str -- 插入数据, maxLen -- 最大可编程字符数.
// fmt -- 字符格式, fmt2 -- 第一个字符的格式.
// Out Param: *obj
// Return: void
///////////////////////////////////////////////////////////////////////////////
void Prn_InitDesc(byte *obj, byte maxLen, const byte *str, byte fmt, byte fmt2)
{
Prn_InsMem1stSpEx(obj, maxLen, str, strlen(str), fmt, fmt2);
}
///////////////////////////////////////////////////////////////////////////////
// Descript: Insert a memory, First Char is Special Format.
// In Param: *str -- 插入数据, fmt -- 字符格式,
// fmt2 -- 第一个字符的格式. len -- 插入字符数.
// maxLen -- 目标数组的最大长度.
// Out Param: *obj
// Return: void
///////////////////////////////////////////////////////////////////////////////
void Prn_InsMem1stSpEx(byte *obj, byte maxLen, const byte *str, byte len, byte fmt, byte fmt2)
{
byte posInc = 1;
byte temp[80];
byte i;
for (i=1; i<=MAX_PRN_LEN; i++)
{
temp[i*2] = NM_FONT_PRN;
temp[i*2+1] = ' ';
}
if (len >= 1)
{
Prn_InsMemEx(temp, str, 1, 1, fmt2, FLUSH_LEFT);
if ((fmt2 == DB_HTWDT_PRN) || (fmt2 == DB_WIDTH_PRN))
{
posInc = 2;
}
if (len > 1)
{
Prn_InsMemEx(temp, str+1, len-1, 1+posInc, fmt, FLUSH_LEFT);
}
}
memcpy(obj, &temp[2], maxLen*2);
}
///////////////////////////////////////////////////////////////////////////////
// Descript: Insert a defined format string to print buffer
// In Param: *str -- 插入数据, pos -- 字符位置 (1 ~ MAX_PRN_LEN).
// fmt -- 字符格式, attr -- 属性,如靠左,靠右,居中对齐等.
// len -- 插入字符数.
// Out Param: void
// Return: void
///////////////////////////////////////////////////////////////////////////////
void Prn_InsMem(const byte *str, byte len, byte pos, byte fmt, byte attr)
{
Prn_InsMemEx(prnBufFmt, str, len, pos, fmt, attr);
}
///////////////////////////////////////////////////////////////////////////////
// Descript: Insert a defined format string to print buffer
// In Param: *str -- 插入数据, pos -- 字符位置 (1 ~ MAX_PRN_LEN).
// fmt -- 字符格式, attr -- 属性,如靠左,靠右,居中对齐等.
// len -- 插入字符数.
// Out Param: *obj
// Return: void
///////////////////////////////////////////////////////////////////////////////
void Prn_InsMemEx(byte *obj, const byte *str, byte len, byte pos, byte fmt, byte attr)
{
byte temp[MAX_PRN_LEN+1];
if (len > MAX_PRN_LEN)
{
len = MAX_PRN_LEN;
}
memcpy(temp, str, len);
temp[len] = 0;
Prn_InsStrEx(obj, temp, pos, fmt, attr);
}
///////////////////////////////////////////////////////////////////////////////
// Descript: Insert a defined format string to print buffer
// In Param: *str -- 插入数据, pos -- 字符位置 (1 ~ MAX_PRN_LEN).
// fmt -- 字符格式, attr -- 属性,如靠左,靠右,居中对齐等.
// Out Param: void
// Return: void
// Caution: 如果传入的字符串与原数据有冲突,将覆盖原数据,或丢失.
// 若长度超出,则会自动截去.
///////////////////////////////////////////////////////////////////////////////
void Prn_InsStr(const byte *str, byte pos, byte fmt, byte attr)
{
Prn_InsStrEx(prnBufFmt, str, pos, fmt, attr);
}
///////////////////////////////////////////////////////////////////////////////
// Descript: Insert a defined format string to print buffer
// In Param: *str -- 插入数据, pos -- 字符位置 (1 ~ MAX_PRN_LEN).
// fmt -- 字符格式, attr -- 属性,如靠左,靠右,居中对齐等.
// Out Param: *obj --
// Return: void
// Caution: 如果传入的字符串与原数据有冲突,将覆盖原数据,或丢失.
// 若长度超出,则会自动截去.
///////////////////////////////////////////////////////////////////////////////
void Prn_InsStrEx(byte *obj, const byte *str, byte pos, byte fmt, byte attr)
{
byte i;
byte len;
// 检查参数是否错误.
if (((attr != FLUSH_RIGHT) && (attr != FLUSH_LEFT) && (attr != FLUSH_MID))
|| (pos > MAX_PRN_LEN))
{
return;
}
if ((fmt == DB_HTWDT_PRN) || (fmt == DB_HEIGT_PRN))
{
obj[0] = PRN_HEIGHT_48;
}
if (fmt == NM_BMP_PRN) // LOGO打印只需设置格式和点缓冲行数.
{
obj[0] = PRN_HEIGHT_BMP;
obj[2] = NM_BMP_PRN;
obj[3] = *str; // 保留,Logo序号.
return;
}
// 根据属性,重新定位起始位置pos.
if (attr == FLUSH_RIGHT)
{
len = strlen(str);
if ((fmt == DB_HTWDT_PRN) || (fmt == DB_WIDTH_PRN))
{
len *= 2; // 双宽属性,实际打印长度加倍.
}
if (len >= pos)
{
pos = 1; // 传入的字符串超过长度,自动舍去超出部分.
}
else
{
pos = pos + 1 - len;
}
}
else if (attr == FLUSH_MID)
{
len = strlen(str);
if ((fmt == DB_HTWDT_PRN) || (fmt == DB_WIDTH_PRN))
{
len *= 2; // 双宽属性,实际打印长度加倍.
}
if (len/2 >= pos)
{
pos = 1; // 字符起始位置超出.
}
else
{
pos = pos + 1 - len/2;
}
}
for (i=pos; i<=MAX_PRN_LEN; )
{
if (*str == 0)
{
break;
}
obj[i*2] = fmt;
obj[i*2+1] = *str++;
i++;
if (i > MAX_PRN_LEN)
{
// 最后一个字符双宽,超过了打印宽度,自动修改之.
if ((fmt == DB_HTWDT_PRN) || (fmt == DB_WIDTH_PRN))
{
obj[2*(i-1)] = NM_FONT_PRN;
}
break;
}
if ((fmt == DB_HTWDT_PRN) || (fmt == DB_WIDTH_PRN))
{
obj[2*i] = PRN_DBWD_FREE_BYTE;
obj[2*i+1] = PRN_DBWD_FREE_BYTE;
i++;
}
}
}
///////////////////////////////////////////////////////////////////////////////
// Descript: The printing format string copy.
// In Param: *src -- 上层传递下来的打印缓冲数据, 这个打印缓冲数据中已经含有打印格式
// pos -- 字符位置, 1~MAX_PRN_LEN
// len -- 打印长度, 即src下传数据长度的一半.
// attr -- 属性, 靠左, 靠右, 居中对齐等. 对于以前的memcpy来说,这个参数
// 可以考虑不要, 依最后情况而定.
// Out Param: void
// Return: void
///////////////////////////////////////////////////////////////////////////////
void Prn_InsFmtStr(const byte *src, byte pos, byte len, byte attr)
{
byte temp[PRN_FMTED_BUF_LEN];
byte i;
byte maxDotLine = PRN_HEIGHT_24;
byte maxPos;
if (pos > MAX_PRN_LEN)
{
return; // 起始位置超出.
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -