~ubuntu-branches/ubuntu/jaunty/ghostscript/jaunty-updates

« back to all changes in this revision

Viewing changes to base/gdevxxf.c

  • Committer: Bazaar Package Importer
  • Author(s): Till Kamppeter
  • Date: 2009-01-20 16:40:45 UTC
  • mfrom: (1.1.10 upstream)
  • Revision ID: james.westby@ubuntu.com-20090120164045-lnfhi0n30o5lwhwa
Tags: 8.64.dfsg.1~svn9377-0ubuntu1
* New upstream release (SVN rev 9377)
   o Fixes many bugs concerning PDF rendering, to make the PDF printing
     workflow correctly working.
   o Fixes long-standing bugs in many drivers, like input paper tray and
     duplex options not working for the built-in PCL 4, 5, 5c, 5e, and
     6/XL drivers, PDF input not working for bjc600, bjc800, and cups
     output devices, several options not working and uninitialized
     memory with cups output device.
   o Merged nearly all patches of the Ubuntu and Debian packages upstream.
   o Fixes LP: #317810, LP: #314439, LP: #314018.
* debian/patches/03_libpaper_support.dpatch,
  debian/patches/11_gs-cjk_font_glyph_handling_fix.dpatch,
  debian/patches/12_gs-cjk_vertical_writing_metrics_fix.dpatch,
  debian/patches/13_gs-cjk_cjkps_examples.dpatch,
  debian/patches/20_bbox_segv_fix.dpatch,
  debian/patches/21_brother_7x0_gdi_fix.dpatch,
  debian/patches/22_epsn_margin_workaround.dpatch,
  debian/patches/24_gs_man_fix.dpatch,
  debian/patches/25_toolbin_insecure_tmp_usage_fix.dpatch,
  debian/patches/26_assorted_script_fixes.dpatch,
  debian/patches/29_gs_css_fix.dpatch,
  debian/patches/30_ps2pdf_man_improvement.dpatch,
  debian/patches/31_fix-gc-sigbus.dpatch,
  debian/patches/34_ftbfs-on-hurd-fix.dpatch,
  debian/patches/35_disable_libcairo.dpatch,
  debian/patches/38_pxl-duplex.dpatch,
  debian/patches/39_pxl-resolution.dpatch,
  debian/patches/42_gs-init-ps-delaybind-fix.dpatch,
  debian/patches/45_bjc600-bjc800-pdf-input.dpatch,
  debian/patches/48_cups-output-device-pdf-duplex-uninitialized-memory-fix.dpatch,
  debian/patches/50_lips4-floating-point-exception.dpatch,
  debian/patches/52_cups-device-logging.dpatch,
  debian/patches/55_pcl-input-slot-fix.dpatch,
  debian/patches/57_pxl-input-slot-fix.dpatch,
  debian/patches/60_pxl-cups-driver-pdf.dpatch,
  debian/patches/62_onebitcmyk-pdf.dpatch,
  debian/patches/65_too-big-temp-files-1.dpatch,
  debian/patches/67_too-big-temp-files-2.dpatch,
  debian/patches/70_take-into-account-data-in-stream-buffer-before-refill.dpatch:
  Removed, applied upstream.
* debian/patches/01_docdir_fix_for_debian.dpatch,
  debian/patches/02_gs_man_fix_debian.dpatch,
  debian/patches/01_docdir-fix-for-debian.dpatch,
  debian/patches/02_docdir-fix-for-debian.dpatch: Renamed patches to
  make merging with Debian easier.
* debian/patches/32_improve-handling-of-media-size-changes-from-gv.dpatch, 
  debian/patches/33_bad-params-to-xinitimage-on-large-bitmaps.dpatch:
  regenerated for new source directory structure.
* debian/rules: Corrected paths to remove cidfmap (it is in Resource/Init/
  in GS 8.64) and to install headers (source paths are psi/ and base/ now).
* debian/rules: Remove all fontmaps, as DeFoMa replaces them.
* debian/local/pdftoraster/pdftoraster.c,
  debian/local/pdftoraster/pdftoraster.convs, debian/rules: Removed
  added pdftoraster filter and use the one which comes with Ghostscript.
* debian/ghostscript.links: s/8.63/8.64/

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2001-2006 Artifex Software, Inc.
 
2
   All Rights Reserved.
 
3
  
 
4
   This software is provided AS-IS with no warranty, either express or
 
