937 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			937 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			C
		
	
	
	
| /* $Xorg: PclText.c,v 1.5 2001/03/06 16:28:48 pookie Exp $ */
 | |
| /*******************************************************************
 | |
| **
 | |
| **    *********************************************************
 | |
| **    *
 | |
| **    *  File:		PclText.c
 | |
| **    *
 | |
| **    *  Contents:
 | |
| **    *                 Character-drawing routines for the PCL DDX
 | |
| **    *
 | |
| **    *  Created:	10/23/95
 | |
| **    *
 | |
| **    *********************************************************
 | |
| ** 
 | |
| ********************************************************************/
 | |
| /*
 | |
| (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.
 | |
| */
 | |
| /* $XFree86: xc/programs/Xserver/Xprint/pcl/PclText.c,v 1.10tsi Exp $ */
 | |
| 
 | |
| #ifdef HAVE_DIX_CONFIG_H
 | |
| #include <dix-config.h>
 | |
| #endif
 | |
| 
 | |
| #ifdef DO_TWO_BYTE_PCL
 | |
| #include "iconv.h"
 | |
| #endif /* DO_TWO_BYTE_PCL */
 | |
| #include "gcstruct.h"
 | |
| #include "windowstr.h"
 | |
| 
 | |
| #include "Pcl.h"
 | |
| #include "migc.h"
 | |
| #include <X11/Xatom.h>
 | |
| 
 | |
| #include "PclSFonts.h"
 | |
| 
 | |
| static PclFontHead8Ptr  makeFontHeader8 (FontPtr, PclSoftFontInfoPtr);
 | |
| static PclFontHead16Ptr makeFontHeader16(FontPtr, PclSoftFontInfoPtr);
 | |
| static PclInternalFontPtr makeInternalFont(FontPtr, PclSoftFontInfoPtr);
 | |
| static void             fillFontDescData(FontPtr, PclFontDescPtr, unsigned int);
 | |
| static PclCharDataPtr   fillCharDescData(PclCharDataPtr, CharInfoPtr);
 | |
| static void             output_text(FILE *, PclContextPrivPtr, unsigned char);
 | |
| static char *           getFontName(FontPtr);
 | |
| static char             isInternal(FontPtr);
 | |
| static void             selectInternalFont(FILE *, PclInternalFontPtr, int);
 | |
| static void             selectSize(FILE *, PclContextPrivPtr, PclInternalFontPtr);
 | |
| static char t[80];
 | |
| 
 | |
| #ifdef DO_TWO_BYTE_PCL
 | |
| static void             code_conv(PclSoftFontInfoPtr, FontPtr, char *, char *);
 | |
| #endif /* DO_TWO_BYTE_PCL */
 | |
| 
 | |
| #define ESC 0x1b
 | |
| #define PER 0x25
 | |
| #define ETX 0x3
 | |
| #define ETX_ALT 0x2a
 | |
| #define DOWNLOAD_FONT 0
 | |
| #define INTERNAL_FONT 1
 | |
| 
 | |
| int
 | |
| PclPolyText8(
 | |
|      DrawablePtr pDrawable,
 | |
|      GCPtr pGC,
 | |
|      int x,
 | |
|      int y,
 | |
|      int count,
 | |
|      char *string)
 | |
