~ubuntu-branches/ubuntu/intrepid/xserver-xgl/intrepid

« back to all changes in this revision

Viewing changes to Xprint/pcl/PclText.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthew Garrett
  • Date: 2006-02-13 14:21:43 UTC
  • Revision ID: james.westby@ubuntu.com-20060213142143-mad6z9xzem7hzxz9
Tags: upstream-7.0.0
ImportĀ upstreamĀ versionĀ 7.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Xorg: PclText.c,v 1.5 2001/03/06 16:28:48 pookie Exp $ */
 
2
/*******************************************************************
 
3
**
 
4
**    *********************************************************
 
5
**    *
 
6
**    *  File:          PclText.c
 
7
**    *
 
8
**    *  Contents:
 
9
**    *                 Character-drawing routines for the PCL DDX
 
10
**    *
 
11
**    *  Created:       10/23/95
 
12
**    *
 
13
**    *********************************************************
 
14
** 
 
15
********************************************************************/
 
16
/*
 
17
(c) Copyright 1996 Hewlett-Packard Company
 
18
(c) Copyright 1996 International Business Machines Corp.
 
19
(c) Copyright 1996 Sun Microsystems, Inc.
 
20
(c) Copyright 1996 Novell, Inc.
 
21
(c) Copyright 1996 Digital Equipment Corp.
 
22
(c) Copyright 1996 Fujitsu Limited
 
23
(c) Copyright 1996 Hitachi, Ltd.
 
24
 
 
25
Permission is hereby granted, free of charge, to any person obtaining a copy
 
26
of this software and associated documentation files (the "Software"), to deal
 
27
in the Software without restriction, including without limitation the rights
 
28
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 
29
copies of the Software, and to permit persons to whom the Software is
 
30
furnished to do so, subject to the following conditions:
 
31
 
 
32
The above copyright notice and this permission notice shall be included in
 
33
all copies or substantial portions of the Software.
 
34
 
 
35
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
36
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
37
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 
38
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 
39
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 
40
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
41
 
 
42
Except as contained in this notice, the names of the copyright holders shall
 
43
not be used in advertising or otherwise to promote the sale, use or other
 
44
dealings in this Software without prior written authorization from said
 
45
copyright holders.
 
46
*/
 
47
/* $XFree86: xc/programs/Xserver/Xprint/pcl/PclText.c,v 1.10tsi Exp $ */
 
48
 
 
49
#ifdef HAVE_DIX_CONFIG_H
 
50
#include <dix-config.h>
 
51
#endif
 
52
 
 
53
#ifdef DO_TWO_BYTE_PCL
 
54
#include "iconv.h"
 
55
#endif /* DO_TWO_BYTE_PCL */
 
56
#include "gcstruct.h"
 
57
#include "windowstr.h"
 
58
 
 
59
#include "Pcl.h"
 
60
#include "migc.h"
 
61
#include <X11/Xatom.h>
 
62
 
 
63
#include "PclSFonts.h"
 
64
 
 
65
static PclFontHead8Ptr  makeFontHeader8 (FontPtr, PclSoftFontInfoPtr);
 
66
static PclFontHead16Ptr makeFontHeader16(FontPtr, PclSoftFontInfoPtr);
 
67
static PclInternalFontPtr makeInternalFont(FontPtr, PclSoftFontInfoPtr);
 
68
static void             fillFontDescData(FontPtr, PclFontDescPtr, unsigned int);
 
69
static PclCharDataPtr   fillCharDescData(PclCharDataPtr, CharInfoPtr);
 
70
static void             output_text(FILE *, PclContextPrivPtr, unsigned char);
 
71
static char *           getFontName(FontPtr);
 
72
static char             isInternal(FontPtr);
 
73
static void             selectInternalFont(FILE *, PclInternalFontPtr, int);
 
74
static void             selectSize(FILE *, PclContextPrivPtr, PclInternalFontPtr);
 
75
static char t[80];
 
76
 
 
77
#ifdef DO_TWO_BYTE_PCL
 
78
static void             code_conv(PclSoftFontInfoPtr, FontPtr, char *, char *);
 
79
#endif /* DO_TWO_BYTE_PCL */
 
80
 
 
81
#define ESC 0x1b
 
82
#define PER 0x25
 
83
#define ETX 0x3
 
84
#define ETX_ALT 0x2a
 
85
#define DOWNLOAD_FONT 0
 
86
#define INTERNAL_FONT 1
 
87
 
 
88
int
 
89
PclPolyText8(
 
90
     DrawablePtr pDrawable,
 
91
     GCPtr pGC,
 
92
     int x,
 
93
     int y,
 
94
     int count,
 
95
     char *string)
 
