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 */
 |