| {
 | |
| XpContextPtr pCon;
 | |
| PclContextPrivPtr pConPriv;
 | |
| unsigned long n, i;
 | |
| int w;
 | |
| CharInfoPtr charinfo[255], *chinfo;
 | |
| 
 | |
| FILE *outFile;
 | |
| PclSoftFontInfoPtr pSoftFontInfo;
 | |
| PclFontHead8Ptr pfh8 = (PclFontHead8Ptr)NULL;
 | |
| PclInternalFontPtr pin = (PclInternalFontPtr)NULL;
 | |
| PclCharDataRec cd;
 | |
| unsigned char *p;
 | |
| unsigned char last_fid;
 | |
| int max_ascent, max_descent;
 | |
| 
 | |
| int nbox;
 | |
| BoxPtr pbox;
 | |
| BoxRec box;
 | |
| RegionPtr drawRegion, region;
 | |
| char font_type;
 | |
| 
 | |
|     if( PclUpdateDrawableGC( pGC, pDrawable, &outFile ) == FALSE )
 | |
| 	return x;
 | |
| 
 | |
|     GetGlyphs(pGC->font, (unsigned long)count, (unsigned char *)string,
 | |
| 						Linear8Bit, &n, charinfo);
 | |
|     if ( n == 0 )
 | |
| 	return x;
 | |
| 
 | |
|     pCon = PclGetContextFromWindow( (WindowPtr)pDrawable );
 | |
|     pConPriv = (PclContextPrivPtr)
 | |
| 			pCon->devPrivates[PclContextPrivateIndex].ptr;
 | |
|     pSoftFontInfo = pConPriv->pSoftFontInfo;
 | |
|     font_type = isInternal(pGC->font);
 | |
|     if ( font_type == DOWNLOAD_FONT ) {
 | |
| 	/*
 | |
|  	 * Create Soft Font Header Information
 | |
|  	 */
 | |
| 	pfh8 = makeFontHeader8(pGC->font, pSoftFontInfo);
 | |
| 	if (!pfh8)
 | |
| 	    return x;
 | |
| 
 | |
| 	/*
 | |
| 	 * exec Soft Font Downloading
 | |
| 	 */
 | |
| 	p = (unsigned char *)string;
 | |
| 	for (i=0, chinfo=charinfo; i<n; i++, p++, chinfo++) {
 | |
| 	    if ( !pfh8->index[*p] ) {
 | |
| 		fillCharDescData(&cd, *chinfo);
 | |
|         	PclDownloadSoftFont8(pConPriv->pJobFile, pSoftFontInfo,
 | |
| 					pfh8, &cd, p);
 | |
|         	xfree(cd.raster_top);
 | |
| 	    }
 | |
| 	}
 | |
| 
 | |
| 	/*
 | |
| 	 * print characters
 | |
| 	 */
 | |
| 	MACRO_START( outFile, pConPriv );
 | |
| 	sprintf(t, "\033%%0B;PU%d,%dPD;TD1;DT%c,1;",
 | |
|                 x + pDrawable->x, y + pDrawable->y + pGC->font->info.fontAscent,
 | |
| 		ETX);
 | |
| 	SAVE_PCL( outFile, pConPriv, t );
 | |
| 	SAVE_PCL_COUNT( outFile, pConPriv, "FI0;SS;LB", 9 );
 | |
| 
 | |
| 	last_fid = 0;
 | |
| 	w = 0;
 | |
| 	max_ascent = charinfo[0]->metrics.ascent;
 | |
| 	max_descent = charinfo[0]->metrics.descent;
 | |
| 	p = (unsigned char *)string;
 | |
| 	for (i=0, chinfo=charinfo; i<n; i++, p++, chinfo++) {
 | |
| 	    if  ( last_fid != pfh8->fid ) {
 | |
| 		sprintf(t, "%c;FI%d;SS;LB", ETX, pfh8->fid);
 | |
| 		SAVE_PCL( outFile, pConPriv, t );
 | |
| 
 | |
| 		last_fid = pfh8->fid;
 | |
| 	    }
 | |
| 
 | |
| 	    output_text(outFile, pConPriv, pfh8->index[*p]);
 | |
| 
 | |
| 	    w += (*chinfo)->metrics.characterWidth;
 | |
| 	    max_ascent = MAX(max_ascent, (*chinfo)->metrics.ascent);
 | |
| 	    max_descent = MAX(max_descent, (*chinfo)->metrics.descent);
 | |
| 	}
 | |
| 
 | |
| 	sprintf(t, "%c", ETX);
 | |
| 	SAVE_PCL_COUNT( outFile, pConPriv, t, 1 );
 | |
| 	sprintf(t, "TD0;\033%%1A");
 | |
| 	SAVE_PCL( outFile, pConPriv, t );
 | |
| 	MACRO_END( outFile );
 | |
| 
 | |
|     } else {
 | |
| 	int fid = 0;
 | |
| 
 | |
| 	pin = makeInternalFont(pGC->font, pSoftFontInfo);
 | |
| 	if (!pin)
 | |
| 	    return x;
 | |
| 
 | |
| 	selectInternalFont(outFile, pin, fid);
 | |
| 
 | |
| 	/*
 | |
| 	 * print characters
 | |
| 	 */
 | |
| 	MACRO_START( outFile, pConPriv );
 | |
| 	sprintf(t, "\033%%0B;PU%d,%dPD;TD1;DT%c,1;",
 | |
| 		x + pDrawable->x, y + pDrawable->y + pGC->font->info.fontAscent,
 | |
| 		ETX);
 | |
| 	SAVE_PCL( outFile, pConPriv, t );
 | |
| 	selectSize(outFile, pConPriv, pin);
 | |
| 	SAVE_PCL_COUNT( outFile, pConPriv, "FI0;SS;LB", 9 );
 | |
| 
 | |
| 	w = 0;
 | |
| 	max_ascent = charinfo[0]->metrics.ascent;
 | |
| 	max_descent = charinfo[0]->metrics.descent;
 | |
| 	p = (unsigned char *)string;
 | |
| 	for (i=0, chinfo=charinfo; i<n; i++, p++, chinfo++) {
 | |
| 	    output_text(outFile, pConPriv, *p);
 | |
| 
 | |
| 	    w += (*chinfo)->metrics.characterWidth;
 | |
| 	    max_ascent = MAX(max_ascent, (*chinfo)->metrics.ascent);
 | |
| 	    max_descent = MAX(max_descent, (*chinfo)->metrics.descent);
 | |
| 	}
 | |
| 	sprintf(t, "%c", ETX);
 | |
| 	SAVE_PCL_COUNT( outFile, pConPriv, t, 1 );
 | |
| 	sprintf(t, "TD0;\033%%1A");
 | |
| 	SAVE_PCL( outFile, pConPriv, t );
 | |
| 	MACRO_END( outFile );
 | |
|     }
 | |
| 
 | |
|     /*
 | |
|      * Convert the collection of rectangles into a proper region, then
 | |
|      * intersect it with the clip region.
 | |
|      */
 | |
|     box.x1 = x +  pDrawable->x;
 | |
|     box.y1 = y - max_ascent + pDrawable->y + pGC->font->info.fontAscent;
 | |
|     box.x2 = x + w + pDrawable->x;
 | |
|     box.y2 = y + max_descent + pDrawable->y + pGC->font->info.fontAscent;
 | |
| 
 | |
|     drawRegion = miRegionCreate( &box, 0 );
 | |
|     region = miRegionCreate( NULL, 0 );
 | |
|     miIntersect( region, drawRegion, pGC->pCompositeClip );
 | |
| 
 | |
|     /*
 | |
|      * For each rectangle in the clip region, set the HP-GL/2 "input
 | |
|      * window" and render the entire polyline to it.
 | |
|      */
 | |
|     pbox = REGION_RECTS( region );
 | |
|     nbox = REGION_NUM_RECTS( region );
 | |
| 
 | |
|     PclSendData(outFile, pConPriv, pbox, nbox, 1.0);
 | |
| 
 | |
|     /*
 | |
|      * Clean up the temporary regions
 | |
|      */
 | |
|     REGION_DESTROY( pGC->pScreen, drawRegion );
 | |
|     REGION_DESTROY( pGC->pScreen, region );
 | |
| 
 | |
|     return x+w;
 | |
| }
 | |