96
{
 
97
XpContextPtr pCon;
 
98
PclContextPrivPtr pConPriv;
 
99
unsigned long n, i;
 
100
int w;
 
101
CharInfoPtr charinfo[255], *chinfo;
 
102
 
 
103
FILE *outFile;
 
104
PclSoftFontInfoPtr pSoftFontInfo;
 
105
PclFontHead8Ptr pfh8 = (PclFontHead8Ptr)NULL;
 
106
PclInternalFontPtr pin = (PclInternalFontPtr)NULL;
 
107
PclCharDataRec cd;
 
108
unsigned char *p;
 
109
unsigned char last_fid;
 
110
int max_ascent, max_descent;
 
111
 
 
112
int nbox;
 
113
BoxPtr pbox;
 
114
BoxRec box;
 
115
RegionPtr drawRegion, region;
 
116
char font_type;
 
117
 
 
118
    if( PclUpdateDrawableGC( pGC, pDrawable, &outFile ) == FALSE )
 
119
        return x;
 
120
 
 
121
    GetGlyphs(pGC->font, (unsigned long)count, (unsigned char *)string,
 
122
                                                Linear8Bit, &n, charinfo);
 
123
    if ( n == 0 )
 
124
        return x;
 
125
 
 
126
    pCon = PclGetContextFromWindow( (WindowPtr)pDrawable );
 
127
    pConPriv = (PclContextPrivPtr)
 
128
                        pCon->devPrivates[PclContextPrivateIndex].ptr;
 
129
    pSoftFontInfo = pConPriv->pSoftFontInfo;
 
130
    font_type = isInternal(pGC->font);
 
131
    if ( font_type == DOWNLOAD_FONT ) {
 
132
        /*
 
133
         * Create Soft Font Header Information
 
134
         */
 
135
        pfh8 = makeFontHeader8(pGC->font, pSoftFontInfo);
 
136
        if (!pfh8)
 
137
            return x;
 
138
 
 
139
        /*
 
140
         * exec Soft Font Downloading
 
141
         */
 
142
        p = (unsigned char *)string;
 
143
        for (i=0, chinfo=charinfo; i<n; i++, p++, chinfo++) {
 
144
            if ( !pfh8->index[*p] ) {
 
145
                fillCharDescData(&cd, *chinfo);
 
146
                PclDownloadSoftFont8(pConPriv->pJobFile, pSoftFontInfo,
 
147
                                        pfh8, &cd, p);
 
148
                xfree(cd.raster_top);
 
149
            }
 
150
        }
 
151
 
 
152
        /*
 
153
         * print characters
 
154
         */
 
155
        MACRO_START( outFile, pConPriv );
 
156
        sprintf(t, "\033%%0B;PU%d,%dPD;TD1;DT%c,1;",
 
157
                x + pDrawable->x, y + pDrawable->y + pGC->font->info.fontAscent,
 
158
                ETX);
 
159
        SAVE_PCL( outFile, pConPriv, t );
 
160
        SAVE_PCL_COUNT( outFile, pConPriv, "FI0;SS;LB", 9 );
 
161
 
 
162
        last_fid = 0;
 
163
        w = 0;
 
164
        max_ascent = charinfo[0]->metrics.ascent;
 
165
        max_descent = charinfo[0]->metrics.descent;
 
166
        p = (unsigned char *)string;
 
167
        for (i=0, chinfo=charinfo; i<n; i++, p++, chinfo++) {
 
168
            if  ( last_fid != pfh8->fid ) {
 
169
                sprintf(t, "%c;FI%d;SS;LB", ETX, pfh8->fid);
 
170
                SAVE_PCL( outFile, pConPriv, t );
 
171
 
 
172
                last_fid = pfh8->fid;
 
173
            }
 
174
 
 
175
            output_text(outFile, pConPriv, pfh8->index[*p]);
 
176
 
 
177
            w += (*chinfo)->metrics.characterWidth;
 
178
            max_ascent = MAX(max_ascent, (*chinfo)->metrics.ascent);
 
179
            max_descent = MAX(max_descent, (*chinfo)->metrics.descent);
 
180
        }
 
181
 
 
182
        sprintf(t, "%c", ETX);
 
183
        SAVE_PCL_COUNT( outFile, pConPriv, t, 1 );
 
184
        sprintf(t, "TD0;\033%%1A");
 
185
        SAVE_PCL( outFile, pConPriv, t );
 
186
        MACRO_END( outFile );
 
187
 
 
188
    } else {
 
189
        int fid = 0;
 
190
 
 
191
        pin = makeInternalFont(pGC->font, pSoftFontInfo);
 
192
        if (!pin)
 
193
            return x;
 
194
 
 
195
        selectInternalFont(outFile, pin, fid);
 
196
 
 
197
        /*
 
198
         * print characters
 
199
         */
 
200
        MACRO_START( outFile, pConPriv );
 
201
        sprintf(t, "\033%%0B;PU%d,%dPD;TD1;DT%c,1;",
 
202
                x + pDrawable->x, y + pDrawable->y + pGC->font->info.fontAscent,
 
203
                ETX);
 
204
        SAVE_PCL( outFile, pConPriv, t );
 
205
        selectSize(outFile, pConPriv, pin);
 
206
        SAVE_PCL_COUNT( outFile, pConPriv, "FI0;SS;LB", 9 );
 
207
 
 
208
        w = 0;
 
209
        max_ascent = charinfo[0]->metrics.ascent;
 
210
        max_descent = charinfo[0]->metrics.descent;
 
211
        p = (unsigned char *)string;
 
212
        for (i=0, chinfo=charinfo; i<n; i++, p++, chinfo++) {
 
213
            output_text(outFile, pConPriv, *p);
 
214
 
 
215
            w += (*chinfo)->metrics.characterWidth;
 
216
            max_ascent = MAX(max_ascent, (*chinfo)->metrics.ascent);
 
217
            max_descent = MAX(max_descent, (*chinfo)->metrics.descent);
 
218
        }
 
219
        sprintf(t, "%c", ETX);
 
220
        SAVE_PCL_COUNT( outFile, pConPriv, t, 1 );
 
221
        sprintf(t, "TD0;\033%%1A");
 
222
        SAVE_PCL( outFile, pConPriv, t );
 
223
        MACRO_END( outFile );
 
224
    }
 
225
 
 
226
    /*
 
227
     * Convert the collection of rectangles into a proper region, then
 
228
     * intersect it with the clip region.
 
229
     */
 
230
    box.x1 = x +  pDrawable->x;
 
231
    box.y1 = y - max_ascent + pDrawable->y + pGC->font->info.fontAscent;
 
232
    box.x2 = x + w + pDrawable->x;
 
233
    box.y2 = y + max_descent + pDrawable->y + pGC->font->info.fontAscent;
 
234
 
 
235
    drawRegion = miRegionCreate( &box, 0 );
 
236
    region = miRegionCreate( NULL, 0 );
 
237
    miIntersect( region, drawRegion, pGC->pCompositeClip );
 
238
 
 
239
    /*
 
240
     * For each rectangle in the clip region, set the HP-GL/2 "input
 
241
     * window" and render the entire polyline to it.
 
242
     */
 
243
    pbox = REGION_RECTS( region );
 
244
    nbox = REGION_NUM_RECTS( region );
 
245
 
 
246
    PclSendData(outFile, pConPriv, pbox, nbox, 1.0);
 
247
 
 
248
    /*
 
249
     * Clean up the temporary regions
 
250
     */
 
251
    REGION_DESTROY( pGC->pScreen, drawRegion );
 
252
    REGION_DESTROY( pGC->pScreen, region );
 
253
 
 
254
    return x+w;
 
255
}
 
