428 lines
12 KiB
C
428 lines
12 KiB
C
/*******************************************************************
|
|
**
|
|
** *********************************************************
|
|
** *
|
|
** * File: PclSFonts.c
|
|
** *
|
|
** * Contents:
|
|
** * Send Soft Font Download data to the specified
|
|
** * file pointer.
|
|
** *
|
|
** * Created: 3/4/96
|
|
** *
|
|
** *********************************************************
|
|
**
|
|
********************************************************************/
|
|
/*
|
|
(c) Copyright 1996 Hewlett-Packard Company
|
|
(c) Copyright 1996 International Business Machines Corp.
|
|
(c) Copyright 1996 Sun Microsystems, Inc.
|
|
(c) Copyright 1996 Novell, Inc.
|
|
(c) Copyright 1996 Digital Equipment Corp.
|
|
(c) Copyright 1996 Fujitsu Limited
|
|
(c) Copyright 1996 Hitachi, Ltd.
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
in the Software without restriction, including without limitation the rights
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
all copies or substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
Except as contained in this notice, the names of the copyright holders shall
|
|
not be used in advertising or otherwise to promote the sale, use or other
|
|
dealings in this Software without prior written authorization from said
|
|
copyright holders.
|
|
*/
|
|
|
|
|
|
#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 /* PCL_FONT_COMPRESS */
|
|
|
|
/* -*- PclDownloadSoftFont8 -*-
|
|
* Send the Character Definition Command for 8-bit font
|
|
* **************************************************************************/
|
|
void
|
|
PclDownloadSoftFont8(
|
|
FILE *fp,
|
|
PclSoftFontInfoPtr pSoftFontInfo,
|
|
PclFontHead8Ptr pfh,
|
|
PclCharDataPtr pcd,
|
|
unsigned char *code
|
|
)
|
|
{
|
|
/*
|
|
* Check whether the font header has already been downloaded.
|
|
* If not, download it.
|
|
*/
|
|
|
|
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]);
|
|
|
|
}
|
|
|
|
/* -*- PclDownloadSoftFont16 -*-
|
|
* Send the Character Definition Command for 16 bit font
|
|
* **************************************************************************/
|
|
void
|
|
PclDownloadSoftFont16(
|
|
FILE *fp,
|
|
PclSoftFontInfoPtr pSoftFontInfo,
|
|
PclFontHead16Ptr pfh,
|
|
PclCharDataPtr pcd,
|
|
unsigned char row,
|
|
unsigned char col
|
|
)
|
|
{
|
|
/*
|
|
* Check whether the font header is already downloaded.
|
|
* If not, download it.
|
|
*/
|
|
|
|
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);
|
|
}
|
|
|
|
/* -*- PclCreateSoftFontInfo -*-
|
|
* Create and Initialize the structure for storing the information
|
|
* of the downloaded soft font.
|
|
* **************************************************************************/
|
|
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;
|
|
}
|
|
|
|
/* -*- PclDestroySoftFontInfo -*-
|
|
* Destroy the soft font information structure
|
|
* **************************************************************************/
|
|
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);
|
|
}
|
|
|
|
/* -*- PclDownloadHeader -*-
|
|
* Send the Font Header Commnad.
|
|
* Format 0 : Font Header for Pcl Bitmapped Fonts
|
|
* Format 20 : Font Header for Resolution Specified Bitmapped Fonts
|
|
* **************************************************************************/
|
|
static unsigned int
|
|
PclDownloadHeader(
|
|
FILE *fp,
|
|
PclFontDescPtr fd,
|
|
unsigned short fid
|
|
)
|
|
{
|
|
int nbytes;
|
|
|
|
#ifdef XP_PCL_LJ3
|
|
nbytes = 64;
|
|
#else
|
|
nbytes = 68;
|
|
#endif /* XP_PCL_LJ3 */
|
|
/*
|
|
* Font ID Command : Esc *c#D
|
|
* (Default = 0, Range = 0 - 32767)
|
|
*/
|
|
fprintf(fp, "%c*c%dD", ESC, fid);
|
|
|
|
/*
|
|
* Font Header Commnad : Esc )s#W[font header data]
|
|
* (Default = 0, Range = 0 - 32767)
|
|
*/
|
|
fprintf(fp, "%c)s%dW", ESC, nbytes);
|
|
|
|
Put2bytes(fp, nbytes); /* Font Description Size */
|
|
#ifdef XP_PCL_LJ3
|
|
Put1byte(fp, 0); /* Header Format */
|
|
#else
|
|
Put1byte(fp, 20); /* Header Format */
|
|
#endif /* XP_PCL_LJ3 */
|
|
Put1byte(fp, 2); /* Font Type */
|
|
Put2bytes(fp, 0); /* Style MSB */
|
|
Put2bytes(fp, fd->ascent); /* BaseLine Position */
|
|
Put2bytes(fp, fd->cellwidth); /* Cell Width */
|
|
Put2bytes(fp, fd->cellheight); /* Cell Height */
|
|
Put1byte(fp, 0); /* Orienation */
|
|
Put1byte(fp, fd->spacing); /* Spacing */
|
|
Put2bytes(fp, SYMBOL_SET); /* Symbol Set */
|
|
Put2bytes(fp, fd->pitch*4); /* font pitch */
|
|
Put2bytes(fp, fd->cellheight * 4); /* Height */
|
|
Put2bytes(fp, 0); /* x-Height */
|
|
Put1byte(fp, 0); /* width type (normal) */
|
|
Put1byte(fp, 0); /* Style LSB */
|
|
Put1byte(fp, 0); /* Stroke Weight */
|
|
Put1byte(fp, 5); /* Typeface LSB */
|
|
Put1byte(fp, 0); /* Typeface MSB */
|
|
Put1byte(fp, 0); /* Serif Style */
|
|
Put1byte(fp, 0); /* Quality */
|
|
Put1byte(fp, 0); /* Placement */
|
|
Put1byte(fp, 0); /* Underline Position */
|
|
Put1byte(fp, 0); /* Underline Thickness */
|
|
Put2bytes(fp, fd->cellheight*1.2); /* Text Height */
|
|
Put2bytes(fp, fd->cellwidth * 4); /* Text Width */
|
|
Put2bytes(fp, 0); /* First Code */
|
|
Put2bytes(fp, 255); /* Last Code */
|
|
Put1byte(fp, 0); /* Pitch Extend */
|
|
Put1byte(fp, 0); /* Height Extend */
|
|
Put2bytes(fp, 0); /* Cap Height */
|
|
Put2bytes(fp, 0); /* Font Number 1 */
|
|
Put2bytes(fp, 0); /* Font Number 2 */
|
|
Put2bytes(fp, 0); /* Font Name */
|
|
Put2bytes(fp, 0); /* Font Name */
|
|
Put2bytes(fp, 0); /* Font Name */
|
|
Put2bytes(fp, 0); /* Font Name */
|
|
Put2bytes(fp, 0); /* Font Name */
|
|
Put2bytes(fp, 0); /* Font Name */
|
|
Put2bytes(fp, 0); /* Font Name */
|
|
Put2bytes(fp, 0); /* Font Name */
|
|
|
|
#ifdef XP_PCL_LJ3
|
|
return 64;
|
|
#else
|
|
Put2bytes(fp, 300); /* X Resolution */
|
|
Put2bytes(fp, 300); /* Y Resolution */
|
|
return 68;
|
|
#endif /* XP_PCL_LJ3 */
|
|
|
|
}
|
|
|
|
/* -*- PclDownloadCharacter -*-
|
|
* Send the Character Definition Command.
|
|
* **************************************************************************/
|
|
static unsigned int
|
|
PclDownloadChar(
|
|
FILE *fp,
|
|
PclCharDataPtr cd,
|
|
unsigned short fid,
|
|
unsigned char code
|
|
)
|
|
{
|
|
unsigned int nbytes, n;
|
|
unsigned char *raster;
|
|
|
|
/*
|
|
* Font ID Command : Esc *c#D
|
|
* (Default = 0, Range = 0 - 32767)
|
|
* Character Code Command : Esc *c#E
|
|
* (Default = 0, Range = 0 - 65535)
|
|
*/
|
|
fprintf(fp, "%c*c%dd%dE", ESC, fid, code);
|
|
|
|
/*
|
|
* Character Definition Command : Esc (s#W[character descriptor and data]
|
|
* (Default = N/A, Range = 0 - 32767)
|
|
*/
|
|
|
|
nbytes = n = cd->height * ((cd->width + 7) / 8);
|
|
#ifdef PCL_FONT_COMPRESS
|
|
raster = compress_bitmap_data(cd, &nbytes);
|
|
#else
|
|
raster = (unsigned char *)NULL;
|
|
#endif /* PCL_FONT_COMPRESS */
|
|
fprintf(fp, "%c(s%dW", ESC, nbytes + 16);
|
|
|
|
Put1byte(fp, 4); /* Format */
|
|
Put1byte(fp, 0); /* Continuation */
|
|
Put1byte(fp, 14); /* Descriptor Size */
|
|
if (raster) { /* Class */
|
|
Put1byte(fp, 2);
|
|
} else {
|
|
Put1byte(fp, 1); /* Class */
|
|
}
|
|
Put2bytes(fp, 0); /* Orientation */
|
|
Put2bytes(fp, cd->h_offset); /* left offset */
|
|
Put2bytes(fp, cd->v_offset); /* top offset */
|
|
Put2bytes(fp, cd->width); /* character width */
|
|
Put2bytes(fp, cd->height); /* character height */
|
|
Put2bytes(fp, cd->font_pitch*4); /* delta X */
|
|
|
|
/*
|
|
* Raster Character Data
|
|
*/
|
|
if (raster) {
|
|
fwrite(raster, nbytes, 1, fp);
|
|
xfree(raster);
|
|
} else
|
|
fwrite(cd->raster_top, nbytes, 1, fp);
|
|
|
|
return n + 16;
|
|
}
|
|
|
|
|
|
#ifdef PCL_FONT_COMPRESS
|
|
/* -*- compress_bitmap_data -*-
|
|
* Compress Bitmap data
|
|
* **************************************************************************/
|
|
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;
|
|
|
|
/* Create buffer for storing compress bitmap glyph */
|
|
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 /* PCL_FONT_COMPRESS */
|