| 
 | |
| int
 | |
| PclPolyText16(
 | |
|      DrawablePtr pDrawable,
 | |
|      GCPtr pGC,
 | |
|      int x,
 | |
|      int y,
 | |
|      int count,
 | |
|      unsigned short *string)
 | |
| {
 | |
| XpContextPtr pCon;
 | |
| PclContextPrivPtr pConPriv;
 | |
| unsigned long n, i;
 | |
| int w;
 | |
| CharInfoPtr charinfo[255], *chinfo;
 | |
| 
 | |
| FILE *outFile;
 | |
| PclSoftFontInfoPtr pSoftFontInfo;
 | |
| PclFontHead16Ptr pfh16 = (PclFontHead16Ptr)NULL;
 | |
| PclCharDataRec cd;
 | |
| FontInfoPtr pfi;
 | |
| unsigned char row, col;
 | |
| char *p;
 | |
| unsigned char last_fid;
 | |
| int max_ascent, max_descent;
 | |
| unsigned short def;
 | |
| 
 | |
| int nbox;
 | |
| BoxPtr pbox;
 | |
| BoxRec box;
 | |
| RegionPtr drawRegion, region;
 | |
| char font_type;
 | |
| 
 | |
|     if( PclUpdateDrawableGC( pGC, pDrawable, &outFile ) == FALSE )
 | |
| 	return x;
 | |
| 
 | |
|     GetGlyphs(pGC->font, (unsigned long)count, (unsigned char *)string,
 | |
| 		(FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit,
 | |
| 		&n, charinfo);
 | |
| 
 | |
|     pCon = PclGetContextFromWindow( (WindowPtr)pDrawable );
 | |
|     pConPriv = (PclContextPrivPtr)
 | |
| 			pCon->devPrivates[PclContextPrivateIndex].ptr;
 | |
|     pSoftFontInfo = pConPriv->pSoftFontInfo;
 | |
| 
 | |
|     font_type = isInternal(pGC->font);
 | |
|     if ( font_type == DOWNLOAD_FONT ) {
 | |
| 	/*
 | |
| 	 * Create Soft Font Header Information
 | |
| 	 */
 | |
| 	pfh16 = makeFontHeader16(pGC->font, pSoftFontInfo);
 | |
| 	if (!pfh16)
 | |
| 	    return x;
 | |
| 
 | |
| 	/*
 | |
| 	 * exec Soft Font Downloading
 | |
| 	 */
 | |
| 	pfi = (FontInfoRec *)&pGC->font->info;
 | |
| 	p = (char *)string;
 | |
| 	for (i=0, p=(char *)string, chinfo=charinfo; i<n; i++, p+=2, chinfo++) {
 | |
| 	    row = *p & 0xff;
 | |
| 	    col = *(p+1) & 0xff;
 | |
| 	    if ( (pfi->firstRow <= row) && (row <= pfi->lastRow)
 | |
| 		&& (pfi->firstCol <= col) && (col <= pfi->lastCol) ) {
 | |
| 		row = row - pfi->firstRow;
 | |
| 		col = col - pfi->firstCol;
 | |
| 	    } else {
 | |
| 		def = pfi->defaultCh;
 | |
| 		row = ((def>>8)&0xff) - pfi->firstRow;
 | |
| 		col = (def&0xff) - pfi->firstCol;
 | |
| 	    }
 | |
| 	    if ( !pfh16->index[row][col].fid ) {
 | |
| 		fillCharDescData(&cd, *chinfo);
 | |
| 		PclDownloadSoftFont16(pConPriv->pJobFile, pSoftFontInfo,
 | |
| 				pfh16, &cd, row, col);
 | |
| 		xfree(cd.raster_top);
 | |
| 	    }
 | |
| 	}
 | |
| 
 | |
| 	/*
 | |
| 	 * print characters
 | |
| 	 */
 | |
| 	MACRO_START( outFile, pConPriv );
 | |
| 	sprintf(t, "\033%%0B;PU%d,%dPD;TD1;DT%c,1;",
 | |
| 		x + pDrawable->x, y + pDrawable->y + pGC->font->info.fontAscent,
 | |
| 		ETX);
 | |
| 	SAVE_PCL( outFile, pConPriv, t );
 | |
| 	SAVE_PCL_COUNT( outFile, pConPriv, "FI0;SS;LB", 9 );
 | |
| 
 | |
| 	last_fid = 0;
 | |
| 
 | |
| 	w = 0;
 | |
| 	max_ascent = charinfo[0]->metrics.ascent;
 | |
| 	max_descent = charinfo[0]->metrics.descent;
 | |
| 	for (i=0, p=(char *)string, chinfo=charinfo; i<n; i++, p+=2, chinfo++) {
 | |
| 	    row = *p & 0xff;
 | |
| 	    col = *(p+1) & 0xff;
 | |
| 	    if ( (pfi->firstRow <= row) && (row <= pfi->lastRow)
 | |
| 		&& (pfi->firstCol <= col) && (col <= pfi->lastCol) ) {
 | |
| 		row = row - pfi->firstRow;
 | |
| 		col = col - pfi->firstCol;
 | |
| 	    } else {
 | |
| 		def = pfi->defaultCh;
 | |
| 		row = ((def>>8)&0xff) - pfi->firstRow;
 | |
| 		col = (def&0xff) - pfi->firstCol;
 | |
| 	    }
 | |
| 	    if ( last_fid != pfh16->index[row][col].fid ) {
 | |
| 		sprintf(t, "%cFI%d;SS;LB",
 | |
| 				ETX, pfh16->index[row][col].fid);
 | |
| 		SAVE_PCL( outFile, pConPriv, t );
 | |
| 		last_fid = pfh16->index[row][col].fid;
 | |
| 	    }
 | |
| 
 | |
| 	    output_text(outFile, pConPriv, pfh16->index[row][col].cindex);
 | |
| 
 | |
| 	    w += (*chinfo)->metrics.characterWidth;
 | |
| 	    max_ascent = MAX(max_ascent, (*chinfo)->metrics.ascent);
 | |
| 	    max_descent = MAX(max_descent, (*chinfo)->metrics.descent);
 | |
| 	}
 | |
| 	sprintf(t, "%c", ETX);
 | |
| 	SAVE_PCL_COUNT( outFile, pConPriv, t, 1 );
 | |
| 	sprintf(t, "TD0;\033%%1A");
 | |
| 	SAVE_PCL( outFile, pConPriv, t );
 | |
| 	MACRO_END( outFile );
 | |
| 
 | |
|     } else {
 | |
| #ifdef DO_TWO_BYTE_PCL
 | |
| 	PclInternalFontPtr pin;
 | |
| 	int fid = 0;
 | |
| 
 | |
| 	pin = makeInternalFont(pGC->font, pSoftFontInfo);
 | |
| 	if (!pin)
 | |
| 	    return x;
 | |
| 
 | |
| 	selectInternalFont(outFile, pin, fid);
 | |
| 	fprintf(outFile, "%c&t31P", ESC);
 | |
| 
 | |
| 	/*
 | |
| 	 * print characters
 | |
| 	 */
 | |
| 	MACRO_START( outFile, pConPriv );
 | |
| 	sprintf(t, "\033%%0B;PU%d,%dPD;TD1;DT%c,1;",
 | |
| 		x + pDrawable->x, y + pDrawable->y + pGC->font->info.fontAscent,
 | |
| 		ETX);
 | |
| 	SAVE_PCL( outFile, pConPriv, t );
 | |
| 	sprintf(t, "TD0;\033%%1A");
 | |
| 	SAVE_PCL( outFile, pConPriv, t );
 | |
| 
 | |
| 	w = 0;
 | |
| 	last_fid = 0;
 | |
| 	max_ascent = charinfo[0]->metrics.ascent;
 | |
| 	max_descent = charinfo[0]->metrics.descent;
 | |
| 	for (i=0, p=(char *)string, chinfo=charinfo; i<n; i++, p+=2, chinfo++) {
 | |
| 	    char tobuf[3];
 | |
| 	    code_conv(pSoftFontInfo, pGC->font, (char *)p, tobuf);
 | |
| 	    fprintf(outFile, "%c%c", tobuf[0], tobuf[1]);
 | |
| 
 | |
| 	    w += (*chinfo)->metrics.characterWidth;
 | |
| 	    max_ascent = MAX(max_ascent, (*chinfo)->metrics.ascent);
 | |
| 	    max_descent = MAX(max_descent, (*chinfo)->metrics.descent);
 | |
| 	}
 | |
| 	MACRO_END( outFile );
 | |
| #else
 | |
| 	return x;
 | |
| #endif /* DO_TWO_BYTE_PCL */
 | |
|     }
 | |
| 
 | |
|     /*
 | |
|      * Convert the collection of rectangles into a proper region, then
 | |
|      * intersect it with the clip region.
 | |
|      */
 | |
|     box.x1 = x + pDrawable->x;
 | |
|     box.y1 = y - max_ascent + pDrawable->y + pGC->font->info.fontAscent;
 | |
|     box.x2 = x + w + pDrawable->x;
 | |
|     box.y2 = y + max_descent + pDrawable->y + pGC->font->info.fontAscent;
 | |
| 
 | |
|     drawRegion = miRegionCreate( &box, 0 );
 | |
|     region = miRegionCreate( NULL, 0 );
 | |
|     miIntersect( region, drawRegion, pGC->pCompositeClip );
 | |
| 
 | |
|     /*
 | |
|      * For each rectangle in the clip region, set the HP-GL/2 "input
 | |
|      * window" and render the entire polyline to it.
 | |
|      */
 | |
|     pbox = REGION_RECTS( region );
 | |
|     nbox = REGION_NUM_RECTS( region );
 | |
| 
 | |
|     PclSendData(outFile, pConPriv, pbox, nbox, 1.0);
 | |
| 
 | |
|     /*
 | |
|      * Clean up the temporary regions
 | |
|      */
 | |
|     REGION_DESTROY( pGC->pScreen, drawRegion );
 | |
|     REGION_DESTROY( pGC->pScreen, region );
 | |
| 
 | |
|     return x+w;
 | |
| }
 | |
| 
 | |
| void
 | |
| PclImageText8(
 | |
|      DrawablePtr pDrawable,
 | |
|      GCPtr pGC, 
 | |
|      int x, int y,
 | |
|      int count,
 | |
|      char *string)
 | |
| {
 | |
| }
 | |
| 
 | |
| void
 | |
| PclImageText16(
 | |
|      DrawablePtr pDrawable,
 | |
|      GCPtr pGC,
 | |
|      int x,
 | |
|      int y,
 | |
|      int count,
 | |
|      unsigned short *string)
 | |
| {
 | |
| }
 | |
| 
 | |
| void
 | |
| PclImageGlyphBlt(
 | |
|      DrawablePtr pDrawable,
 | |
|      GCPtr pGC,
 | |
|      int x, int y,
 | |
|      unsigned int nGlyphs,
 | |
|      CharInfoPtr *pCharInfo,
 | |
|      pointer pGlyphBase)
 | |
| {
 | |
| }
 | |
| 
 | |
| void
 | |
| PclPolyGlyphBlt(
 | |
|      DrawablePtr pDrawable,
 | |
|      GCPtr pGC,
 | |
|      int x, int y,
 | |
|      unsigned int nGlyphs,
 | |
|      CharInfoPtr *pCharInfo,
 | |
|      pointer pGlyphBase)
 | |
| {
 | |
| }
 | |
| 
 | |
| /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 | |
| /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 | |
| 
 | |
| static PclFontHead8Ptr
 | |
| makeFontHeader8(FontPtr pfont, PclSoftFontInfoPtr pSoftFontInfo)
 | |
| {
 | |
| PclFontHead8Ptr phead8 = pSoftFontInfo->phead8;
 | |
| PclFontHead8Ptr pfh8 = phead8;
 | |
| PclFontHead8Ptr prev = (PclFontHead8Ptr)NULL;
 | |
| FontInfoPtr pfi;
 | |
| char *fontname;
 | |
| unsigned char nindex;
 | |
| int i;
 | |
| unsigned long n;
 | |
| CharInfoPtr charinfo[1];
 | |
| unsigned int space_width;
 | |
| 
 | |
|     if (pSoftFontInfo == (PclSoftFontInfoPtr) NULL)
 | |
| 	return (PclFontHead8Ptr)NULL;
 | |
| 
 | |
|     /*
 | |
|      * Verify it has already been created, if so, return it.
 | |
|      */
 | |
|     if ( (fontname = getFontName(pfont)) == (char *)NULL)
 | |
| 	return (PclFontHead8Ptr)NULL;
 | |
| 
 | |
|     while (pfh8 != (PclFontHead8Ptr) NULL) {
 | |
| 	if (!strcmp(pfh8->fontname, fontname))
 | |
| 	    return pfh8;
 | |
| 	prev = pfh8;
 | |
| 	pfh8 = pfh8->next;
 | |
|     }
 | |
| 
 | |
|     /*
 | |
|      * Create Font Header Information
 | |
|      */
 | |
|     pfh8 = (PclFontHead8Ptr)xalloc(sizeof(PclFontHead8Rec));
 | |
|     if (pfh8 == (PclFontHead8Ptr)NULL)
 | |
| 	return (PclFontHead8Ptr)NULL;
 | |
| 
 | |
|     pfi = (FontInfoRec *)&pfont->info;
 | |
|     GetGlyphs(pfont, 1, (unsigned char *)&pfi->defaultCh,
 | |
| 						Linear8Bit, &n, charinfo);
 | |
|     if ( n )
 | |
| 	space_width = charinfo[0]->metrics.characterWidth;
 | |
|     else
 | |
| 	space_width = FONTMAXBOUNDS(pfont,characterWidth);
 | |
| 
 | |
|     fillFontDescData(pfont, &(pfh8->fd), space_width);
 | |
|     pfh8->fid = 0;
 | |
|     pfh8->fontname = (char *)xalloc(strlen(fontname) + 1);
 | |
|     if (pfh8->fontname == (char *)NULL) {
 | |
| 	xfree(pfh8);
 | |
| 	return (PclFontHead8Ptr) NULL;
 | |
|     }
 | |
|     strcpy(pfh8->fontname, fontname);
 | |
| 
 | |
|     nindex = 0xff;
 | |
|     pfh8->index = (unsigned char *)xalloc(nindex);
 | |
|     if ( pfh8->index == (unsigned char *) NULL ) {
 | |
| 	xfree(pfh8->fontname);
 | |
| 	xfree(pfh8);
 | |
| 	return (PclFontHead8Ptr) NULL;
 | |
|     }
 | |
| 
 | |
|     for (i=0; i<=nindex; i++)
 | |
|         pfh8->index[i] = 0x0;
 | |
| 
 | |
|     pfh8->next = (PclFontHead8Ptr)NULL;
 | |
| 
 | |
|     if ( prev == (PclFontHead8Ptr) NULL)
 | |
| 	pSoftFontInfo->phead8 = pfh8;
 | |
|     else
 | |
| 	prev->next = pfh8;
 | |
| 
 | |
|     return pfh8;
 | |
| }
 | |
| 
 | |
| static PclFontHead16Ptr
 | |
| makeFontHeader16(FontPtr pfont, PclSoftFontInfoPtr pSoftFontInfo)
 | |
| {
 | |
| PclFontHead16Ptr phead16 = pSoftFontInfo->phead16;
 | |
| PclFontHead16Ptr pfh16 = phead16;
 | |
| PclFontHead16Ptr prev = (PclFontHead16Ptr)NULL;
 | |
| PclFontMapRec ** index;
 | |
| FontInfoPtr pfi;
 | |
| char *fontname;
 | |
| unsigned char nindex_row, nindex_col;
 | |
| int i, j;
 | |
| unsigned long n;
 | |
| CharInfoPtr charinfo[1];
 | |
| unsigned int space_width;
 | |
| 
 | |
|     if (pSoftFontInfo == (PclSoftFontInfoPtr) NULL)
 | |
| 	return (PclFontHead16Ptr)NULL;
 | |
| 
 | |
|     /*
 | |
|      * Verify it has already been created, if so, return it.
 | |
|      */
 | |
|     if ( (fontname = getFontName(pfont)) == (char *)NULL)
 | |
| 	return (PclFontHead16Ptr)NULL;
 | |
| 
 | |
|     while (pfh16 != (PclFontHead16Ptr) NULL) {
 | |
| 	if (!strcmp(pfh16->fontname, fontname))
 | |
| 	    return pfh16;
 | |
| 	prev = pfh16;
 | |
| 	pfh16 = pfh16->next;
 | |
|     }
 | |
| 
 | |
|     /*
 | |
|      * Create Font Header Information
 | |
|      */
 | |
|     pfh16 = (PclFontHead16Ptr)xalloc(sizeof(PclFontHead16Rec));
 | |
|     if (pfh16 == (PclFontHead16Ptr)NULL)
 | |
| 	return (PclFontHead16Ptr)NULL;
 | |
| 
 | |
|     pfi = (FontInfoRec *)&pfont->info;
 | |
|     GetGlyphs(pfont, 1, (unsigned char *)&pfi->defaultCh,
 | |
| 		(FONTLASTROW(pfont) == 0) ? Linear16Bit : TwoD16Bit,
 | |
| 		&n, charinfo);
 | |
| 
 | |
|     if ( n )
 | |
| 	space_width = charinfo[0]->metrics.characterWidth;
 | |
|     else
 | |
| 	space_width = FONTMAXBOUNDS(pfont,characterWidth);
 | |
| 
 | |
|     fillFontDescData(pfont, &(pfh16->fd), space_width);
 | |
|     pfh16->cur_fid = 0;
 | |
|     pfh16->cur_cindex = 0;
 | |
|     pfh16->fontname = (char *)xalloc(strlen(fontname) + 1);
 | |
|     if (pfh16->fontname == (char *)NULL) {
 | |
| 	xfree(pfh16);
 | |
| 	return (PclFontHead16Ptr) NULL;
 | |
|     }
 | |
|     strcpy(pfh16->fontname, fontname);
 | |
| 
 | |
|     pfi = (FontInfoRec *)&pfont->info;
 | |
|     nindex_col = pfi->lastCol - pfi->firstCol + 1;
 | |
|     nindex_row = pfi->lastRow - pfi->firstRow + 1;
 | |
|     index = (PclFontMapRec **)xalloc(sizeof(PclFontMapRec *)*nindex_row);
 | |
|     if (index == (PclFontMapRec **)NULL) {
 | |
| 	xfree(pfh16->fontname);
 | |
| 	xfree(pfh16);
 | |
| 	return (PclFontHead16Ptr) NULL;
 | |
|     }
 | |
|     for (i=0; i<nindex_row; i++) {
 | |
| 	index[i] = (PclFontMapRec *)xalloc(sizeof(PclFontMapRec)*nindex_col);
 | |
| 	if (index[i] == (PclFontMapRec *)NULL) {
 | |
| 	    for(j=0; j<i; j++)
 | |
| 		xfree(index[j]);
 | |
| 	    xfree(pfh16->fontname);
 | |
| 	    xfree(pfh16);
 | |
| 	    return (PclFontHead16Ptr) NULL;
 | |
| 	}
 | |
|         for (j=0; j<=nindex_col; j++)
 | |
|             index[i][j].fid = 0x0;
 | |
|     }
 | |
| 
 | |
|     pfh16->index = index;
 | |
|     pfh16->firstCol = pfi->firstCol;
 | |
|     pfh16->lastCol = pfi->lastCol;
 | |
|     pfh16->firstRow = pfi->firstRow;
 | |
|     pfh16->lastRow = pfi->lastRow;
 | |
|     pfh16->next = (PclFontHead16Ptr)NULL;
 | |
| 
 | |
|     if ( prev == (PclFontHead16Ptr) NULL)
 | |
| 	pSoftFontInfo->phead16 = pfh16;
 | |
|     else
 | |
| 	prev->next = pfh16;
 | |
| 
 | |
|     return pfh16;
 | |
| }
 | |
| 
 | |
| static PclInternalFontPtr
 | |
| makeInternalFont(FontPtr pfont, PclSoftFontInfoPtr pSoftFontInfo)
 | |
| {
 | |
| PclInternalFontPtr pinfont = pSoftFontInfo->pinfont;
 | |
| PclInternalFontPtr pin = pinfont;
 | |
| PclInternalFontPtr prev = (PclInternalFontPtr)NULL;
 | |
| FontPropPtr props;
 | |
| FontInfoPtr pfi;
 | |
| char *fontname;
 | |
| Atom xa_pcl_font_name, xa_res, xa_ave_width, xa_spacing;
 | |
| int width = 1;
 | |
| int mask;
 | |
| int i;
 | |
| 
 | |
|     if (pSoftFontInfo == (PclSoftFontInfoPtr) NULL)
 | |
| 	return (PclInternalFontPtr)NULL;
 | |
| 
 | |
|     /*
 | |
|      * Verify it has already been created, if so, return it.
 | |
|      */
 | |
|     if ( (fontname = getFontName(pfont)) == (char *)NULL)
 | |
| 	return (PclInternalFontPtr)NULL;
 | |
| 
 | |
|     while (pin != (PclInternalFontPtr) NULL) {
 | |
| 	if (!strcmp(pin->fontname, fontname))
 | |
| 	    return pin;
 | |
| 	prev = pin;
 | |
| 	pin = pin->next;
 | |
|     }
 | |
| 
 | |
|     /*
 | |
|      * Create Internal Font Information
 | |
|      */
 | |
|     pin = (PclInternalFontPtr)xalloc(sizeof(PclInternalFontRec));
 | |
|     if (pin == (PclInternalFontPtr)NULL)
 | |
| 	return (PclInternalFontPtr)NULL;
 | |
| 
 | |
|     pin->fontname = (char *)xalloc(strlen(fontname) + 1);
 | |
|     if (pin->fontname == (char *)NULL) {
 | |
| 	xfree(pin);
 | |
| 	return (PclInternalFontPtr) NULL;
 | |
|     }
 | |
|     strcpy(pin->fontname, fontname);
 | |
| 
 | |
|     xa_pcl_font_name = MakeAtom("PCL_FONT_NAME", strlen("PCL_FONT_NAME"), TRUE);
 | |
|     xa_res = MakeAtom("RESOLUTION_X", strlen("RESOLUTION_X"), TRUE);
 | |
|     xa_ave_width = MakeAtom("AVERAGE_WIDTH", strlen("AVERAGE_WIDTH"), TRUE);
 | |
|     xa_spacing = MakeAtom("SPACING", strlen("SPACING"), TRUE);
 | |
|     pfi = (FontInfoRec *)&pfont->info;
 | |
|     props = pfi->props;
 | |
| 
 | |
|     mask = 0;
 | |
|     for (i=0; i<pfi->nprops; i++, props++) {
 | |
| 	if ( (Atom) props->name == xa_pcl_font_name ) {
 | |
| 	    pin->pcl_font_name = NameForAtom(props->value);
 | |
| 	    mask |= 0x1;
 | |
| 	} else if ( props->name == XA_POINT_SIZE ) {
 | |
| 	    pin->height = (float) props->value / 10.0;
 | |
| 	    mask |= 0x2;
 | |
| 	} else if ( (Atom) props->name == xa_res ) {
 | |
| 	    mask |= 0x4;
 | |
| 	} else if ( (Atom) props->name == xa_ave_width ) {
 | |
| 	    width = (int) props->value / 10;
 | |
| 	    mask |= 0x8;
 | |
| 	} else if ( (Atom) props->name == xa_spacing ) {
 | |
| 	    pin->spacing = NameForAtom(props->value);
 | |
| 	    mask |= 0x10;
 | |
| 	}
 | |
|     }
 | |
|     if ( mask != 0x1f ) {
 | |
| 	xfree(pin->fontname);
 | |
| 	xfree(pin);
 | |
| 	return (PclInternalFontPtr) NULL;
 | |
|     }
 | |
| 
 | |
|     if ( *pin->spacing != 'P' || *pin->spacing != 'p' ) {
 | |
| 	if (width == 0)
 | |
| 	    width = 1;
 | |
| 	pin->pitch = (float) 300.0 / width;  /* Hard-Code: Resolution is 300 */
 | |
|     }
 | |
| 
 | |
|     pin->next = (PclInternalFontPtr)NULL;
 | |
|     if ( prev == (PclInternalFontPtr) NULL)
 | |
| 	pSoftFontInfo->pinfont = pin;
 | |
|     else
 | |
| 	prev->next = pin;
 | |
| 
 | |
|     return pin;
 | |
| }
 | |
| 
 | |
| static void
 | |
| fillFontDescData(FontPtr pfont, PclFontDescPtr pfd, unsigned int space)
 | |
| {
 | |
| FontInfoPtr pfi;
 | |
| 
 | |
|     pfi = (FontInfoRec *)&pfont->info;
 | |
| 
 | |
|     if ( (pfi->maxbounds.leftSideBearing == pfi->minbounds.leftSideBearing)
 | |
| 	&& (pfi->maxbounds.rightSideBearing == pfi->minbounds.rightSideBearing)
 | |
| 	&& (pfi->maxbounds.characterWidth == pfi->minbounds.characterWidth)
 | |
| 	&& (pfi->maxbounds.ascent == pfi->minbounds.ascent)
 | |
| 	&& (pfi->maxbounds.descent == pfi->minbounds.descent)
 | |
|     )
 | |
| 	pfd->spacing = MONOSPACE;
 | |
|     else
 | |
| 	pfd->spacing = PROPSPACE;
 | |
| 
 | |
|     pfd->pitch      = space;
 | |
|     pfd->cellheight = FONTMAXBOUNDS(pfont,ascent)
 | |
| 				+ FONTMAXBOUNDS(pfont,descent);
 | |
|     pfd->cellwidth  = FONTMAXBOUNDS(pfont,rightSideBearing)
 | |
| 				- FONTMINBOUNDS(pfont,leftSideBearing);
 | |
|     pfd->ascent     = FONTMAXBOUNDS(pfont,ascent);   /*FONTASCENT(pfont);*/
 | |
|     pfd->descent    = FONTMAXBOUNDS(pfont,descent); /*FONTDESCENT(pfont);*/
 | |
| }
 | |
| 
 | |
| static PclCharDataPtr
 | |
| fillCharDescData(PclCharDataPtr pcd, CharInfoPtr pci)
 | |
| {
 | |
| unsigned int byte_width;
 | |
| unsigned char *p;
 | |
| register int nbyGlyphWidth;
 | |
| unsigned char *pglyph, *pg;
 | |
| unsigned int i, j;
 | |
| 
 | |
|     pcd->h_offset   = pci->metrics.leftSideBearing;
 | |
|     pcd->v_offset   = pci->metrics.ascent;
 | |
|     pcd->width      = pci->metrics.rightSideBearing
 | |
| 				- pci->metrics.leftSideBearing;
 | |
|     pcd->height     = pci->metrics.ascent + pci->metrics.descent;
 | |
|     pcd->font_pitch = pci->metrics.characterWidth;
 | |
| 
 | |
|     byte_width = (pcd->width + 7)/8;
 | |
|     pcd->raster_top = (unsigned char *)xalloc(byte_width * pcd->height);
 | |
|     if (pcd->raster_top == (unsigned char *)NULL)
 | |
| 	return (PclCharDataPtr)NULL;
 | |
| 
 | |
|     p = pcd->raster_top;
 | |
|     nbyGlyphWidth = GLYPHWIDTHBYTESPADDED(pci);
 | |
|     pglyph = FONTGLYPHBITS(pglyphBase, pci);
 | |
|     for (i=0; i<pcd->height; i++) {
 | |
| 	pg = pglyph + nbyGlyphWidth * i;
 | |
| 	for (j=0; j<byte_width; j++) 
 | |
| 	    *p++ = *pg++;
 | |
|     }
 | |
|     return pcd;
 | |
| }
 | |
| 
 | |
| static void
 | |
| output_text(FILE *outFile,
 | |
| 	PclContextPrivPtr pConPriv,
 | |
| 	unsigned char index)
 | |
| {
 | |
|     if ( index == ETX ) {
 | |
| 	sprintf(t, "%c;DT%c,1;LB%c%c;DT%c,1;LB",
 | |
| 				ETX, ETX_ALT, ETX, ETX_ALT, ETX);
 | |
| 	SAVE_PCL( outFile, pConPriv, t );
 | |
|     } else {
 | |
| 	sprintf(t, "%c", index);
 | |
| 	SAVE_PCL_COUNT( outFile, pConPriv, t, 1 );
 | |
|     }
 | |
| }
 | |
| 
 | |
| static char *
 | |
| getFontName(FontPtr pfont)
 | |
| {
 | |
| int i;
 | |
| FontInfoPtr pfi;
 | |
| FontPropPtr props;
 | |
| char *fontname;
 | |
| 
 | |
|     pfi = (FontInfoRec *)&pfont->info;
 | |
|     props = pfi->props;
 | |
|     fontname = (char *) NULL;
 | |
|     for (i=0; i<pfi->nprops; i++, props++) {
 | |
|         if ( props->name == XA_FONT ) {
 | |
|             fontname = (char *)NameForAtom(props->value);
 | |
|             break;
 | |
|         }
 | |
|     }
 | |
|     return fontname;
 | |
| }
 | |
| 
 | |
| /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 | |
| /* Internal Font Selection                                               */
 | |
| /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 | |
| 
 | |
| static char
 | |
| isInternal(FontPtr pfont)
 | |
| {
 | |
| int i;
 | |
| FontInfoPtr pfi;
 | |
| FontPropPtr props;
 | |
| Atom dest;
 | |
| 
 | |
|     dest = MakeAtom("PRINTER_RESIDENT_FONT", strlen("PRINTER_RESIDENT_FONT"), TRUE);
 | |
| 
 | |
|     pfi = (FontInfoRec *)&pfont->info;
 | |
|     props = pfi->props;
 | |
|     for (i=0; i<pfi->nprops; i++, props++) {
 | |
|         if ( (Atom) props->name == dest && props->value == 2 )
 | |
| 		return INTERNAL_FONT;
 | |
|     }
 | |
|     return DOWNLOAD_FONT;
 | |
| }
 | |
| 
 | |
| static void
 | |
| selectInternalFont(FILE *outFile, PclInternalFontPtr pin, int fid)
 | |
| {
 | |
|     fprintf(outFile, "%c*c%dD", ESC, fid);
 | |
|     if ( *pin->spacing == 'P' || *pin->spacing == 'p' )
 | |
| 	fprintf(outFile, pin->pcl_font_name, pin->height);
 | |
|     else
 | |
| 	fprintf(outFile, pin->pcl_font_name, pin->pitch);
 | |
|     fprintf(outFile, "%c*c6F", ESC);
 | |
| }
 | |
| 
 | |
| static void
 | |
| selectSize(FILE *outFile,
 | |
| 	PclContextPrivPtr pConPriv,
 | |
| 	PclInternalFontPtr pin)
 | |
| {
 | |
|     if ( *pin->spacing == 'P' || *pin->spacing == 'p' ) {
 | |
| 	sprintf(t, "SD4,%f;", pin->height);
 | |
| 	SAVE_PCL( outFile, pConPriv, t );
 | |
|     } else {
 | |
| 	sprintf(t, "SD3,%f;", pin->pitch);
 | |
| 	SAVE_PCL( outFile, pConPriv, t );
 | |
|     }
 | |
|     return;
 | |
| }
 | |
| 
 | |
| #ifdef DO_TWO_BYTE_PCL
 | |
| static void
 | |
| code_conv(
 | |
|     PclSoftFontInfoPtr pSoftFontInfo,
 | |
|     FontPtr pfont,
 | |
|     char *from,
 | |
|     char *to
 | |
| )
 | |
| {
 | |
| iconv_t cd;
 | |
| char frombuf[9], *fromptr;
 | |
| size_t inbyte = 5, outbyte=2;
 | |
| 
 | |
|     fromptr = frombuf;
 | |
|     frombuf[0] = 0x1b; /* Esc */
 | |
|     frombuf[1] = 0x24; /* $ */
 | |
|     frombuf[2] = 0x42; /* B */
 | |
|     frombuf[3] = *from;
 | |
|     frombuf[4] = *(from+1);
 | |
|     frombuf[5] = 0x1b; /* Esc */
 | |
|     frombuf[6] = 0x28; /* ( */
 | |
|     frombuf[7] = 0x4a; /* J */
 | |
|     frombuf[8] = 0x0;
 | |
|     if ((cd = iconv_open("sjis", "jis")) == (iconv_t)(-1)) {
 | |
| 	*to = (unsigned char)NULL;
 | |
| 	return;
 | |
|     }
 | |
| 
 | |
|     if ( iconv(cd, &fromptr, &inbyte, &to, &outbyte) == -1 )
 | |
| 	*to = (unsigned char)NULL;
 | |
| 
 | |
|     iconv_close(cd);
 | |
|     return;
 | |
| }
 | |
| #endif /* DO_TWO_BYTE_PCL */
 |