5
   implied.
 
6
 
 
7
   This software is distributed under license and may not be copied, modified
 
8
   or distributed except as expressly authorized under the terms of that
 
9
   license.  Refer to licensing information at http://www.artifex.com/
 
10
   or contact Artifex Software, Inc.,  7 Mt. Lassen Drive - Suite A-134,
 
11
   San Rafael, CA  94903, U.S.A., +1(415)492-9861, for further information.
 
12
*/
 
13
 
 
14
/* $Id: gdevxxf.c 8250 2007-09-25 13:31:24Z giles $ */
 
15
/* External font (xfont) implementation for X11. */
 
16
#include "math_.h"
 
17
#include "memory_.h"
 
18
#include "x_.h"
 
19
#include "gx.h"
 
20
#include "gxdevice.h"
 
21
#include "gdevx.h"
 
22
#include "gsstruct.h"
 
23
#include "gsutil.h"
 
24
#include "gserrors.h"
 
25
#include "gxxfont.h"
 
26
 
 
27
/* Define the smallest point size that we trust X to render reasonably well. */
 
28
#define min_X_font_size 6
 
29
/* Define the largest point size where X will do a better job than we can. */
 
30
#define max_X_font_size 35
 
31
 
 
32
extern gx_device_X gs_x11_device;
 
33
 
 
34
extern const byte gs_map_std_to_iso[256];
 
35
extern const byte gs_map_iso_to_std[256];
 
36
 
 
37
/* Declare the xfont procedures */
 
38
static xfont_proc_lookup_font(x_lookup_font);
 
39
static xfont_proc_char_xglyph(x_char_xglyph);
 
40
static xfont_proc_char_metrics(x_char_metrics);
 
41
static xfont_proc_render_char(x_render_char);
 
42
static xfont_proc_release(x_release);
 
43
static const gx_xfont_procs x_xfont_procs =
 
44
{
 
45
    x_lookup_font,
 
46
    x_char_xglyph,
 
47
    x_char_metrics,
 
48
    x_render_char,
 
49
    x_release
 
50
};
 
51
 
 
52
/* Return the xfont procedure record. */
 
53
const gx_xfont_procs *
 
54
gdev_x_get_xfont_procs(gx_device * dev)
 
55
{
 
56
    return &x_xfont_procs;
 
57
}
 
58
 
 
59
/* Define a X11 xfont. */
 
60
typedef struct x_xfont_s x_xfont;
 
61
struct x_xfont_s {
 
62
    gx_xfont_common common;
 
63
    gx_device_X *xdev;
 
64
    XFontStruct *font;
 
65
    int encoding_index;
 
66
    int My;
 
67
    int angle;
 
68
};
 
69
 
 
70
gs_private_st_dev_ptrs1(st_x_xfont, x_xfont, "x_xfont",
 
71
                        x_xfont_enum_ptrs, x_xfont_reloc_ptrs, xdev);
 
72
 
 
73
/* ---------------- Utilities ---------------- */
 
74
 
 
75
/* Search one set of font maps for a font with a given name. */
 
76
static x11fontmap *
 
77
find_fontmap(x11fontmap *fmps, const byte *fname, uint len)
 
78
{
 
79
    x11fontmap *fmp = fmps;
 
80
 
 
81
    while (fmp) {
 
82
        if (len == strlen(fmp->ps_name) &&
 
83
            strncmp(fmp->ps_name, (const char *)fname, len) == 0)
 
84
            break;
 
85
        fmp = fmp->next;
 
86
    }
 
87
    return fmp;
 
88
}
 
89
 
 
90
/* Find an X font with a given name, encoding, and size. */
 
91
static char *
 
92
find_x_font(gx_device_X *xdev, char x11template[256], x11fontmap *fmp,
 
93
            const char *encoding_name, x11fontlist *fls, int xheight,
 
94
            bool *scalable_font)
 
