Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 104512
Collapse All | Expand All

(-)src/configure.ac (+37 lines)
Lines 399-404 Link Here
399
               fi])
399
               fi])
400
AC_SUBST(COMPILE_INITS)
400
AC_SUBST(COMPILE_INITS)
401
401
402
dnl Do we have libfontconfig ?
403
dnl Don't bother trying to use fontconfig-config, recent fontconfig versions
404
dnl provide pkg-config instead.
405
PKG_CONFIG=""
406
AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
407
LIBFONTCONFIG_LIBS=
408
LIBFONTCONFIG_CFLAGS=
409
AC_MSG_CHECKING([for fontconfig])
410
if test -n "${PKG_CONFIG}"; then
411
	LIBFONTCONFIG_LIBS="`${PKG_CONFIG} fontconfig --libs`"
412
	LIBFONTCONFIG_CFLAGS="`${PKG_CONFIG} fontconfig --cflags`"
413
	if test -n "$LIBFONTCONFIG_LIBS" || test -n "$LIBFONTCONFIG_CFLAGS"; then
414
		AC_MSG_RESULT([found])
415
	else
416
		AC_MSG_RESULT([not found])
417
	fi
418
else
419
	AC_MSG_RESULT([failed: pkg-config not found])
420
fi
421
dnl We found fontconfig, or think we did, but need to check if it's usable
422
SAVE_CFLAGS="${CFLAGS}"
423
SAVE_LDFLAGS="${LDFLAGS}"
424
CFLAGS="${CFLAGS} ${LIBFONTCONFIG_CFLAGS}"
425
LDFLAGS="${LDFLAGS} ${LIBFONTCONFIG_LIBS}"
426
AC_CHECK_LIB(fontconfig, FcPatternBuild, [hafontconfig=yes],[hafontconfig=no])
427
CFLAGS="${SAVE_CFLAGS}"
428
LDFLAGS="${SAVE_LDFLAGS}"
429
AC_MSG_CHECKING([if fontconfig is usable])
430
if test $hafontconfig = yes; then
431
	AC_DEFINE_UNQUOTED(HAVE_FONTCONFIG, 1, [Defines if your system has the libfontconfig library])
432
	AC_MSG_RESULT([yes])
433
else
434
	AC_MSG_RESULT([no])
435
fi
436
AC_SUBST(LIBFONTCONFIG_LIBS)
437
AC_SUBST(LIBFONTCONFIG_CFLAGS)
438
402
dnl --------------------------------------------------
439
dnl --------------------------------------------------
403
dnl Check for library functions
440
dnl Check for library functions
404
dnl --------------------------------------------------
441
dnl --------------------------------------------------
(-)src/gp_unix.c (-3 / +186 lines)
Lines 24-29 Link Here
24
#include "gsexit.h"
24
#include "gsexit.h"
25
#include "gp.h"
25
#include "gp.h"
26
26
27
#define HAVE_FONTCONFIG
28
29
#ifdef HAVE_FONTCONFIG
30
#include <fontconfig/fontconfig.h>
31
#endif
32
27
/*
33
/*
28
 * This is the only place in Ghostscript that calls 'exit'.  Including
34
 * This is the only place in Ghostscript that calls 'exit'.  Including
29
 * <stdlib.h> is overkill, but that's where it's declared on ANSI systems.
35
 * <stdlib.h> is overkill, but that's where it's declared on ANSI systems.
Lines 175-190 Link Here
175
  * building a custom fontmap file.
181
  * building a custom fontmap file.
176
  */
182
  */
177
 
183
 
184
185
/* Mangle the FontConfig family and style information into a
186
 * PostScript font name */