256
 
 
257
int
 
258
PclPolyText16(
 
259
     DrawablePtr pDrawable,
 
260
     GCPtr pGC,
 
261
     int x,
 
262
     int y,
 
263
     int count,
 
264
     unsigned short *string)
 
265
{
 
266
XpContextPtr pCon;
 
267
PclContextPrivPtr pConPriv;
 
268
unsigned long n, i;
 
269
int w;
 
270
CharInfoPtr charinfo[255], *chinfo;
 
271
 
 
272
FILE *outFile;
 
273
PclSoftFontInfoPtr pSoftFontInfo;
 
274
PclFontHead16Ptr pfh16 = (PclFontHead16Ptr)NULL;
 
275
PclCharDataRec cd;
 
276
FontInfoPtr pfi;
 
277
unsigned char row, col;
 
278
char *p;
 
279
unsigned char last_fid;
 
280
int max_ascent, max_descent;
 
281
unsigned short def;
 
282
 
 
283
int nbox;
 
284
BoxPtr pbox;
 
285
BoxRec box;
 
286
RegionPtr drawRegion, region;
 
287
char font_type;
 
288
 
 
289
    if( PclUpdateDrawableGC( pGC, pDrawable, &outFile ) == FALSE )
 
290
        return x;
 
291
 
 
292
    GetGlyphs(pGC->font, (unsigned long)count, (unsigned char *)string,
 
293
                (FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit,
 
294
                &n, charinfo);
 
295
 
 
296
    pCon = PclGetContextFromWindow( (WindowPtr)pDrawable );
 
297
    pConPriv = (PclContextPrivPtr)
 
298
                        pCon->devPrivates[PclContextPrivateIndex].ptr;
 
299
    pSoftFontInfo = pConPriv->pSoftFontInfo;
 
300
 
 
301
    font_type = isInternal(pGC->font);
 
302
    if ( font_type == DOWNLOAD_FONT ) {
 
303
        /*
 
304
         * Create Soft Font Header Information
 
305
         */
 
306
        pfh16 = makeFontHeader16(pGC->font, pSoftFontInfo);
 
307
        if (!pfh16)
 
308
            return x;
 
309
 
 
310
        /*
 
311
         * exec Soft Font Downloading
 
312
         */
 
313
        pfi = (FontInfoRec *)&pGC->font->info;
 
314
        p = (char *)string;
 
315
        for (i=0, p=(char *)string, chinfo=charinfo; i<n; i++, p+=2, chinfo++) {
 
316
            row = *p & 0xff;
 
317
            col = *(p+1) & 0xff;
 
318
            if ( (pfi->firstRow <= row) && (row <= pfi->lastRow)
 
319
                && (pfi->firstCol <= col) && (col <= pfi->lastCol) ) {
 
320
                row = row - pfi->firstRow;
 
321
                col = col - pfi->firstCol;
 
322
            } else {
 
323
                def = pfi->defaultCh;
 
324
                row = ((def>>8)&0xff) - pfi->firstRow;
 
325
                col = (def&0xff) - pfi->firstCol;
 
326
            }
 
327
            if ( !pfh16->index[row][col].fid ) {
 
328
                fillCharDescData(&cd, *chinfo);
 
329
                PclDownloadSoftFont16(pConPriv->pJobFile, pSoftFontInfo,
 
330
                                pfh16, &cd, row, col);
 
331
                xfree(cd.raster_top);
 
332
            }
 
333
        }
 
334
 
 
335
        /*
 
336
         * print characters
 
337
         */
 
338
        MACRO_START( outFile, pConPriv );
 
339
        sprintf(t, "\033%%0B;PU%d,%dPD;TD1;DT%c,1;",
 
340
                x + pDrawable->x, y + pDrawable->y + pGC->font->info.fontAscent,
 
341
                ETX);
 
342
        SAVE_PCL( outFile, pConPriv, t );
 
343
        SAVE_PCL_COUNT( outFile, pConPriv, "FI0;SS;LB", 9 );
 
344
 
 
345
        last_fid = 0;
 
346
 
 
347
        w = 0;
 
348
        max_ascent = charinfo[0]->metrics.ascent;
 
349
        max_descent = charinfo[0]->metrics.descent;
 
350
        for (i=0, p=(char *)string, chinfo=charinfo; i<n; i++, p+=2, chinfo++) {
 
351
            row = *p & 0xff;
 
352
            col = *(p+1) & 0xff;
 
353
            if ( (pfi->firstRow <= row) && (row <= pfi->lastRow)
 
354
                && (pfi->firstCol <= col) && (col <= pfi->lastCol) ) {
 
355
                row = row - pfi->firstRow;
 
356
                col = col - pfi->firstCol;
 
357
            } else {
 
358
                def = pfi->defaultCh;
 
359
                row = ((def>>8)&0xff) - pfi->firstRow;
 
360
                col = (def&0xff) - pfi->firstCol;
 
361
            }
 
362
            if ( last_fid != pfh16->index[row][col].fid ) {
 
363
                sprintf(t, "%cFI%d;SS;LB",
 
364
                                ETX, pfh16->index[row][col].fid);
 
365
                SAVE_PCL( outFile, pConPriv, t );
 
366
                last_fid = pfh16->index[row][col].fid;
 
367
            }
 
368
 
 
369
            output_text(outFile, pConPriv, pfh16->index[row][col].cindex);
 
370
 
 
371
            w += (*chinfo)->metrics.characterWidth;
 
372
            max_ascent = MAX(max_ascent, (*chinfo)->metrics.ascent);
 
373
            max_descent = MAX(max_descent, (*chinfo)->metrics.descent);
 
374
        }
 
375
        sprintf(t, "%c", ETX);
 
376
        SAVE_PCL_COUNT( outFile, pConPriv, t, 1 );
 
377
        sprintf(t, "TD0;\033%%1A");
 
378
        SAVE_PCL( outFile, pConPriv, t );
 
379
        MACRO_END( outFile );
 
380
 
 
381
    } else {
 
382
#ifdef DO_TWO_BYTE_PCL
 
383
        PclInternalFontPtr pin;
 
384
        int fid = 0;
 
385
 
 
386
        pin = makeInternalFont(pGC->font, pSoftFontInfo);
 
387
        if (!pin)
 
388
            return x;
 
389
 
 
390
        selectInternalFont(outFile, pin, fid);
 
391
        fprintf(outFile, "%c&t31P", ESC);
 
392
 
 
393
        /*
 
394
         * print characters
 
395
         */
 
396
        MACRO_START( outFile, pConPriv );
 
397
        sprintf(t, "\033%%0B;PU%d,%dPD;TD1;DT%c,1;",
 
398
                x + pDrawable->x, y + pDrawable->y + pGC->font->info.fontAscent,
 
399
                ETX);
 
400
        SAVE_PCL( outFile, pConPriv, t );
 
401
        sprintf(t, "TD0;\033%%1A");
 
402
        SAVE_PCL( outFile, pConPriv, t );
 
403
 
 
404
        w = 0;
 
405
        last_fid = 0;
 
406
        max_ascent = charinfo[0]->metrics.ascent;
 
407
        max_descent = charinfo[0]->metrics.descent;
 
408
        for (i=0, p=(char *)string, chinfo=charinfo; i<n; i++, p+=2, chinfo++) {
 
409
            char tobuf[3];
 
410
            code_conv(pSoftFontInfo, pGC->font, (char *)p, tobuf);
 
411
            fprintf(outFile, "%c%c", tobuf[0], tobuf[1]);
 
412
 
 
413
            w += (*chinfo)->metrics.characterWidth;
 
414
            max_ascent = MAX(max_ascent, (*chinfo)->metrics.ascent);
 
415
            max_descent = MAX(max_descent, (*chinfo)->metrics.descent);
 
416
        }
 
417
        MACRO_END( outFile );
 
418
#else
 
419
        return x;
 
420
#endif /* DO_TWO_BYTE_PCL */
 
421
    }
 
422
 
 
423
    /*
 
424
     * Convert the collection of rectangles into a proper region, then
 
425
     * intersect it with the clip region.
 
426
     */
 
427
    box.x1 = x + pDrawable->x;
 
428
    box.y1 = y - max_ascent + pDrawable->y + pGC->font->info.fontAscent;
 
429
    box.x2 = x + w + pDrawable->x;
 
430
    box.y2 = y + max_descent + pDrawable->y + pGC->font->info.fontAscent;
 
431
 
 
432
    drawRegion = miRegionCreate( &box, 0 );
 
433
    region = miRegionCreate( NULL, 0 );
 
434
    miIntersect( region, drawRegion, pGC->pCompositeClip );
 
435
 
 
436
    /*
 
437
     * For each rectangle in the clip region, set the HP-GL/2 "input
 
438
     * window" and render the entire polyline to it.
 
439
     */
 
440
    pbox = REGION_RECTS( region );
 
441
    nbox = REGION_NUM_RECTS( region );
 
442
 
 
443
    PclSendData(outFile, pConPriv, pbox, nbox, 1.0);
 
444
 
 
445
    /*
 
446
     * Clean up the temporary regions
 
447
     */
 
448
    REGION_DESTROY( pGC->pScreen, drawRegion );
 
449
    REGION_DESTROY( pGC->pScreen, region );
 
450
 
 
451
    return x+w;
 
452
}
 
453
 
 
454
void
 
455
PclImageText8(
 
456
     DrawablePtr pDrawable,
 
457
     GCPtr pGC, 
 
458
     int x, int y,
 
459
     int count,
 
460
     char *string)
 
461
{
 
462
}
 
463
 
 
464
void
 
465
PclImageText16(
 
466
     DrawablePtr pDrawable,
 
467
     GCPtr pGC,
 
468
     int x,
 
469
     int y,
 
470
     int count,
 
471
     unsigned short *string)
 
472
{
 
473
}
 
474
 
 
475
void
 
476
PclImageGlyphBlt(
 
477
     DrawablePtr pDrawable,
 
478
     GCPtr pGC,
 
479
     int x, int y,
 
480
     unsigned int nGlyphs,
 
481
     CharInfoPtr *pCharInfo,
 
482
     pointer pGlyphBase)
 
483
{
 
484
}
 
485
 
 
486
void
 
487
PclPolyGlyphBlt(
 
488
     DrawablePtr pDrawable,
 
489
     GCPtr pGC,
 
490
     int x, int y,
 
491
     unsigned int nGlyphs,
 
492
     CharInfoPtr *pCharInfo,
 
493
     pointer pGlyphBase)
 
494
{
 
495
}
 
496
 
 
497
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
498
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
499
 
 
500
static PclFontHead8Ptr
 
501
makeFontHeader8(FontPtr pfont, PclSoftFontInfoPtr pSoftFontInfo)
 
502
{
 
503
PclFontHead8Ptr phead8 = pSoftFontInfo->phead8;
 
504
PclFontHead8Ptr pfh8 = phead8;
 
505
PclFontHead8Ptr prev = (PclFontHead8Ptr)NULL;
 
506
FontInfoPtr pfi;
 
507
char *fontname;
 
508
unsigned char nindex;
 
509
int i;
 
510
unsigned long n;
 
511
CharInfoPtr charinfo[1];
 
512
unsigned int space_width;
 
513
 
 
514
    if (pSoftFontInfo == (PclSoftFontInfoPtr) NULL)
 
515
        return (PclFontHead8Ptr)NULL;
 
516
 
 
517
    /*
 
518
     * Verify it has already been created, if so, return it.
 
519
     */
 
520
    if ( (fontname = getFontName(pfont)) == (char *)NULL)
 
521
        return (PclFontHead8Ptr)NULL;
 
522
 
 
523
    while (pfh8 != (PclFontHead8Ptr) NULL) {
 
524
        if (!strcmp(pfh8->fontname, fontname))
 
525
            return pfh8;
 
526
        prev = pfh8;
 
527
        pfh8 = pfh8->next;
 
528
    }
 
529
 
 
530
    /*
 
531
     * Create Font Header Information
 
532
     */
 
533
    pfh8 = (PclFontHead8Ptr)xalloc(sizeof(PclFontHead8Rec));
 
534
    if (pfh8 == (PclFontHead8Ptr)NULL)
 
535
        return (PclFontHead8Ptr)NULL;
 
536
 
 
537
    pfi = (FontInfoRec *)&pfont->info;
 
538
    GetGlyphs(pfont, 1, (unsigned char *)&pfi->defaultCh,
 
539
                                                Linear8Bit, &n, charinfo);
 
540
    if ( n )
 
541
        space_width = charinfo[0]->metrics.characterWidth;
 
542
    else
 
543
        space_width = FONTMAXBOUNDS(pfont,characterWidth);
 
544
 
 
545
    fillFontDescData(pfont, &(pfh8->fd), space_width);
 
546
    pfh8->fid = 0;
 
547
    pfh8->fontname = (char *)xalloc(strlen(fontname) + 1);
 
548
    if (pfh8->fontname == (char *)NULL) {
 
549
        xfree(pfh8);
 
550
        return (PclFontHead8Ptr) NULL;
 
551
    }
 
552
    strcpy(pfh8->fontname, fontname);
 
553
 
 
554
    nindex = 0xff;
 
555
    pfh8->index = (unsigned char *)xalloc(nindex);
 
556
    if ( pfh8->index == (unsigned char *) NULL ) {
 
557
        xfree(pfh8->fontname);
 
558
        xfree(pfh8);
 
559
        return (PclFontHead8Ptr) NULL;
 
560
    }
 
561
 
 
562
    for (i=0; i<=nindex; i++)
 
563
        pfh8->index[i] = 0x0;
 
564
 
 
565
    pfh8->next = (PclFontHead8Ptr)NULL;
 
566
 
 
567
    if ( prev == (PclFontHead8Ptr) NULL)
 
568
        pSoftFontInfo->phead8 = pfh8;
 
569
    else
 
570
        prev->next = pfh8;
 
571
 
 
572
    return pfh8;
 
573
}
 
574
 
 
575
static PclFontHead16Ptr
 
576
makeFontHeader16(FontPtr pfont, PclSoftFontInfoPtr pSoftFontInfo)
 
577
{
 
578
PclFontHead16Ptr phead16 = pSoftFontInfo->phead16;
 
579
PclFontHead16Ptr pfh16 = phead16;
 
580
PclFontHead16Ptr prev = (PclFontHead16Ptr)NULL;
 
581
PclFontMapRec ** index;
 
582
FontInfoPtr pfi;
 
583
char *fontname;
 
584
unsigned char nindex_row, nindex_col;
 
585
int i, j;
 
586
unsigned long n;
 
587
CharInfoPtr charinfo[1];
 
588
unsigned int space_width;
 
589
 
 
590
    if (pSoftFontInfo == (PclSoftFontInfoPtr) NULL)
 
591
        return (PclFontHead16Ptr)NULL;
 
592
 
 
593
    /*
 
594
     * Verify it has already been created, if so, return it.
 
595
     */
 
596
    if ( (fontname = getFontName(pfont)) == (char *)NULL)
 
597
        return (PclFontHead16Ptr)NULL;
 
598
 
 
599
    while (pfh16 != (PclFontHead16Ptr) NULL) {
 
600
        if (!strcmp(pfh16->fontname, fontname))
 
601
            return pfh16;
 
602
        prev = pfh16;
 
603
        pfh16 = pfh16->next;
 
604
    }
 
605
 
 
606
    /*
 
607
     * Create Font Header Information
 
608
     */
 
609
    pfh16 = (PclFontHead16Ptr)xalloc(sizeof(PclFontHead16Rec));
 
610
    if (pfh16 == (PclFontHead16Ptr)NULL)
 
611
        return (PclFontHead16Ptr)NULL;
 
612
 
 
613
    pfi = (FontInfoRec *)&pfont->info;
 
614
    GetGlyphs(pfont, 1, (unsigned char *)&pfi->defaultCh,
 
615
                (FONTLASTROW(pfont) == 0) ? Linear16Bit : TwoD16Bit,
 
616
                &n, charinfo);
 
617
 
 
618
    if ( n )
 
619
        space_width = charinfo[0]->metrics.characterWidth;
 
620
    else
 
621
        space_width = FONTMAXBOUNDS(pfont,characterWidth);
 
622
 
 
623
    fillFontDescData(pfont, &(pfh16->fd), space_width);
 
624
    pfh16->cur_fid = 0;
 
625
    pfh16->cur_cindex = 0;
 
626
    pfh16->fontname = (char *)xalloc(strlen(fontname) + 1);
 
627
    if (pfh16->fontname == (char *)NULL) {
 
628
        xfree(pfh16);
 
629
        return (PclFontHead16Ptr) NULL;
 
630
    }
 
631
    strcpy(pfh16->fontname, fontname);
 
632
 
 
633
    pfi = (FontInfoRec *)&pfont->info;
 
634
    nindex_col = pfi->lastCol - pfi->firstCol + 1;
 
635
    nindex_row = pfi->lastRow - pfi->firstRow + 1;
 
636
    index = (PclFontMapRec **)xalloc(sizeof(PclFontMapRec *)*nindex_row);
 
637
    if (index == (PclFontMapRec **)NULL) {
 
638
        xfree(pfh16->fontname);
 
639
        xfree(pfh16);
 
640
        return (PclFontHead16Ptr) NULL;
 
641
    }
 
642
    for (i=0; i<nindex_row; i++) {
 
643
        index[i] = (PclFontMapRec *)xalloc(sizeof(PclFontMapRec)*nindex_col);
 
644
        if (index[i] == (PclFontMapRec *)NULL) {
 
645
            for(j=0; j<i; j++)
 
646
                xfree(index[j]);
 
647
            xfree(pfh16->fontname);
 
648
            xfree(pfh16);
 
649
            return (PclFontHead16Ptr) NULL;
 
650
        }
 
651
        for (j=0; j<=nindex_col; j++)
 
652
            index[i][j].fid = 0x0;
 
653
    }
 
654
 
 
655
    pfh16->index = index;
 
656
    pfh16->firstCol = pfi->firstCol;
 
657
    pfh16->lastCol = pfi->lastCol;
 
658
    pfh16->firstRow = pfi->firstRow;
 
659
    pfh16->lastRow = pfi->lastRow;
 
660
    pfh16->next = (PclFontHead16Ptr)NULL;
 
661
 
 
662
    if ( prev == (PclFontHead16Ptr) NULL)
 
663
        pSoftFontInfo->phead16 = pfh16;
 
664
    else
 
665
        prev->next = pfh16;
 
666
 
 
667
    return pfh16;
 
668
}
 
669
 
 
670
static PclInternalFontPtr
 
671
makeInternalFont(FontPtr pfont, PclSoftFontInfoPtr pSoftFontInfo)
 
672
{
 
673
PclInternalFontPtr pinfont = pSoftFontInfo->pinfont;
 
674
PclInternalFontPtr pin = pinfont;
 
675
PclInternalFontPtr prev = (PclInternalFontPtr)NULL;
 
676
FontPropPtr props;
 
677
FontInfoPtr pfi;
 
678
char *fontname;
 
679
Atom xa_pcl_font_name, xa_res, xa_ave_width, xa_spacing;
 
680
int width = 1;
 
681
int mask;
 
682
int i;
 
683
 
 
684
    if (pSoftFontInfo == (PclSoftFontInfoPtr) NULL)
 
685
        return (PclInternalFontPtr)NULL;
 
686
 
 
687
    /*
 
688
     * Verify it has already been created, if so, return it.
 
689
     */
 
690
    if ( (fontname = getFontName(pfont)) == (char *)NULL)
 
691
        return (PclInternalFontPtr)NULL;
 
692
 
 
693
    while (pin != (PclInternalFontPtr) NULL) {
 
694
        if (!strcmp(pin->fontname, fontname))
 
695
            return pin;
 
696
        prev = pin;
 
697
        pin = pin->next;
 
698
    }
 
699
 
 
700
    /*
 
701
     * Create Internal Font Information
 
702
     */
 
703
    pin = (PclInternalFontPtr)xalloc(sizeof(PclInternalFontRec));
 
704
    if (pin == (PclInternalFontPtr)NULL)
 
705
        return (PclInternalFontPtr)NULL;
 
706
 
 
707
    pin->fontname = (char *)xalloc(strlen(fontname) + 1);
 
708
    if (pin->fontname == (char *)NULL) {
 
709
        xfree(pin);
 
710
        return (PclInternalFontPtr) NULL;
 
711
    }
 
712
    strcpy(pin->fontname, fontname);
 
713
 
 
714
    xa_pcl_font_name = MakeAtom("PCL_FONT_NAME", strlen("PCL_FONT_NAME"), TRUE);
 
715
    xa_res = MakeAtom("RESOLUTION_X", strlen("RESOLUTION_X"), TRUE);
 
716
    xa_ave_width = MakeAtom("AVERAGE_WIDTH", strlen("AVERAGE_WIDTH"), TRUE);
 
717
    xa_spacing = MakeAtom("SPACING", strlen("SPACING"), TRUE);
 
718
    pfi = (FontInfoRec *)&pfont->info;
 
719
    props = pfi->props;
 
720
 
 
721
    mask = 0;
 
722
    for (i=0; i<pfi->nprops; i++, props++) {
 
723
        if ( (Atom) props->name == xa_pcl_font_name ) {
 
724
            pin->pcl_font_name = NameForAtom(props->value);
 
725
            mask |= 0x1;
 
726
        } else if ( props->name == XA_POINT_SIZE ) {
 
727
            pin->height = (float) props->value / 10.0;
 
728
            mask |= 0x2;
 
729
        } else if ( (Atom) props->name == xa_res ) {
 
730
            mask |= 0x4;
 
731
        } else if ( (Atom) props->name == xa_ave_width ) {
 
732
            width = (int) props->value / 10;
 
733
            mask |= 0x8;
 
734
        } else if ( (Atom) props->name == xa_spacing ) {
 
735
            pin->spacing = NameForAtom(props->value);
 
736
            mask |= 0x10;
 
737
        }
 
738
    }
 
739
    if ( mask != 0x1f ) {
 
740
        xfree(pin->fontname);
 
741
        xfree(pin);
 
742
        return (PclInternalFontPtr) NULL;
 
743
    }
 
744
 
 
745
    if ( *pin->spacing != 'P' || *pin->spacing != 'p' ) {
 
746
        if (width == 0)
 
747
            width = 1;
 
748
        pin->pitch = (float) 300.0 / width;  /* Hard-Code: Resolution is 300 */
 
749
    }
 
750
 
 
751
    pin->next = (PclInternalFontPtr)NULL;
 
752
    if ( prev == (PclInternalFontPtr) NULL)
 
753
        pSoftFontInfo->pinfont = pin;
 
754
    else
 
755
        prev->next = pin;
 
756
 
 
757
    return pin;
 
758
}
 
759
 
 
760
static void
 
761
fillFontDescData(FontPtr pfont, PclFontDescPtr pfd, unsigned int space)
 
762
{
 
763
FontInfoPtr pfi;
 
764
 
 
765
    pfi = (FontInfoRec *)&pfont->info;
 
766
 
 
767
    if ( (pfi->maxbounds.leftSideBearing == pfi->minbounds.leftSideBearing)
 
768
        && (pfi->maxbounds.rightSideBearing == pfi->minbounds.rightSideBearing)
 
769
        && (pfi->maxbounds.characterWidth == pfi->minbounds.characterWidth)
 
770
        && (pfi->maxbounds.ascent == pfi->minbounds.ascent)
 
771
        && (pfi->maxbounds.descent == pfi->minbounds.descent)
 
772
    )
 
773
        pfd->spacing = MONOSPACE;
 
774
    else
 
775
        pfd->spacing = PROPSPACE;
 
776
 
 
777
    pfd->pitch      = space;
 
778
    pfd->cellheight = FONTMAXBOUNDS(pfont,ascent)
 
779
                                + FONTMAXBOUNDS(pfont,descent);
 
780
    pfd->cellwidth  = FONTMAXBOUNDS(pfont,rightSideBearing)
 
781
                                - FONTMINBOUNDS(pfont,leftSideBearing);
 
782
    pfd->ascent     = FONTMAXBOUNDS(pfont,ascent);   /*FONTASCENT(pfont);*/
 
783
    pfd->descent    = FONTMAXBOUNDS(pfont,descent); /*FONTDESCENT(pfont);*/
 
784
}
 
785
 
 
786
static PclCharDataPtr
 
787
fillCharDescData(PclCharDataPtr pcd, CharInfoPtr pci)
 
788
{
 
789
unsigned int byte_width;
 
790
unsigned char *p;
 
791
register int nbyGlyphWidth;
 
792
unsigned char *pglyph, *pg;
 
793
unsigned int i, j;
 
794
 
 
795
    pcd->h_offset   = pci->metrics.leftSideBearing;
 
796
    pcd->v_offset   = pci->metrics.ascent;
 
797
    pcd->width      = pci->metrics.rightSideBearing
 
798
                                - pci->metrics.leftSideBearing;
 
799
    pcd->height     = pci->metrics.ascent + pci->metrics.descent;
 
800
    pcd->font_pitch = pci->metrics.characterWidth;
 
801
 
 
802
    byte_width = (pcd->width + 7)/8;
 
803
    pcd->raster_top = (unsigned char *)xalloc(byte_width * pcd->height);
 
804
    if (pcd->raster_top == (unsigned char *)NULL)
 
805
        return (PclCharDataPtr)NULL;
 
806
 
 
807
    p = pcd->raster_top;
 
808
    nbyGlyphWidth = GLYPHWIDTHBYTESPADDED(pci);
 
809
    pglyph = FONTGLYPHBITS(pglyphBase, pci);
 
810
    for (i=0; i<pcd->height; i++) {
 
811
        pg = pglyph + nbyGlyphWidth * i;
 
812
        for (j=0; j<byte_width; j++) 
 
813
            *p++ = *pg++;
 
814
    }
 
815
    return pcd;
 
816
}
 
817
 
 
818
static void
 
819
output_text(FILE *outFile,
 
820
        PclContextPrivPtr pConPriv,
 
821
        unsigned char index)
 
822
{
 
823
    if ( index == ETX ) {
 
824
        sprintf(t, "%c;DT%c,1;LB%c%c;DT%c,1;LB",
 
825
                                ETX, ETX_ALT, ETX, ETX_ALT, ETX);
 
826
        SAVE_PCL( outFile, pConPriv, t );
 
827
    } else {
 
828
        sprintf(t, "%c", index);
 
829
        SAVE_PCL_COUNT( outFile, pConPriv, t, 1 );
 
830
    }
 
831
}
 
832
 
 
833
static char *
 
834
getFontName(FontPtr pfont)
 
835
{
 
836
int i;
 
837
FontInfoPtr pfi;
 
838
FontPropPtr props;
 
839
char *fontname;
 
840
 
 
841
    pfi = (FontInfoRec *)&pfont->info;
 
842
    props = pfi->props;
 
843
    fontname = (char *) NULL;
 
844
    for (i=0; i<pfi->nprops; i++, props++) {
 
845
        if ( props->name == XA_FONT ) {
 
846
            fontname = (char *)NameForAtom(props->value);
 
847
            break;
 
848
        }
 
849
    }
 
850
    return fontname;
 
851
}
 
852
 
 
853
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
854
/* Internal Font Selection                                               */
 
855
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
856
 
 
857
static char
 
858
isInternal(FontPtr pfont)
 
859
{
 
860
int i;
 
861
FontInfoPtr pfi;
 
862
FontPropPtr props;
 
863
Atom dest;
 
864
 
 
865
    dest = MakeAtom("PRINTER_RESIDENT_FONT", strlen("PRINTER_RESIDENT_FONT"), TRUE);
 
866
 
 
867
    pfi = (FontInfoRec *)&pfont->info;
 
868
    props = pfi->props;
 
869
    for (i=0; i<pfi->nprops; i++, props++) {
 
870
        if ( (Atom) props->name == dest && props->value == 2 )
 
871
                return INTERNAL_FONT;
 
872
    }
 
873
    return DOWNLOAD_FONT;
 
874
}
 
875
 
 
876
static void
 
877
selectInternalFont(FILE *outFile, PclInternalFontPtr pin, int fid)
 
878
{
 
879
    fprintf(outFile, "%c*c%dD", ESC, fid);
 
880
    if ( *pin->spacing == 'P' || *pin->spacing == 'p' )
 
881
        fprintf(outFile, pin->pcl_font_name, pin->height);
 
882
    else
 
883
        fprintf(outFile, pin->pcl_font_name, pin->pitch);
 
884
    fprintf(outFile, "%c*c6F", ESC);
 
885
}
 
886
 
 
887
static void
 
888
selectSize(FILE *outFile,
 
889
        PclContextPrivPtr pConPriv,
 
890
        PclInternalFontPtr pin)
 
891
{
 
892
    if ( *pin->spacing == 'P' || *pin->spacing == 'p' ) {
 
893
        sprintf(t, "SD4,%f;", pin->height);
 
894
        SAVE_PCL( outFile, pConPriv, t );
 
895
    } else {
 
896
        sprintf(t, "SD3,%f;", pin->pitch);
 
897
        SAVE_PCL( outFile, pConPriv, t );
 
898
    }
 
899
    return;
 
900
}
 
901
 
 
902
#ifdef DO_TWO_BYTE_PCL
 
903
static void
 
904
code_conv(
 
905
    PclSoftFontInfoPtr pSoftFontInfo,
 
906
    FontPtr pfont,
 
907
    char *from,
 
908
    char *to
 
909
)
 
910
{
 
911
iconv_t cd;
 
912
char frombuf[9], *fromptr;
 
913
size_t inbyte = 5, outbyte=2;
 
914
 
 
915
    fromptr = frombuf;
 
916
    frombuf[0] = 0x1b; /* Esc */
 
917
    frombuf[1] = 0x24; /* $ */
 
918
    frombuf[2] = 0x42; /* B */
 
919
    frombuf[3] = *from;
 
920
    frombuf[4] = *(from+1);
 
921
    frombuf[5] = 0x1b; /* Esc */
 
922
    frombuf[6] = 0x28; /* ( */
 
923
    frombuf[7] = 0x4a; /* J */
 
924
    frombuf[8] = 0x0;
 
925
    if ((cd = iconv_open("sjis", "jis")) == (iconv_t)(-1)) {
 
926
        *to = (unsigned char)NULL;
 
927
        return;
 
928
    }
 
929
 
 
930
    if ( iconv(cd, &fromptr, &inbyte, &to, &outbyte) == -1 )
 
931
        *to = (unsigned char)NULL;
 
932
 
 
933
    iconv_close(cd);
 
934
    return;
 
935
}
 
936
#endif /* DO_TWO_BYTE_PCL */