95
{
 
96
    int i;
 
97
    char *x11fontname = 0;
 
98
    int len1 = strlen(fmp->x11_name) + 1;
 
99
 
 
100
    if (fls->count == -1) {
 
101
        sprintf(x11template, "%s-*-*-*-*-*-*-%s", fmp->x11_name,
 
102
                encoding_name);
 
103
        fls->names = XListFonts(xdev->dpy, x11template, 32, &fls->count);
 
104
    }
 
105
    *scalable_font = false;
 
106
    for (i = 0; i < fls->count; i++) {
 
107
        const char *szp = fls->names[i] + len1;
 
108
        int size = 0;
 
109
 
 
110
        while (*szp >= '0' && *szp <= '9')
 
111
            size = size * 10 + *szp++ - '0';
 
112
        if (size == 0) {
 
113
            *scalable_font = true;
 
114
            continue;
 
115
        }
 
116
        if (size == xheight)
 
117
            return fls->names[i];
 
118
    }
 
119
    if (*scalable_font && xdev->useScalableFonts) {
 
120
        sprintf(x11template, "%s-%d-0-0-0-*-0-%s", fmp->x11_name,
 
121
                xheight, encoding_name);
 
122
        x11fontname = x11template;
 
123
    }
 
124
    return x11fontname;
 
125
}
 
126
 
 
127
/* ---------------- xfont procedures ---------------- */
 
128
 
 
129
/* Look up a font. */
 
130
static gx_xfont *
 
131
x_lookup_font(gx_device * dev, const byte * fname, uint len,
 
132
            int encoding_index, const gs_uid * puid, const gs_matrix * pmat,
 
133
              gs_memory_t * mem)
 
134
{
 
135
    gx_device_X *xdev = (gx_device_X *) dev;
 
136
    x_xfont *xxf;
 
137
    char x11template[256];
 
138
    char *x11fontname = NULL;
 
139
    XFontStruct *x11font;
 
140
    x11fontmap *fmp;
 
141
    double height;
 
142
    int xwidth, xheight, angle;
 
143
    Boolean My;
 
144
    bool scalable_font;
 
145
 
 
146
    if (!xdev->useXFonts)
 
147
        return NULL;
 
148
 
 
149
    if (pmat->xy == 0 && pmat->yx == 0) {
 
150
        xwidth = fabs(pmat->xx * 1000) + 0.5;
 
151
        xheight = fabs(pmat->yy * 1000) + 0.5;
 
152
        height = fabs(pmat->yy * 1000);
 
153
        angle = (pmat->xx > 0 ? 0 : 180);
 
154
        My = (pmat->xx > 0 && pmat->yy > 0) || (pmat->xx < 0 && pmat->yy < 0);
 
155
    } else if (pmat->xx == 0 && pmat->yy == 0) {
 
156
        xwidth = fabs(pmat->xy * 1000) + 0.5;
 
157
        xheight = fabs(pmat->yx * 1000) + 0.5;
 
158
        height = fabs(pmat->yx * 1000);
 
159
        angle = (pmat->yx < 0 ? 90 : 270);
 
160
        My = (pmat->yx > 0 && pmat->xy < 0) || (pmat->yx < 0 && pmat->xy > 0);
 
161
    } else {
 
162
        return NULL;
 
163
    }
 
164
 
 
165
    /* Don't do very small fonts, where font metrics are way off */
 
166
    /* due to rounding and the server does a very bad job of scaling, */
 
167
    /* or very large fonts, where we can do just as good a job and */
 
168
    /* the server may lock up the entire window system while rasterizing */
 
169
    /* the whole font. */
 
170
    if (xwidth < min_X_font_size || xwidth > max_X_font_size ||
 
171
        xheight < min_X_font_size || xheight > max_X_font_size
 
172
        )
 
173
        return NULL;
 
174
 
 
175
    if (!xdev->useFontExtensions && (My || angle != 0))
 
176
        return NULL;
 
177
 
 
178
    switch (encoding_index) {
 
179
    case 0:
 
180
        fmp = find_fontmap(xdev->regular_fonts, fname, len);
 
181
        if (fmp == NULL)
 
182
            return NULL;
 
183
        x11fontname =
 
184
            find_x_font(xdev, x11template, fmp, "Adobe-fontspecific",
 
185
                        &fmp->std, xheight, &scalable_font);
 
186
        if (!x11fontname) {
 
187
            x11fontname =
 
188
                find_x_font(xdev, x11template, fmp, "ISO8859-1",
 
189
                            &fmp->iso, xheight, &scalable_font);
 
190
            encoding_index = 1;
 
191
        }
 
192
        break;
 
193
    case 1:
 
194
        fmp = find_fontmap(xdev->regular_fonts, fname, len);
 
195
        if (fmp == NULL)
 
196
            return NULL;
 
197
        x11fontname =
 
198
            find_x_font(xdev, x11template, fmp, "ISO8859-1",
 
199
                        &fmp->iso, xheight, &scalable_font);
 
200
        if (!x11fontname) {
 
201
            x11fontname =
 
202
                find_x_font(xdev, x11template, fmp, "Adobe-fontspecific",
 
203
                            &fmp->std, xheight, &scalable_font);
 
204
            encoding_index = 0;
 
205
        }
 
206
        break;
 
207
    case 2:
 
208
        fmp = xdev->symbol_fonts;
 
209
        goto sym;
 
210
    case 3:
 
211
        fmp = xdev->dingbat_fonts;
 
212
sym:    fmp = find_fontmap(fmp, fname, len);
 
213
        if (fmp == NULL)
 
214
            return NULL;
 
215
        x11fontname =
 
216
            find_x_font(xdev, x11template, fmp, "Adobe-fontspecific",
 
217
                        &fmp->std, xheight, &scalable_font);
 
218
    default:
 
219
        return NULL;
 
220
    }
 
221
    if (!x11fontname)
 
222
        return NULL;
 
223
 
 
224
    if (xwidth != xheight || angle != 0 || My) {
 
225
        if (!xdev->useScalableFonts || !scalable_font)
 
226
            return NULL;
 
227
        sprintf(x11template, "%s%s+%d-%d+%d-0-0-0-*-0-%s",
 
228
                fmp->x11_name, (My ? "+My" : ""),
 
229
                angle * 64, xheight, xwidth,
 
230
                (encoding_index == 1 ? "ISO8859-1" : "Adobe-fontspecific"));
 
231
        x11fontname = x11template;
 
232
    }
 
233
    x11font = XLoadQueryFont(xdev->dpy, x11fontname);
 
234
    if (x11font == NULL)
 
235
        return NULL;
 
236
    /* Don't bother with 16-bit or 2 byte fonts yet */
 
237
    if (x11font->min_byte1 || x11font->max_byte1) {
 
238
        XFreeFont(xdev->dpy, x11font);
 
239
        return NULL;
 
240
    }
 
241
    xxf = gs_alloc_struct(mem, x_xfont, &st_x_xfont, "x_lookup_font");
 
242
    if (xxf == NULL)
 
243
        return NULL;
 
244
    xxf->common.procs = &x_xfont_procs;
 
245
    xxf->xdev = xdev;
 
246
    xxf->font = x11font;
 
247
    xxf->encoding_index = encoding_index;
 
248
    xxf->My = (My ? -1 : 1);
 
249
    xxf->angle = angle;
 
250
    if (xdev->logXFonts) {
 
251
        dprintf3("Using %s\n  for %s at %g pixels.\n", x11fontname,
 
252
                 fmp->ps_name, height);
 
253
        dflush();
 
254
    }
 
255
    return (gx_xfont *) xxf;
 
256
}
 