187
#ifdef HAVE_FONTCONFIG
188
static void makePSFontName(char* family, int weight, int slant, char *buf, int bufsize)
189
{
190
    int bytesCopied, length, i;
191
    const char *slantname, *weightname;
192
193
    switch (slant) {
194
	case FC_SLANT_ROMAN:   slantname=""; break;;
195
	case FC_SLANT_OBLIQUE: slantname="Oblique"; break;;
196
	case FC_SLANT_ITALIC:  slantname="Italic"; break;;
197
	default:               slantname="Unknown"; break;;
198
    }
199
200
    switch (weight) {
201
	case FC_WEIGHT_MEDIUM:   weightname=""; break;;
202
	case FC_WEIGHT_LIGHT:    weightname="Light"; break;;
203
	case FC_WEIGHT_DEMIBOLD: weightname="Demi"; break;;
204
	case FC_WEIGHT_BOLD:     weightname="Bold"; break;;
205
	case FC_WEIGHT_BLACK:    weightname="Black"; break;;
206
	default:                 weightname="Unknown"; break;;
207
    }
208
209
    length = strlen(family);
210
    if (length >= bufsize)
211
	length = bufsize;
212
    /* Copy the family name, stripping spaces */
213
    bytesCopied=0;
214
    for (i = 0; i < length; i++)
215
	if (family[i] != ' ')
216
	    buf[bytesCopied++] = family[i];
217
218
    if ( ((slant != FC_SLANT_ROMAN) || (weight != FC_WEIGHT_MEDIUM)) \
219
	    && bytesCopied < bufsize )
220
    {
221
	buf[bytesCopied] = '-';
222
	bytesCopied++;
223
	if (weight != FC_WEIGHT_MEDIUM)
224
	{
225
	    length = strlen(family);
226
	    if ((length + bytesCopied) >= bufsize)
227
		length = bufsize - bytesCopied - 1;
228
	    strncpy(buf+bytesCopied, weightname, length);
229
	    bytesCopied += length;
230
	}
231
	if (slant != FC_SLANT_ROMAN)
232
	{
233
	    length = strlen(family);
234
	    if ((length + bytesCopied) >= bufsize)
235
		length = bufsize - bytesCopied - 1;
236
	    strncpy(buf+bytesCopied, slantname, length);
237
	    bytesCopied += length;
238
	}
239
    }
240
    buf[bytesCopied] = '\0';
241
}
242
#endif
243
244
/* State struct for font iteration - passed as an opaque 'void*' through the rest of gs */
245
#ifdef HAVE_FONTCONFIG
246
typedef struct {
247
    int index;              /* current index of iteration over font_list */
248
    FcConfig* fc;           /* FontConfig library handle */
249
    FcFontSet* font_list;   /* FontConfig font list */
250
    char name[255];         /* name of last font */
251
} unix_fontenum_t;
252
#endif
253
178
void *gp_enumerate_fonts_init(gs_memory_t *mem)
254
void *gp_enumerate_fonts_init(gs_memory_t *mem)
179
{
255
{
256
#ifdef HAVE_FONTCONFIG
257
    unix_fontenum_t *state = (unix_fontenum_t *)malloc(sizeof(unix_fontenum_t));
258
    if (state == NULL)
259
	return NULL;    /* Failed to allocate state */
260
261
    state->index     = 0;
262
    state->fc        = NULL;
263
    state->font_list = NULL;
264
265
    /* Load the fontconfig library */
266
    state->fc = FcInitLoadConfigAndFonts();
267
    if (state->fc == NULL) {
268
	free(state);
269
	state = NULL;
270
	dlprintf("destroyed state - fontconfig init failed");
271
	return NULL;  /* Failed to open fontconfig library */
272
    }
273
274
    /* load the font set that we'll iterate over */
275
    FcPattern *pat = FcPatternBuild(NULL,
276
	    FC_OUTLINE, FcTypeBool, 1,
277
	    FC_SCALABLE, FcTypeBool, 1,
278
	    NULL);
279
    FcObjectSet* os = FcObjectSetBuild(FC_FILE, FC_OUTLINE, FC_FAMILY, FC_WEIGHT, FC_SLANT, 0);
280
    state->font_list = FcFontList(0, pat, os);
281
    FcPatternDestroy(pat);
282
    FcObjectSetDestroy(os);
283
    if (state->font_list == NULL) {
284
	free(state);
285
	state = NULL;
286
	return NULL;  /* Failed to generate font list */
287
    }
288
    return (void *)state;
289
#else
180
    return NULL;
290
    return NULL;
291
#endif
181
}
292
}
182
         
