#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include <stdio.h>
#include "Pcl.h"
static char tmp1;
static short tmp2;
#define Put1byte(fp, x) tmp1=x; fwrite((char *)&tmp1, 1, 1, fp)
#define Put2bytes(fp, x) tmp2=x; fwrite((char *)&tmp2, 2, 1, fp)
#define ESC 0x1b
#define SYMBOL_SET 277
static unsigned int PclDownloadChar(FILE *,PclCharDataPtr,unsigned short,unsigned char);
static unsigned int PclDownloadHeader(FILE *, PclFontDescPtr, unsigned short);
#ifdef PCL_FONT_COMPRESS
static unsigned char *compress_bitmap_data(PclCharDataPtr, unsigned int *);
#endif
void
PclDownloadSoftFont8(
FILE *fp,
PclSoftFontInfoPtr pSoftFontInfo,
PclFontHead8Ptr pfh,
PclCharDataPtr pcd,
unsigned char *code
)
{
if ( !pfh->fid ) {
pfh->fid = pSoftFontInfo->cur_max_fid++;
PclDownloadHeader(fp, &(pfh->fd), pfh->fid);
}
pfh->index[*code] = *code;
PclDownloadChar(fp, pcd, pfh->fid, pfh->index[*code]);
}
void
PclDownloadSoftFont16(
FILE *fp,
PclSoftFontInfoPtr pSoftFontInfo,
PclFontHead16Ptr pfh,
PclCharDataPtr pcd,
unsigned char row,
unsigned char col
)
{
if ( !pfh->cur_cindex ) {
pfh->cur_fid = pSoftFontInfo->cur_max_fid++;
PclDownloadHeader(fp, &(pfh->fd), pfh->cur_fid);
}
pfh->index[row][col].fid = pfh->cur_fid;
pfh->index[row][col].cindex = pfh->cur_cindex++;
PclDownloadChar(fp, pcd, pfh->index[row][col].fid, pfh->index[row][col].cindex);
}
PclSoftFontInfoPtr
PclCreateSoftFontInfo(void)
{
PclSoftFontInfoPtr pSoftFontInfo;
pSoftFontInfo = (PclSoftFontInfoPtr)xalloc(sizeof(PclSoftFontInfoRec));
if ( pSoftFontInfo == (PclSoftFontInfoPtr) NULL)
return (PclSoftFontInfoPtr) NULL;
pSoftFontInfo->phead8 = (PclFontHead8Ptr)NULL;
pSoftFontInfo->phead16 = (PclFontHead16Ptr)NULL;
pSoftFontInfo->pinfont = (PclInternalFontPtr)NULL;
pSoftFontInfo->cur_max_fid = 1;
return pSoftFontInfo;
}
void
PclDestroySoftFontInfo( PclSoftFontInfoPtr pSoftFontInfo )
{
PclFontHead8Ptr pfh8, pfh8_next;
PclFontHead16Ptr pfh16, pfh16_next;
PclInternalFontPtr pin, pin_next;
unsigned char nindex_row;
int i;
if ( pSoftFontInfo == (PclSoftFontInfoPtr) NULL )
return;
pfh8 = pSoftFontInfo->phead8;
while (pfh8 != (PclFontHead8Ptr) NULL) {
xfree(pfh8->fontname);
xfree(pfh8->index);
pfh8_next = pfh8->next;
xfree(pfh8);
pfh8 = pfh8_next;
}
pfh16 = pSoftFontInfo->phead16;
while (pfh16 != (PclFontHead16Ptr) NULL) {
xfree(pfh16->fontname);
nindex_row = pfh16->lastRow - pfh16->firstRow + 1;
for (i=0; i<nindex_row; i++)
xfree(pfh16->index[i]);
xfree(pfh16->index);
pfh16_next = pfh16->next;
xfree(pfh16);
pfh16 = pfh16_next;
}
pin = pSoftFontInfo->pinfont;
while (pin != (PclInternalFontPtr) NULL) {
xfree(pin->fontname);
pin_next = pin->next;
xfree(pin);
pin = pin_next;
}
xfree(pSoftFontInfo);
}
static unsigned int
PclDownloadHeader(
FILE *fp,
PclFontDescPtr fd,
unsigned short fid
)
{
int nbytes;
#ifdef XP_PCL_LJ3
nbytes = 64;
#else
nbytes = 68;
#endif
fprintf(fp, "%c*c%dD", ESC, fid);
fprintf(fp, "%c)s%dW", ESC, nbytes);
Put2bytes(fp, nbytes);
#ifdef XP_PCL_LJ3
Put1byte(fp, 0);
#else
Put1byte(fp, 20);
#endif
Put1byte(fp, 2);
Put2bytes(fp, 0);
Put2bytes(fp, fd->ascent);
Put2bytes(fp, fd->cellwidth);
Put2bytes(fp, fd->cellheight);
Put1byte(fp, 0);
Put1byte(fp, fd->spacing);
Put2bytes(fp, SYMBOL_SET);
Put2bytes(fp, fd->pitch*4);
Put2bytes(fp, fd->cellheight * 4);
Put2bytes(fp, 0);
Put1byte(fp, 0);
Put1byte(fp, 0);
Put1byte(fp, 0);
Put1byte(fp, 5);
Put1byte(fp, 0);
Put1byte(fp, 0);
Put1byte(fp, 0);
Put1byte(fp, 0);
Put1byte(fp, 0);
Put1byte(fp, 0);
Put2bytes(fp, fd->cellheight*1.2);
Put2bytes(fp, fd->cellwidth * 4);
Put2bytes(fp, 0);
Put2bytes(fp, 255);
Put1byte(fp, 0);
Put1byte(fp, 0);
Put2bytes(fp, 0);
Put2bytes(fp, 0);
Put2bytes(fp, 0);
Put2bytes(fp, 0);
Put2bytes(fp, 0);
Put2bytes(fp, 0);
Put2bytes(fp, 0);
Put2bytes(fp, 0);
Put2bytes(fp, 0);
Put2bytes(fp, 0);
Put2bytes(fp, 0);
#ifdef XP_PCL_LJ3
return 64;
#else
Put2bytes(fp, 300);
Put2bytes(fp, 300);
return 68;
#endif
}
static unsigned int
PclDownloadChar(
FILE *fp,
PclCharDataPtr cd,
unsigned short fid,
unsigned char code
)
{
unsigned int nbytes, n;
unsigned char *raster;
fprintf(fp, "%c*c%dd%dE", ESC, fid, code);
nbytes = n = cd->height * ((cd->width + 7) / 8);
#ifdef PCL_FONT_COMPRESS
raster = compress_bitmap_data(cd, &nbytes);
#else
raster = (unsigned char *)NULL;
#endif
fprintf(fp, "%c(s%dW", ESC, nbytes + 16);
Put1byte(fp, 4);
Put1byte(fp, 0);
Put1byte(fp, 14);
if (raster) {
Put1byte(fp, 2);
} else {
Put1byte(fp, 1);
}
Put2bytes(fp, 0);
Put2bytes(fp, cd->h_offset);
Put2bytes(fp, cd->v_offset);
Put2bytes(fp, cd->width);
Put2bytes(fp, cd->height);
Put2bytes(fp, cd->font_pitch*4);
if (raster) {
fwrite(raster, nbytes, 1, fp);
xfree(raster);
} else
fwrite(cd->raster_top, nbytes, 1, fp);
return n + 16;
}
#ifdef PCL_FONT_COMPRESS
static unsigned char *
compress_bitmap_data(
PclCharDataPtr cd,
unsigned int *nbytes
)
{
unsigned int byte_width;
unsigned char *raster, *rptr_s, *rptr_e, *rptr_end;
unsigned char *tmp_s, *tmp_ptr;
unsigned char *p;
unsigned char cur, pixel;
unsigned int num;
int i, j, k, w;
byte_width = (cd->width + 7) / 8;
*nbytes = cd->height * byte_width;
raster = (unsigned char *)xalloc(*nbytes);
rptr_s = raster;
rptr_e = raster;
rptr_end = raster + *nbytes;
tmp_s = (unsigned char *)xalloc(cd->width * 8 + 2);
p = cd->raster_top;
for (i=0; i<cd->height; i++) {
tmp_ptr = tmp_s;
*tmp_ptr++ = 0;
if ( (*p>>7)&0x1 == 1 ) {
*tmp_ptr++ = 0;
cur = 1;
} else {
cur = 0;
}
num = 0;
for (j=0, w=0; j<byte_width; j++, p++) {
for (k=0; k<8 && w<cd->width; k++, w++) {
pixel = (*p>>(7-k))&0x1;
if ( pixel == cur ) {
num++;
} else {
cur = pixel;
while (num > 255) {
*tmp_ptr++ = 255;
*tmp_ptr++ = 0;
num -= 255;
}
*tmp_ptr++ = num;
num = 1;
}
}
}
if ( pixel == cur ) {
while (num > 255) {
*tmp_ptr++ = 255;
*tmp_ptr++ = 0;
num -= 255;
}
*tmp_ptr++ = num&0xff;
} else
*tmp_ptr++ = num;
if ( ((rptr_e - rptr_s) == (tmp_ptr - tmp_s)) &&
!memcmp(rptr_s+1, tmp_s+1, (tmp_ptr - tmp_s) - 1) )
*rptr_s += 1;
else {
if ( rptr_e + (tmp_ptr - tmp_s) > rptr_end ) {
xfree(raster);
xfree(tmp_s);
return (unsigned char *)NULL;
}
memcpy (rptr_e, tmp_s, tmp_ptr - tmp_s);
rptr_s = rptr_e;
rptr_e = rptr_s + (tmp_ptr - tmp_s);
}
}
xfree(tmp_s);
*nbytes = rptr_e - raster;
return raster;
}
#endif