First import
[xorg_rtime.git] / xorg-server-1.4 / hw / xprint / ps / PsText.c
blob98cf1534555f16f54021ebd106382fc5b36af70a
1 /*
3 Copyright 1996, 1998 The Open Group
5 Permission to use, copy, modify, distribute, and sell this software and its
6 documentation for any purpose is hereby granted without fee, provided that
7 the above copyright notice appear in all copies and that both that
8 copyright notice and this permission notice appear in supporting
9 documentation.
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 Except as contained in this notice, the name of The Open Group shall not be
22 used in advertising or otherwise to promote the sale, use or other dealings
23 in this Software without prior written authorization from The Open Group.
27 * (c) Copyright 1996 Hewlett-Packard Company
28 * (c) Copyright 1996 International Business Machines Corp.
29 * (c) Copyright 1996 Sun Microsystems, Inc.
30 * (c) Copyright 1996 Novell, Inc.
31 * (c) Copyright 1996 Digital Equipment Corp.
32 * (c) Copyright 1996 Fujitsu Limited
33 * (c) Copyright 1996 Hitachi, Ltd.
35 * Permission is hereby granted, free of charge, to any person obtaining
36 * a copy of this software and associated documentation files (the
37 * "Software"), to deal in the Software without restriction, including
38 * without limitation the rights to use, copy, modify, merge, publish,
39 * distribute, sublicense, and/or sell copies of the Software, and to
40 * permit persons to whom the Software is furnished to do so, subject
41 * to the following conditions:
43 * The above copyright notice and this permission notice shall be included
44 * in all copies or substantial portions of the Software.
46 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
47 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
48 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
49 * THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
50 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
51 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
52 * SOFTWARE.
54 * Except as contained in this notice, the names of the copyright holders
55 * shall not be used in advertising or otherwise to promote the sale, use
56 * or other dealings in this Software without prior written authorization
57 * from said copyright holders.
60 /*******************************************************************
62 ** *********************************************************
63 ** *
64 ** * File: PsText.c
65 ** *
66 ** * Contents: Character-drawing routines for the PS DDX
67 ** *
68 ** * Created By: Roger Helmendach (Liberty Systems)
69 ** *
70 ** * Copyright: Copyright 1996 The Open Group, Inc.
71 ** *
72 ** *********************************************************
73 **
74 ********************************************************************/
76 #ifdef HAVE_DIX_CONFIG_H
77 #include <dix-config.h>
78 #endif
80 #include "Ps.h"
81 #include "gcstruct.h"
82 #include "windowstr.h"
83 #include <X11/fonts/fntfil.h>
84 #include <X11/fonts/fntfilst.h>
85 #include <limits.h>
87 int
88 PsPolyText8(
89 DrawablePtr pDrawable,
90 GCPtr pGC,
91 int x,
92 int y,
93 int count,
94 char *string)
96 if( pDrawable->type==DRAWABLE_PIXMAP )
98 DisplayElmPtr elm;
99 PixmapPtr pix = (PixmapPtr)pDrawable;
100 PsPixmapPrivPtr priv = (PsPixmapPrivPtr)pix->devPrivate.ptr;
101 DisplayListPtr disp;
102 GCPtr gc;
104 if ((gc = PsCreateAndCopyGC(pDrawable, pGC)) == NULL) return x;
106 disp = PsGetFreeDisplayBlock(priv);
108 elm = &disp->elms[disp->nelms];
109 elm->type = Text8Cmd;
110 elm->gc = gc;
111 elm->c.text8.x = x;
112 elm->c.text8.y = y;
113 elm->c.text8.count = count;
114 elm->c.text8.string = (char *)xalloc(count);
115 memcpy(elm->c.text8.string, string, count);
116 disp->nelms += 1;
118 return x;
120 else
122 PsFontInfoRec *firec;
124 /* We need a context for rendering... */
125 if (PsGetPsContextPriv(pDrawable) == NULL)
126 return x;
128 firec = PsGetFontInfoRec(pDrawable, pGC->font);
129 if (!firec)
130 return x;
132 #ifdef XP_USE_FREETYPE
133 if (firec->ftir->downloadableFont &&
134 (firec->ftir->font_type == PSFTI_FONT_TYPE_FREETYPE))
136 PsOutPtr psOut;
137 ColormapPtr cMap;
139 if( PsUpdateDrawableGC(pGC, pDrawable, &psOut, &cMap)==FALSE )
140 return x;
142 if (firec->ftir->alreadyDownloaded[0] == False)
144 PsOut_DownloadFreeType(psOut,
145 firec->ftir->ft_download_font_type,
146 firec->ftir->download_ps_name, pGC->font, 0);
147 firec->ftir->alreadyDownloaded[0] = True;
150 PsOut_Offset(psOut, pDrawable->x, pDrawable->y);
151 PsOut_Color(psOut, PsGetPixelColor(cMap, pGC->fgPixel));
152 if (!firec->size)
153 PsOut_TextAttrsMtx(psOut, firec->ftir->download_ps_name, firec->mtx, firec->ftir->is_iso_encoding);
154 else
155 PsOut_TextAttrs(psOut, firec->ftir->download_ps_name, firec->size, firec->ftir->is_iso_encoding);
156 PsOut_FreeType_Text(pGC->font, psOut, x, y, string, count);
158 return x;
160 else
161 #endif /* XP_USE_FREETYPE */
162 if (firec->ftir->downloadableFont &&
163 (firec->ftir->font_type != PSFTI_FONT_TYPE_FREETYPE))
165 PsOutPtr psOut;
166 ColormapPtr cMap;
168 if( PsUpdateDrawableGC(pGC, pDrawable, &psOut, &cMap)==FALSE )
169 return x;
171 if (firec->ftir->alreadyDownloaded[0] == False)
173 PsOut_DownloadType1(psOut, "PsPolyText8",
174 firec->ftir->download_ps_name, firec->ftir->filename);
175 firec->ftir->alreadyDownloaded[0] = True;
178 PsOut_Offset(psOut, pDrawable->x, pDrawable->y);
179 PsOut_Color(psOut, PsGetPixelColor(cMap, pGC->fgPixel));
180 if (!firec->size)
181 PsOut_TextAttrsMtx(psOut, firec->ftir->download_ps_name, firec->mtx, firec->ftir->is_iso_encoding);
182 else
183 PsOut_TextAttrs(psOut, firec->ftir->download_ps_name, firec->size, firec->ftir->is_iso_encoding);
184 PsOut_Text(psOut, x, y, string, count, -1);
186 return x;
189 /* Render glyphs as bitmaps */
191 unsigned long n, i;
192 int w;
193 CharInfoPtr charinfo[255];
195 GetGlyphs(pGC->font, (unsigned long)count,
196 (unsigned char *)string, Linear8Bit, &n, charinfo);
197 w = 0;
198 for (i=0; i < n; i++)
199 w += charinfo[i]->metrics.characterWidth;
201 if (n != 0)
202 PsPolyGlyphBlt(pDrawable, pGC, x, y, n,
203 charinfo, FONTGLYPHS(pGC->font));
204 x += w;
206 return x;
209 return x;
213 PsPolyText16(
214 DrawablePtr pDrawable,
215 GCPtr pGC,
216 int x,
217 int y,
218 int count,
219 unsigned short *string)
221 if( pDrawable->type==DRAWABLE_PIXMAP )
223 DisplayElmPtr elm;
224 PixmapPtr pix = (PixmapPtr)pDrawable;
225 PsPixmapPrivPtr priv = (PsPixmapPrivPtr)pix->devPrivate.ptr;
226 DisplayListPtr disp;
227 GCPtr gc;
229 if ((gc = PsCreateAndCopyGC(pDrawable, pGC)) == NULL) return x;
231 disp = PsGetFreeDisplayBlock(priv);
233 elm = &disp->elms[disp->nelms];
234 elm->type = Text16Cmd;
235 elm->gc = gc;
236 elm->c.text16.x = x;
237 elm->c.text16.y = y;
238 elm->c.text16.count = count;
239 elm->c.text16.string =
240 (unsigned short *)xalloc(count*sizeof(unsigned short));
241 memcpy(elm->c.text16.string, string, count*sizeof(unsigned short));
242 disp->nelms += 1;
244 return x;
246 else
248 PsFontInfoRec *firec;
250 /* We need a context for rendering... */
251 if (PsGetPsContextPriv(pDrawable) == NULL)
252 return x;
254 firec = PsGetFontInfoRec(pDrawable, pGC->font);
255 if (!firec)
256 return x;
258 #ifdef XP_USE_FREETYPE
259 if (firec->ftir->downloadableFont &&
260 (firec->ftir->font_type == PSFTI_FONT_TYPE_FREETYPE))
262 PsOutPtr psOut;
263 ColormapPtr cMap;
264 unsigned short c,
265 c_hiByte,
266 c_lowByte,
267 fontPage;
268 int i;
270 if( PsUpdateDrawableGC(pGC, pDrawable, &psOut, &cMap)==FALSE )
271 return x;
273 /* Scan the string we want to render and download all neccesary parts
274 * of the font (one part(="font page") has 256 glyphs)
276 for( i = 0 ; i < count ; i++ )
278 c = string[i];
279 #if IMAGE_BYTE_ORDER == LSBFirst
280 c_hiByte = c & 0x00FF;
281 c_lowByte = (c >> 8) & 0x00FF;
282 #elif IMAGE_BYTE_ORDER == MSBFirst
283 c_hiByte = (c >> 8) & 0x00FF;
284 c_lowByte = c & 0x00FF;
285 #else
286 #error Unsupported byte order
287 #endif
288 fontPage = c_hiByte;
290 if (firec->ftir->alreadyDownloaded[fontPage] == False)
292 char buffer[256];
293 const char *ps_name;
295 if (fontPage > 0)
297 sprintf(buffer, "%s_%x", firec->ftir->download_ps_name, (int)fontPage);
298 ps_name = buffer;
300 else
302 ps_name = firec->ftir->download_ps_name;
305 PsOut_DownloadFreeType(psOut,
306 firec->ftir->ft_download_font_type,
307 ps_name, pGC->font, (fontPage * 0x100)); /* same as (fontPage << 8) */
309 firec->ftir->alreadyDownloaded[fontPage] = True;
314 PsOut_Offset(psOut, pDrawable->x, pDrawable->y);
315 PsOut_Color(psOut, PsGetPixelColor(cMap, pGC->fgPixel));
316 if (!firec->size)
317 PsOut_FreeType_TextAttrsMtx16(psOut, firec->ftir->download_ps_name, firec->mtx, firec->ftir->is_iso_encoding);
318 else
319 PsOut_FreeType_TextAttrs16(psOut, firec->ftir->download_ps_name, firec->size, firec->ftir->is_iso_encoding);
320 PsOut_FreeType_Text16(pGC->font, psOut, x, y, string, count);
322 return x;
324 else
325 #endif /* XP_USE_FREETYPE */
326 if (firec->ftir->downloadableFont &&
327 (firec->ftir->font_type != PSFTI_FONT_TYPE_FREETYPE))
329 PsOutPtr psOut;
330 ColormapPtr cMap;
331 unsigned short fontPage;
333 if( PsUpdateDrawableGC(pGC, pDrawable, &psOut, &cMap)==FALSE )
334 return x;
336 PsOut_DownloadType1(psOut, "PsPolyText16",
337 firec->ftir->download_ps_name, firec->ftir->filename);
338 firec->ftir->alreadyDownloaded[fontPage] = True;
340 PsOut_Offset(psOut, pDrawable->x, pDrawable->y);
341 PsOut_Color(psOut, PsGetPixelColor(cMap, pGC->fgPixel));
342 if (!firec->size)
343 PsOut_TextAttrsMtx(psOut, firec->ftir->download_ps_name, firec->mtx, firec->ftir->is_iso_encoding);
344 else
345 PsOut_TextAttrs(psOut, firec->ftir->download_ps_name, firec->size, firec->ftir->is_iso_encoding);
346 PsOut_Text16(psOut, x, y, string, count, -1);
348 return x;
351 /* Render glyphs as bitmaps */
353 unsigned long n, i;
354 int w;
355 CharInfoPtr charinfo[255]; /* encoding only has 1 byte for count */
357 GetGlyphs(pGC->font, (unsigned long)count, (unsigned char *)string,
358 (FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit,
359 &n, charinfo);
360 w = 0;
361 for (i=0; i < n; i++)
362 w += charinfo[i]->metrics.characterWidth;
363 if (n != 0)
364 PsPolyGlyphBlt(pDrawable, pGC, x, y, n, charinfo, FONTGLYPHS(pGC->font));
365 x += w;
367 return x;
370 return x;
373 void
374 PsImageText8(
375 DrawablePtr pDrawable,
376 GCPtr pGC,
377 int x,
378 int y,
379 int count,
380 char *string)
382 if( pDrawable->type==DRAWABLE_PIXMAP )
384 DisplayElmPtr elm;
385 PixmapPtr pix = (PixmapPtr)pDrawable;
386 PsPixmapPrivPtr priv = (PsPixmapPrivPtr)pix->devPrivate.ptr;
387 DisplayListPtr disp;
388 GCPtr gc;
390 if ((gc = PsCreateAndCopyGC(pDrawable, pGC)) == NULL) return;
392 disp = PsGetFreeDisplayBlock(priv);
394 elm = &disp->elms[disp->nelms];
395 elm->type = TextI8Cmd;
396 elm->gc = gc;
397 elm->c.text8.x = x;
398 elm->c.text8.y = y;
399 elm->c.text8.count = count;
400 elm->c.text8.string = (char *)xalloc(count);
401 memcpy(elm->c.text8.string, string, count);
402 disp->nelms += 1;
404 else
406 int iso;
407 int siz;
408 float mtx[4];
409 char *fnam;
410 PsOutPtr psOut;
411 ColormapPtr cMap;
413 if( PsUpdateDrawableGC(pGC, pDrawable, &psOut, &cMap)==FALSE ) return;
414 PsOut_Offset(psOut, pDrawable->x, pDrawable->y);
415 PsOut_Color(psOut, PsGetPixelColor(cMap, pGC->fgPixel));
416 fnam = PsGetPSFontName(pGC->font);
417 if( !fnam ) fnam = "Times-Roman";
418 siz = PsGetFontSize(pGC->font, mtx);
419 iso = PsIsISOLatin1Encoding(pGC->font);
420 if( !siz ) PsOut_TextAttrsMtx(psOut, fnam, mtx, iso);
421 else PsOut_TextAttrs(psOut, fnam, siz, iso);
422 PsOut_Text(psOut, x, y, string, count, PsGetPixelColor(cMap, pGC->bgPixel));
426 void
427 PsImageText16(
428 DrawablePtr pDrawable,
429 GCPtr pGC,
430 int x,
431 int y,
432 int count,
433 unsigned short *string)
435 if( pDrawable->type==DRAWABLE_PIXMAP )
437 DisplayElmPtr elm;
438 PixmapPtr pix = (PixmapPtr)pDrawable;
439 PsPixmapPrivPtr priv = (PsPixmapPrivPtr)pix->devPrivate.ptr;
440 DisplayListPtr disp;
441 GCPtr gc;
443 if ((gc = PsCreateAndCopyGC(pDrawable, pGC)) == NULL) return;
445 disp = PsGetFreeDisplayBlock(priv);
447 elm = &disp->elms[disp->nelms];
448 elm->type = TextI16Cmd;
449 elm->gc = gc;
450 elm->c.text16.x = x;
451 elm->c.text16.y = y;
452 elm->c.text16.count = count;
453 elm->c.text16.string =
454 (unsigned short *)xalloc(count*sizeof(unsigned short));
455 memcpy(elm->c.text16.string, string, count*sizeof(unsigned short));
456 disp->nelms += 1;
458 else
460 int i;
461 char *str;
462 if( !count ) return;
463 str = (char *)xalloc(count);
464 for( i=0 ; i<count ; i++ ) str[i] = string[i];
465 PsImageText8(pDrawable, pGC, x, y, count, str);
466 free(str);
470 void
471 PsImageGlyphBlt(
472 DrawablePtr pDrawable,
473 GCPtr pGC,
474 int x,
475 int y,
476 unsigned int nGlyphs,
477 CharInfoPtr *pCharInfo,
478 pointer pGlyphBase)
480 /* NOT TO BE IMPLEMENTED */
483 void
484 PsPolyGlyphBlt(
485 DrawablePtr pDrawable,
486 GCPtr pGC,
487 int x,
488 int y,
489 unsigned int nGlyphs,
490 CharInfoPtr *pCharInfo,
491 pointer pGlyphBase)
493 int width, height;
494 PixmapPtr pPixmap;
495 int nbyLine; /* bytes per line of padded pixmap */
496 FontPtr pfont;
497 GCPtr pGCtmp;
498 register int i;
499 register int j;
500 unsigned char *pbits; /* buffer for PutImage */
501 register unsigned char *pb; /* temp pointer into buffer */
502 register CharInfoPtr pci; /* currect char info */
503 register unsigned char *pglyph; /* pointer bits in glyph */
504 int gWidth, gHeight; /* width and height of glyph */
505 register int nbyGlyphWidth; /* bytes per scanline of glyph */
506 int nbyPadGlyph; /* server padded line of glyph */
507 int w, tmpx;
508 XID gcvals[3];
510 pfont = pGC->font;
511 width = FONTMAXBOUNDS(pfont,rightSideBearing) -
512 FONTMINBOUNDS(pfont,leftSideBearing);
513 height = FONTMAXBOUNDS(pfont,ascent) +
514 FONTMAXBOUNDS(pfont,descent);
516 if ((width == 0) || (height == 0) )
517 return;
519 int i;
520 w = 0;
521 for (i=0; i < nGlyphs; i++) w += pCharInfo[i]->metrics.characterWidth;
523 pGCtmp = GetScratchGC(1, pDrawable->pScreen);
524 if (!pGCtmp)
526 (*pDrawable->pScreen->DestroyPixmap)(pPixmap);
527 return;
530 gcvals[0] = GXcopy;
531 gcvals[1] = pGC->fgPixel;
532 gcvals[2] = pGC->bgPixel;
534 DoChangeGC(pGCtmp, GCFunction|GCForeground|GCBackground, gcvals, 0);
537 nbyLine = BitmapBytePad(width);
538 pbits = (unsigned char *)ALLOCATE_LOCAL(height*nbyLine);
539 if (!pbits){
540 PsDestroyPixmap(pPixmap);
541 return;
543 tmpx = 0;
544 while(nGlyphs--)
546 pci = *pCharInfo++;
547 pglyph = FONTGLYPHBITS(pGlyphBase, pci);
548 gWidth = GLYPHWIDTHPIXELS(pci);
549 gHeight = GLYPHHEIGHTPIXELS(pci);
550 if (gWidth && gHeight)
552 nbyGlyphWidth = GLYPHWIDTHBYTESPADDED(pci);
553 nbyPadGlyph = BitmapBytePad(gWidth);
555 if (nbyGlyphWidth == nbyPadGlyph
556 #if GLYPHPADBYTES != 4
557 && (((int) pglyph) & 3) == 0
558 #endif
561 pb = pglyph;
563 else
565 for (i=0, pb = pbits; i<gHeight; i++, pb = pbits+(i*nbyPadGlyph))
566 for (j = 0; j < nbyGlyphWidth; j++)
567 *pb++ = *pglyph++;
568 pb = pbits;
571 PsPutImageMask((DrawablePtr)pDrawable, pGCtmp,
572 1, x + pci->metrics.leftSideBearing,
573 y - pci->metrics.ascent, gWidth, gHeight,
574 0, XYBitmap, (char *)pb);
577 x += pci->metrics.characterWidth;
579 DEALLOCATE_LOCAL(pbits);
580 FreeScratchGC(pGCtmp);