257
 
 
258
/* Convert a character name or index to an xglyph code. */
 
259
static gx_xglyph
 
260
x_char_xglyph(gx_xfont * xf, gs_char chr, int encoding_index,
 
261
              gs_glyph glyph, const gs_const_string *glyph_name)
 
262
{
 
263
    const x_xfont *xxf = (x_xfont *) xf;
 
264
 
 
265
    if (chr == gs_no_char)
 
266
        return gx_no_xglyph;    /* can't look up names yet */
 
267
    if (encoding_index != xxf->encoding_index) {
 
268
        if (encoding_index == 0 && xxf->encoding_index == 1)
 
269
            chr = gs_map_std_to_iso[chr];
 
270
        else if (encoding_index == 1 && xxf->encoding_index == 0)
 
271
            chr = gs_map_iso_to_std[chr];
 
272
        else
 
273
            return gx_no_xglyph;
 
274
        if (chr == 0)
 
275
            return gx_no_xglyph;
 
276
    }
 
277
    if (chr < xxf->font->min_char_or_byte2 ||
 
278
        chr > xxf->font->max_char_or_byte2)
 
279
        return gx_no_xglyph;
 
280
    if (xxf->font->per_char) {
 
281
        int i = chr - xxf->font->min_char_or_byte2;
 
282
        const XCharStruct *xc = &xxf->font->per_char[i];
 
283
 
 
284
        if ((xc->lbearing == 0) && (xc->rbearing == 0) &&
 
285
            (xc->ascent == 0) && (xc->descent == 0))
 
286
            return gx_no_xglyph;
 
287
    }
 
288
    return (gx_xglyph) chr;
 
289
}
 
