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