293
183
int gp_enumerate_fonts_next(void *enum_state, char **fontname, char **path)
294
int gp_enumerate_fonts_next(void *enum_state, char **fontname, char **path)
184
{
295
{
296
#ifdef HAVE_FONTCONFIG
297
    char* psname = NULL;
298
299
    unix_fontenum_t* state = (unix_fontenum_t *)enum_state;
300
    if (state == NULL) {
301
	return 0;   /* gp_enumerate_fonts_init failed for some reason */
302
    }
303
304
    /* Bits of the following were borrowed from Red Hat's GS 7 FontConfig patch */
305
    FcChar8* file_fc = NULL;
306
    FcChar8* family_fc = NULL;
307
    int outline_fc, slant_fc, weight_fc;
308
    FcResult result;
309
310
    if (state->index == state->font_list->nfont) {
311
	return 0; /* we've run out of fonts */
312
    }
313
314
    FcPattern* font = state->font_list->fonts[state->index];
315
316
    result = FcPatternGetString (font, FC_FAMILY, 0, &family_fc);
317
    if (result != FcResultMatch || family_fc == NULL) {
318
	dlprintf ("DEBUG: FC_FAMILY mismatch\n");
319
	return 0;
320
    }
321
322
    result = FcPatternGetString (font, FC_FILE, 0, &file_fc);
323
    if (result != FcResultMatch || file_fc == NULL) {
324
	dlprintf ("DEBUG: FC_FILE mismatch\n");
325
	return 0;
326
    }
327
328
    result = FcPatternGetBool (font, FC_OUTLINE, 0, &outline_fc);
329
    if (result != FcResultMatch) {
330
	dlprintf1 ("DEBUG: FC_OUTLINE failed to match on %s\n", (char*)family_fc);
331
	return 0;
332
    }
333
334
    result = FcPatternGetInteger (font, FC_SLANT, 0, &slant_fc);
335
    if (result != FcResultMatch) {
336
	dlprintf ("DEBUG: FC_SLANT didn't match\n");
337
	return 0;
338
    }
339
340
    result = FcPatternGetInteger (font, FC_WEIGHT, 0, &weight_fc);
341
    if (result != FcResultMatch) {
342
	dlprintf ("DEBUG: FC_WEIGHT didn't match\n");
343
	return 0;
344
    }
345
346
    /* Gross hack to work around Fontconfig's inability to tell
347
     * us the font's PostScript name - generate it ourselves.
348
     * We must free the memory allocated here next time around. */
349
    makePSFontName((char *)family_fc, weight_fc, slant_fc, &state->name, sizeof(state->name));
350
    *fontname = &state->name;
351
352
    /* return the font path straight out of fontconfig */
353
    *path = (char*)file_fc;
354
355
    state->index ++;
356
    return 1;
357
#else
185
    return 0;
358
    return 0;
359
#endif
186
}
360
}
187
                         
361
188
void gp_enumerate_fonts_free(void *enum_state)
362
void gp_enumerate_fonts_free(void *enum_state)
189
{
363
{
190
}           
364
#ifdef HAVE_FONTCONFIG
365
    unix_fontenum_t* state = (unix_fontenum_t *)enum_state;
366
    if (state != NULL) {
367
	if (state->font_list != NULL)
368
	    FcFontSetDestroy(state->font_list);
369
	free(state);
370
    }
371
#endif
372
}
373

Return to bug 104512