290
 
 
291
/* Get the metrics for a character. */
 
292
static int
 
293
x_char_metrics(gx_xfont * xf, gx_xglyph xg, int wmode,
 
294
               gs_point * pwidth, gs_int_rect * pbbox)
 
295
{
 
296
    const x_xfont *xxf = (const x_xfont *) xf;
 
297
    int width;
 
298
 
 
299
    if (wmode != 0)
 
300
        return gs_error_undefined;
 
301
    if (xxf->font->per_char == NULL) {
 
302
        width = xxf->font->max_bounds.width;
 
303
        pbbox->p.x = xxf->font->max_bounds.lbearing;
 
304
        pbbox->q.x = xxf->font->max_bounds.rbearing;
 
305
        pbbox->p.y = -xxf->font->max_bounds.ascent;
 
306
        pbbox->q.y = xxf->font->max_bounds.descent;
 
307
    } else {
 
308
        int i = xg - xxf->font->min_char_or_byte2;
 
309
        const XCharStruct *xc = &xxf->font->per_char[i];
 
310
 
 
311
        width = xc->width;
 
312
        pbbox->p.x = xc->lbearing;
 
313
        pbbox->q.x = xc->rbearing;
 
314
        pbbox->p.y = -xc->ascent;
 
315
        pbbox->q.y = xc->descent;
 
316
    }
 
317
    switch (xxf->angle) {
 
318
    case 0:
 
319
        pwidth->x = width, pwidth->y = 0; break;
 
320
    case 90:
 
321
        pwidth->x = 0, pwidth->y = -xxf->My * width; break;
 
322
    case 180:
 
323
        pwidth->x = -width, pwidth->y = 0; break;
 
324
    case 270:
 
325
        pwidth->x = 0, pwidth->y = xxf->My * width; break;
 
326
    }
 
327
    return 0;
 
328
}
 
329
 
 
330
/* Render a character. */
 
331
static int
 
332
x_render_char(gx_xfont * xf, gx_xglyph xg, gx_device * dev,
 
333
              int xo, int yo, gx_color_index color, int required)
 
