diff options
Diffstat (limited to 'xorg-server/hw/xprint/pcl/PclText.c')
-rw-r--r-- | xorg-server/hw/xprint/pcl/PclText.c | 934 |
1 files changed, 934 insertions, 0 deletions
diff --git a/xorg-server/hw/xprint/pcl/PclText.c b/xorg-server/hw/xprint/pcl/PclText.c new file mode 100644 index 000000000..324de3014 --- /dev/null +++ b/xorg-server/hw/xprint/pcl/PclText.c @@ -0,0 +1,934 @@ +/******************************************************************* +** +** ********************************************************* +** * +** * 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. +*/ + +#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) + dixLookupPrivate(&pCon->devPrivates, PclContextPrivateKey); + 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) + dixLookupPrivate(&pCon->devPrivates, PclContextPrivateKey); + 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 */ |