334
{
 
335
    x_xfont *xxf = (x_xfont *) xf;
 
336
    char chr = (char)xg;
 
337
    gs_point wxy;
 
338
    gs_int_rect bbox;
 
339
    int x, y, w, h;
 
340
    int code;
 
341
 
 
342
    if (dev->dname == gs_x11_device.dname && !((gx_device_X *)dev)->is_buffered) {
 
343
        gx_device_X *xdev = (gx_device_X *)dev;
 
344
 
 
345
        code = (*xf->common.procs->char_metrics) (xf, xg, 0, &wxy, &bbox);
 
346
        if (code < 0)
 
347
            return code;
 
348
        /* Buffer text for more efficient X interaction. */
 
349
        if (xdev->text.item_count == MAX_TEXT_ITEMS ||
 
350
            xdev->text.char_count == MAX_TEXT_CHARS ||
 
351
            (IN_TEXT(xdev) &&
 
352
             (yo != xdev->text.origin.y || color != xdev->fore_color ||
 
353
              xxf->font->fid != xdev->fid))
 
354
            ) {
 
355
            DRAW_TEXT(xdev);
 
356
            xdev->text.item_count = xdev->text.char_count = 0;
 
357
        }
 
358
        if (xdev->text.item_count == 0) {
 
359
            X_SET_FILL_STYLE(xdev, FillSolid);
 
360
            X_SET_FORE_COLOR(xdev, color);
 
361
            X_SET_FUNCTION(xdev, GXcopy);
 
362
            xdev->text.origin.x = xdev->text.x = xo;
 
363
            xdev->text.origin.y = yo;
 
364
            xdev->text.items[0].font = xdev->fid = xxf->font->fid;
 
365
        }
 
366
        /*
 
367
         * The following is wrong for rotated text, but it doesn't matter,
 
368
         * because the next call of x_render_char will have a different Y.
 
369
         */
 
370
        {
 
371
            int index = xdev->text.item_count;
 
372
            XTextItem *item = &xdev->text.items[index];
 
373
            char *pchar = &xdev->text.chars[xdev->text.char_count++];
 
374
            int delta = xo - xdev->text.x;
 
375
 
 
376
            *pchar = chr;
 
377
            if (index > 0 && delta == 0) {
 
378
                /* Continue the same item. */
 
379
                item[-1].nchars++;
 
380
            } else {
 
381
                /* Start a new item. */
 
382
                item->chars = pchar;
 
383
                item->nchars = 1;
 
384
                item->delta = delta;
 
385
                if (index > 0)
 
386
                    item->font = None;
 
387
                xdev->text.item_count++;
 
388
            }
 
389
            xdev->text.x = xo + wxy.x;
 
390
        }
 
391
        if (xdev->bpixmap != (Pixmap) 0) {
 
392
            x = xo + bbox.p.x;
 
393
            y = yo + bbox.p.y;
 
394
            w = bbox.q.x - bbox.p.x;
 
395
            h = bbox.q.y - bbox.p.y;
 
396
            fit_fill(dev, x, y, w, h);
 
397
            x_update_add(xdev, x, y, w, h);
 
398
        }
 
399
        return 0;
 
400
    } else if (!required)
 
401
        return -1;              /* too hard */
 
402
    else {
 
403
        /* Display on an intermediate bitmap, then copy the bits. */
 
404
        gx_device_X *xdev = xxf->xdev;
 
405
        int wbm, raster;
 
406
        int i;
 
407
        XImage *xim;
 
408
        Pixmap xpm;
 
409
        GC fgc;
 
410
        byte *bits;
 
411
 
 
412
        dev_proc_copy_mono((*copy_mono)) = dev_proc(dev, copy_mono);
 
413
 
 
414
        code = (*xf->common.procs->char_metrics) (xf, xg, 0, &wxy, &bbox);
 
415
        if (code < 0)
 
416
            return code;
 
417
        w = bbox.q.x - bbox.p.x;
 
418
        h = bbox.q.y - bbox.p.y;
 
419
        wbm = ROUND_UP(w, align_bitmap_mod * 8);
 
420
        raster = wbm >> 3;
 
421
        bits = (byte *) gs_malloc(xdev->memory, h, raster, "x_render_char");
 
422
        if (bits == 0)
 
423
            return gs_error_limitcheck;
 
424
        xpm = XCreatePixmap(xdev->dpy, xdev->win, w, h, 1);
 
425
        fgc = XCreateGC(xdev->dpy, xpm, None, NULL);
 
426
        XSetForeground(xdev->dpy, fgc, 0);
 
427
        XFillRectangle(xdev->dpy, xpm, fgc, 0, 0, w, h);
 
428
        XSetForeground(xdev->dpy, fgc, 1);
 
429
        XSetFont(xdev->dpy, fgc, xxf->font->fid);
 
430
        XDrawString(xdev->dpy, xpm, fgc, -bbox.p.x, -bbox.p.y, &chr, 1);
 
431
        xim = XGetImage(xdev->dpy, xpm, 0, 0, w, h, 1, ZPixmap);
 
432
        i = 0;
 
433
        for (y = 0; y < h; y++) {
 
434
            char b = 0;
 
435
 
 
436
            for (x = 0; x < wbm; x++) {
 
437
                b = b << 1;
 
438
                if (x < w)
 
439
                    b += XGetPixel(xim, x, y);
 
440
                if ((x & 7) == 7)
 
441
                    bits[i++] = b;
 
442
            }
 
443
        }
 
444
        code = (*copy_mono) (dev, bits, 0, raster, gx_no_bitmap_id,
 
445
                             xo + bbox.p.x, yo + bbox.p.y, w, h,
 
446
                             gx_no_color_index, color);
 
447
        gs_free(xdev->memory, (char *)bits, h, raster, "x_render_char");
 
448
        XFreePixmap(xdev->dpy, xpm);
 
449
        XFreeGC(xdev->dpy, fgc);
 
450
        XDestroyImage(xim);
 
451
        return (code < 0 ? code : 0);
 
452
    }
 
453
}
 
454
 
 
455
/* Release an xfont. */
 
456
static int
 
457
x_release(gx_xfont * xf, gs_memory_t * mem)
 
458
{
 
459
#if 0
 
460
    /* The device may not be open.  Cannot reliably free the font. */
 
461
    x_xfont *xxf = (x_xfont *) xf;
 
462
 
 
463
    XFreeFont(xxf->xdev->dpy, xxf->font);
 
464
#endif
 
465
    if (mem != NULL)
 
466
        gs_free_object(mem, xf, "x_release");
 
467
    return 0;
 
468
}