aboutsummaryrefslogtreecommitdiff
path: root/nx-X11/extras/ttf2pt1/ft.c
diff options
context:
space:
mode:
authorReinhard Tartler <siretart@tauware.de>2011-10-10 17:43:39 +0200
committerReinhard Tartler <siretart@tauware.de>2011-10-10 17:43:39 +0200
commitf4092abdf94af6a99aff944d6264bc1284e8bdd4 (patch)
tree2ac1c9cc16ceb93edb2c4382c088dac5aeafdf0f /nx-X11/extras/ttf2pt1/ft.c
parenta840692edc9c6d19cd7c057f68e39c7d95eb767d (diff)
downloadnx-libs-f4092abdf94af6a99aff944d6264bc1284e8bdd4.tar.gz
nx-libs-f4092abdf94af6a99aff944d6264bc1284e8bdd4.tar.bz2
nx-libs-f4092abdf94af6a99aff944d6264bc1284e8bdd4.zip
Imported nx-X11-3.1.0-1.tar.gznx-X11/3.1.0-1
Summary: Imported nx-X11-3.1.0-1.tar.gz Keywords: Imported nx-X11-3.1.0-1.tar.gz into Git repository
Diffstat (limited to 'nx-X11/extras/ttf2pt1/ft.c')
-rw-r--r--nx-X11/extras/ttf2pt1/ft.c808
1 files changed, 808 insertions, 0 deletions
diff --git a/nx-X11/extras/ttf2pt1/ft.c b/nx-X11/extras/ttf2pt1/ft.c
new file mode 100644
index 000000000..60a429654
--- /dev/null
+++ b/nx-X11/extras/ttf2pt1/ft.c
@@ -0,0 +1,808 @@
+/*
+ * The font parser using the FreeType library version 2.
+ *
+ * see COPYRIGHT
+ *
+ */
+
+#ifdef USE_FREETYPE
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <sys/types.h>
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include FT_TRUETYPE_TABLES_H
+#include FT_BBOX_H
+#include FT_GLYPH_H
+
+#include FT_CONFIG_CONFIG_H
+#include FT_CONFIG_OPTIONS_H
+#include FT_ERRORS_H
+#include FT_SYSTEM_H
+#include FT_IMAGE_H
+#include FT_TYPES_H
+#include FT_OUTLINE_H
+#include FT_MODULE_H
+#include FT_RENDER_H
+#include FT_TYPE1_TABLES_H
+#include FT_TRUETYPE_IDS_H
+#include FT_TRUETYPE_TAGS_H
+#include FT_MULTIPLE_MASTERS_H
+#include FT_SFNT_NAMES_H
+
+#ifdef XP_PSTEXT
+#include "os.h"
+#include "Xproto.h"
+#include "font.h"
+#include "fontstruct.h"
+#include "fntfilst.h"
+#include "fontutil.h"
+#include "fontenc.h"
+#include "ft.h"
+#define NOT_IN_FTFUNCS
+#include "ftfuncs.h"
+#endif /* XP_PSTEXT */
+
+#include "pt1.h"
+#include "global.h"
+
+/* prototypes of call entries */
+static void openfont(char *fname, char *arg);
+static void closefont( void);
+static int getnglyphs ( void);
+static int glnames( GLYPH *glyph_list);
+static void glmetrics( GLYPH *glyph_list);
+static int glenc( GLYPH *glyph_list, int *encoding, int *unimap);
+static void fnmetrics( struct font_metrics *fm);
+static void glpath( int glyphno, GLYPH *glyph_list);
+static void kerning( GLYPH *glyph_list);
+
+/* globals */
+
+/* front-end descriptor */
+struct frontsw freetype_sw = {
+ /*name*/ "ft",
+ /*descr*/ "based on the FreeType2 library",
+ /*suffix*/ { "ttf", "ttc", "otf", "otc", "pfa", "pfb" },
+ /*open*/ openfont,
+ /*close*/ closefont,
+ /*nglyphs*/ getnglyphs,
+ /*glnames*/ glnames,
+ /*glmetrics*/ glmetrics,
+ /*glenc*/ glenc,
+ /*fnmetrics*/ fnmetrics,
+ /*glpath*/ glpath,
+ /*kerning*/ kerning,
+};
+
+/* statics */
+
+static char * dupcnstring( unsigned char *s, int len);
+
+#ifndef XP_PSTEXT
+static FT_Library library;
+#endif /* !XP_PSTEXT */
+static FT_Face face;
+
+static int enc_type, enc_found;
+
+/* SFNT functions do not seem to be included by default in FT2beta8 */
+#define ENABLE_SFNT
+
+/*
+ * Open font and prepare to return information to the main driver.
+ * May print error and warning messages.
+ * Exit on error.
+ */
+
+static void
+openfont(
+ char *fname,
+ char *arg /* unused now */
+)
+{
+ FT_Error error;
+
+#ifdef XP_PSTEXT
+ extern FT_Face xp_pstext_ft_face;
+ extern FT_Library ftypeLibrary; /* defined in xc/lib/font/FreeType/ftfuncs.c */
+
+ face = xp_pstext_ft_face;
+#else
+ if( FT_Init_FreeType( &library ) ) {
+ fprintf(stderr, "** FreeType initialization failed\n");
+ exit(1);
+ }
+
+ if( error = FT_New_Face( library, fname, 0, &face ) ) {
+ if ( error == FT_Err_Unknown_File_Format )
+ fprintf(stderr, "**** %s has format unknown to FreeType\n", fname);
+ else
+ fprintf(stderr, "**** Cannot access %s ****\n", fname);
+ exit(1);
+ }
+#endif /* XP_PSTEXT */
+
+ if(FT_HAS_FIXED_SIZES(face)) {
+ WARNING_1 fprintf(stderr, "Font contains bitmaps\n");
+ }
+ if(FT_HAS_MULTIPLE_MASTERS(face)) {
+ WARNING_1 fprintf(stderr, "Font contains multiple masters, using default\n");
+ }
+
+ if(ISDBG(FT)) fprintf(stderr," %d units per EM\n", face->units_per_EM);
+
+ enc_found = 0;
+}
+
+/*
+ * Close font.
+ * Exit on error.
+ */
+
+static void
+closefont(
+ void
+)
+{
+#ifdef XP_PSTEXT
+ /* NOP */
+#else
+ if( FT_Done_Face(face) ) {
+ WARNING_1 fprintf(stderr, "Errors when closing the font file, ignored\n");
+ }
+ if( FT_Done_FreeType(library) ) {
+ WARNING_1 fprintf(stderr, "Errors when stopping FreeType, ignored\n");
+ }
+#endif /* XP_PSTEXT */
+}
+
+/*
+ * Get the number of glyphs in font.
+ */
+
+static int
+getnglyphs (
+ void
+)
+{
+ if(ISDBG(FT)) fprintf(stderr, "%d glyphs in font\n", face->num_glyphs);
+ return (int)face->num_glyphs;
+}
+
+/*
+ * Get the names of the glyphs.
+ * Returns 0 if the names were assigned, non-zero if the font
+ * provides no glyph names.
+ */
+
+static int
+glnames(
+ GLYPH *glyph_list
+)
+{
+#define MAX_NAMELEN 1024
+
+#ifdef XP_PSTEXT
+ char buf[1024];
+ long i;
+ FT_Error error;
+
+#ifdef XP_ONLY_BLOCKS
+ extern unsigned long xp_font_block_offset;
+ extern FTFontPtr xp_xtf;
+ int bc; /* block counter */
+
+
+ /* FixMe: This code should use PsOut_Get_FreeType_Glyph_Name() instead of
+ * duplicating the code
+ */
+ for( bc = xp_font_block_offset ; bc < (xp_font_block_offset+256) ; bc++ ) {
+ /* Remap X11 font index to FreeType font index */
+ i = FTRemap(face, &xp_xtf->mapping, bc);
+
+ if( i >= face->num_glyphs )
+ continue;
+#else
+ for(i=0; i < face->num_glyphs; i++) {
+#endif /* XP_ONLY_BLOCKS */
+ if( FT_Has_PS_Glyph_Names(face) ) {
+ error = FT_Get_Glyph_Name(face, i, buf, MAX_NAMELEN);
+ }
+ else
+ {
+ error = -1;
+ }
+
+ if( error ) {
+ /* Check for unicode mapping
+ * See Adobe document "Unicode and Glyph Names"
+ * (http://partners.adobe.com/asn/tech/type/unicodegn.jsp)
+ */
+ if( (xp_xtf->mapping.mapping->type == FONT_ENCODING_UNICODE) &&
+ (i < 0xFFFE) )
+ {
+ sprintf(buf, "uni%04lx", i);
+ }
+ else
+ {
+ sprintf(buf, "ch%02lx", i);
+ }
+ }
+ glyph_list[i].name = strdup(buf);
+ if(ISDBG(FT)) fprintf(stderr, "%d has name %s\n", i, buf);
+ if (glyph_list[i].name == NULL) {
+ fprintf (stderr, "****malloc failed %s line %d\n", __FILE__, __LINE__);
+ exit(255);
+ }
+ }
+
+ return 0;
+#else
+ char bf[1024];
+ long i;
+
+ if( ! FT_HAS_GLYPH_NAMES(face) ) {
+ WARNING_1 fprintf(stderr, "Font has no glyph names\n");
+ return 1;
+ }
+
+ for(i=0; i < face->num_glyphs; i++) {
+ if( FT_Get_Glyph_Name(face, i, bf, MAX_NAMELEN) || bf[0]==0 ) {
+ sprintf(bf, "_g_%d", i);
+ WARNING_2 fprintf(stderr,
+ "Glyph No. %d has no postscript name, becomes %s\n", i, bf);
+ }
+ glyph_list[i].name = strdup(bf);
+ if(ISDBG(FT)) fprintf(stderr, "%d has name %s\n", i, bf);
+ if (glyph_list[i].name == NULL) {
+ fprintf (stderr, "****malloc failed %s line %d\n", __FILE__, __LINE__);
+ exit(255);
+ }
+ }
+
+ return 0;
+#endif /* XP_PSTEXT */
+}
+
+/*
+ * Get the metrics of the glyphs.
+ */
+
+static void
+glmetrics(
+ GLYPH *glyph_list
+)
+{
+ GLYPH *g;
+ int i;
+ FT_Glyph_Metrics *met;
+ FT_BBox bbox;
+ FT_Glyph gly;
+
+#ifdef XP_ONLY_BLOCKS
+ extern unsigned long xp_font_block_offset;
+ extern FTFontPtr xp_xtf;
+ int bc; /* block counter */
+
+ for( bc = xp_font_block_offset ; bc < (xp_font_block_offset+256) ; bc++ ) {
+ /* Remap X11 font index to FreeType font index */
+ i = FTRemap(face, &xp_xtf->mapping, bc);
+
+ if( i >= face->num_glyphs )
+ continue;
+
+#else
+ for(i=0; i < face->num_glyphs; i++) {
+#endif /* XP_ONLY_BLOCKS */
+ g = &(glyph_list[i]);
+
+ if( FT_Load_Glyph(face, i, FT_LOAD_NO_BITMAP|FT_LOAD_NO_SCALE) ) {
+ fprintf(stderr, "Can't load glyph %s, skipped\n", g->name);
+ continue;
+ }
+
+ met = &face->glyph->metrics;
+
+ if(FT_HAS_HORIZONTAL(face)) {
+ g->width = met->horiAdvance;
+ g->lsb = met->horiBearingX;
+ } else {
+ WARNING_2 fprintf(stderr, "Glyph %s has no horizontal metrics, guessed them\n", g->name);
+ g->width = met->width;
+ g->lsb = 0;
+ }
+
+ if( FT_Get_Glyph(face->glyph, &gly) ) {
+ fprintf(stderr, "Can't access glyph %s bbox, skipped\n", g->name);
+ continue;
+ }
+
+ FT_Glyph_Get_CBox(gly, ft_glyph_bbox_unscaled, &bbox);
+ g->xMin = bbox.xMin;
+ g->yMin = bbox.yMin;
+ g->xMax = bbox.xMax;
+ g->yMax = bbox.yMax;
+
+ g->ttf_pathlen = face->glyph->outline.n_points;
+ }
+}
+
+/*
+ * Get the original encoding of the font.
+ * Returns 1 for if the original encoding is Unicode, 2 if the
+ * original encoding is other 16-bit, 0 if 8-bit.
+ */
+
+static int
+glenc(
+ GLYPH *glyph_list,
+ int *encoding,
+ int *unimap
+)
+{
+#ifdef XP_PSTEXT
+ int i,
+ e;
+ unsigned code;
+ extern FTFontPtr xp_xtf;
+ extern unsigned long xp_font_block_offset;
+
+ enc_found = 1;
+ enc_type = 0;
+
+ for(i=0; i<ENCTABSZ; i++) {
+ if(encoding[i] != -1)
+ continue;
+
+ /* Remap X11 font index to FreeType font index */
+ code = FTRemap(face, &xp_xtf->mapping, xp_font_block_offset+i);
+
+ if(code == 0)
+ continue; /* .notdef */
+
+ encoding[i] = code;
+ }
+
+ return enc_type;
+#else
+ int i, e;
+ unsigned code;
+
+ if(ISDBG(FT))
+ for(e=0; e < face->num_charmaps; e++) {
+ fprintf(stderr, "found encoding pid=%d eid=%d\n",
+ face->charmaps[e]->platform_id,
+ face->charmaps[e]->encoding_id);
+ }
+
+ if(enc_found)
+ goto populate_map;
+
+ enc_type = 0;
+
+ /* first check for an explicit PID/EID */
+
+ if(force_pid != -1) {
+ for(e=0; e < face->num_charmaps; e++) {
+ if(face->charmaps[e]->platform_id == force_pid
+ && face->charmaps[e]->encoding_id == force_eid) {
+ WARNING_1 fprintf(stderr, "Found Encoding PID=%d/EID=%d\n",
+ force_pid, force_eid);
+ if( FT_Set_Charmap(face, face->charmaps[e]) ) {
+ fprintf(stderr, "**** Cannot set charmap in FreeType ****\n");
+ exit(1);
+ }
+ enc_type = 1;
+ goto populate_map;
+ }
+ }
+ fprintf(stderr, "*** TTF encoding table PID=%d/EID=%d not found\n",
+ force_pid, force_eid);
+ exit(1);
+ }
+
+ /* next check for a direct Adobe mapping */
+
+ if(!forcemap) {
+ for(e=0; e < face->num_charmaps; e++) {
+ if(face->charmaps[e]->encoding == ft_encoding_adobe_custom) {
+ WARNING_1 fputs("Found Adobe Custom Encoding\n", stderr);
+ if( FT_Set_Charmap(face, face->charmaps[e]) ) {
+ fprintf(stderr, "**** Cannot set charmap in FreeType ****\n");
+ exit(1);
+ }
+ goto populate_map;
+ }
+ }
+ }
+
+ for(e=0; e < face->num_charmaps; e++) {
+ if(face->charmaps[e]->platform_id == 3) {
+ switch(face->charmaps[e]->encoding_id) {
+ case 0:
+ WARNING_1 fputs("Found Symbol Encoding\n", stderr);
+ break;
+ case 1:
+ WARNING_1 fputs("Found Unicode Encoding\n", stderr);
+ enc_type = 1;
+ break;
+ default:
+ WARNING_1 {
+ fprintf(stderr,
+ "****MS Encoding ID %d not supported****\n",
+ face->charmaps[e]->encoding_id);
+ fputs("Treating it like Symbol encoding\n", stderr);
+ }
+ break;
+ }
+ break;
+ }
+ }
+ if(e >= face->num_charmaps) {
+ WARNING_1 fputs("No Microsoft encoding, using first encoding available\n", stderr);
+ e = 0;
+ }
+
+ if( FT_Set_Charmap(face, face->charmaps[e]) ) {
+ fprintf(stderr, "**** Cannot set charmap in FreeType ****\n");
+ exit(1);
+ }
+
+populate_map:
+ enc_found = 1;
+ for(i=0; i<ENCTABSZ; i++) {
+ if(encoding[i] != -1)
+ continue;
+ if(enc_type == 1 || forcemap) {
+ code = unimap[i];
+ if(code == (unsigned) -1)
+ continue;
+ } else
+ code = i;
+
+ code = FT_Get_Char_Index(face, code);
+ if(0 && ISDBG(FT)) fprintf(stderr, "code of %3d is %3d\n", i, code);
+ if(code == 0)
+ continue; /* .notdef */
+ encoding[i] = code;
+ }
+
+ return enc_type;
+#endif /* XP_PSTEXT */
+}
+
+/* duplicate a string with counter to a 0-terminated string */
+static char *
+dupcnstring(
+ unsigned char *s,
+ int len
+)
+{
+ char *res, *out;
+ int i, c;
+ static int warned=0;
+
+ if(( res = malloc(len+1) )==NULL) {
+ fprintf (stderr, "****malloc failed %s line %d\n", __FILE__, __LINE__);
+ exit(255);
+ }
+
+ out = res;
+ for(i=0; i<len; i++) {
+ if(( c=s[i] )>=' ' && c!=127)
+ *out++ = c;
+ else if(!warned) {
+ warned=1;
+ WARNING_1 fprintf(stderr, "Some font name strings are in Unicode, may not show properly\n");
+ }
+ }
+ *out = 0;
+ return res;
+}
+
+/*
+ * Get the font metrics
+ */
+static void
+fnmetrics(
+ struct font_metrics *fm
+)
+{
+ char *str;
+ static char *fieldstocheck[3];
+#ifdef ENABLE_SFNT
+ FT_SfntName sn;
+#endif /* ENABLE_SFNT */
+ int i;
+
+ fm->italic_angle = 0.0; /* FreeType hides the angle */
+ fm->underline_position = face->underline_position;
+ fm->underline_thickness = face->underline_thickness;
+ fm->is_fixed_pitch = FT_IS_FIXED_WIDTH(face);
+
+ fm->ascender = face->ascender;
+ fm->descender = face->descender;
+
+ fm->units_per_em = face->units_per_EM;
+
+ fm->bbox[0] = face->bbox.xMin;
+ fm->bbox[1] = face->bbox.yMin;
+ fm->bbox[2] = face->bbox.xMax;
+ fm->bbox[3] = face->bbox.yMax;
+
+#ifdef ENABLE_SFNT
+ if( FT_Get_Sfnt_Name(face, TT_NAME_ID_COPYRIGHT, &sn) )
+#endif /* ENABLE_SFNT */
+ fm->name_copyright = "";
+#ifdef ENABLE_SFNT
+ else
+ fm->name_copyright = dupcnstring(sn.string, sn.string_len);
+#endif /* ENABLE_SFNT */
+
+ fm->name_family = face->family_name;
+
+ fm->name_style = face->style_name;
+ if(fm->name_style == NULL)
+ fm->name_style = "";
+
+#ifdef ENABLE_SFNT
+ if( FT_Get_Sfnt_Name(face, TT_NAME_ID_FULL_NAME, &sn) )
+#endif /* ENABLE_SFNT */
+ {
+ int len;
+
+ len = strlen(fm->name_family) + strlen(fm->name_style) + 2;
+ if(( fm->name_full = malloc(len) )==NULL) {
+ fprintf (stderr, "****malloc failed %s line %d\n", __FILE__, __LINE__);
+ exit(255);
+ }
+ strcpy(fm->name_full, fm->name_family);
+ if(strlen(fm->name_style) != 0) {
+ strcat(fm->name_full, " ");
+ strcat(fm->name_full, fm->name_style);
+ }
+ }
+#ifdef ENABLE_SFNT
+ else
+ fm->name_full = dupcnstring(sn.string, sn.string_len);
+#endif /* ENABLE_SFNT */
+
+#ifdef ENABLE_SFNT
+ if( FT_Get_Sfnt_Name(face, TT_NAME_ID_VERSION_STRING, &sn) )
+#endif /* ENABLE_SFNT */
+ fm->name_version = "1.0";
+#ifdef ENABLE_SFNT
+ else
+ fm->name_version = dupcnstring(sn.string, sn.string_len);
+#endif /* ENABLE_SFNT */
+
+#ifdef XP_PSTEXT
+ {
+ extern const char *xp_psfontname;
+
+ fm->name_ps = strdup(xp_psfontname);
+
+ /* Handle the rare case if a family name was not provided by the TTF
+ * font (like Solaris TTF fonts in /usr/openwin/lib/locale/ko.UTF-8/X11/fonts/TrueType,
+ * /usr/openwin/lib/locale/ko/X11/fonts/TrueType) - in this case we
+ * have to generate a family name somehow... */
+ if(fm->name_family == NULL)
+ fm->name_family = fm->name_ps;
+ }
+#else
+
+#ifdef ENABLE_SFNT
+ if( FT_Get_Sfnt_Name(face, TT_NAME_ID_PS_NAME , &sn) ) {
+#endif /* ENABLE_SFNT */
+ if(( fm->name_ps = strdup(fm->name_full) )==NULL) {
+ fprintf (stderr, "****malloc failed %s line %d\n", __FILE__, __LINE__);
+ exit(255);
+ }
+#ifdef ENABLE_SFNT
+ } else
+ fm->name_ps = dupcnstring(sn.string, sn.string_len);
+#endif /* ENABLE_SFNT */
+
+#endif /* XP_PSTEXT */
+
+ for(i=0; fm->name_ps[i]!=0; i++)
+ if(fm->name_ps[i] == ' ')
+ fm->name_ps[i] = '_'; /* no spaces in the Postscript name *m */
+
+ /* guess the boldness from the font names */
+ fm->force_bold=0;
+
+ fieldstocheck[0] = fm->name_style;
+ fieldstocheck[1] = fm->name_full;
+ fieldstocheck[2] = fm->name_ps;
+
+ for(i=0; !fm->force_bold && i<sizeof fieldstocheck /sizeof(fieldstocheck[0]); i++) {
+ str=fieldstocheck[i];
+ for(i=0; str[i]!=0; i++) {
+ if( (str[i]=='B'
+ || str[i]=='b'
+ && ( i==0 || !isalpha(str[i-1]) )
+ )
+ && !strncmp("old",&str[i+1],3)
+ && !islower(str[i+4])
+ ) {
+ fm->force_bold=1;
+ break;
+ }
+ }
+ }
+}
+
+/*
+ * Functions to decompose the outlines
+ */
+
+static GLYPH *curg;
+static double lastx, lasty;
+
+static int
+outl_moveto(
+ FT_Vector *to,
+ void *unused
+)
+{
+ double tox, toy;
+
+ tox = fscale((double)to->x); toy = fscale((double)to->y);
+
+ /* FreeType does not do explicit closepath() */
+ if(curg->lastentry) {
+ g_closepath(curg);
+ }
+ fg_rmoveto(curg, tox, toy);
+ lastx = tox; lasty = toy;
+
+ return 0;
+}
+
+static int
+outl_lineto(
+ FT_Vector *to,
+ void *unused
+)
+{
+ double tox, toy;
+
+ tox = fscale((double)to->x); toy = fscale((double)to->y);
+
+ fg_rlineto(curg, tox, toy);
+ lastx = tox; lasty = toy;
+
+ return 0;
+}
+
+static int
+outl_conicto(
+ FT_Vector *control1,
+ FT_Vector *to,
+ void *unused
+)
+{
+ double c1x, c1y, tox, toy;
+
+ c1x = fscale((double)control1->x); c1y = fscale((double)control1->y);
+ tox = fscale((double)to->x); toy = fscale((double)to->y);
+
+ fg_rrcurveto(curg,
+ (lastx + 2.0 * c1x) / 3.0, (lasty + 2.0 * c1y) / 3.0,
+ (2.0 * c1x + tox) / 3.0, (2.0 * c1y + toy) / 3.0,
+ tox, toy );
+ lastx = tox; lasty = toy;
+
+ return 0;
+}
+
+static int
+outl_cubicto(
+ FT_Vector *control1,
+ FT_Vector *control2,
+ FT_Vector *to,
+ void *unused
+)
+{
+ double c1x, c1y, c2x, c2y, tox, toy;
+
+ c1x = fscale((double)control1->x); c1y = fscale((double)control1->y);
+ c2x = fscale((double)control2->x); c2y = fscale((double)control2->y);
+ tox = fscale((double)to->x); toy = fscale((double)to->y);
+
+ fg_rrcurveto(curg, c1x, c1y, c2x, c2y, tox, toy);
+ lastx = tox; lasty = toy;
+
+ return 0;
+}
+
+static FT_Outline_Funcs ft_outl_funcs = {
+ outl_moveto,
+ outl_lineto,
+ outl_conicto,
+ outl_cubicto,
+ 0,
+ 0
+};
+
+/*
+ * Get the path of contrours for a glyph.
+ */
+
+static void
+glpath(
+ int glyphno,
+ GLYPH *glyf_list
+)
+{
+ FT_Outline *ol;
+
+ curg = &glyf_list[glyphno];
+
+ if( FT_Load_Glyph(face, glyphno, FT_LOAD_NO_BITMAP|FT_LOAD_NO_SCALE|FT_LOAD_NO_HINTING)
+ || face->glyph->format != ft_glyph_format_outline ) {
+ fprintf(stderr, "Can't load glyph %s, skipped\n", curg->name);
+ return;
+ }
+
+ ol = &face->glyph->outline;
+ lastx = 0.0; lasty = 0.0;
+
+ if( FT_Outline_Decompose(ol, &ft_outl_funcs, NULL) ) {
+ fprintf(stderr, "Can't decompose outline of glyph %s, skipped\n", curg->name);
+ return;
+ }
+
+ /* FreeType does not do explicit closepath() */
+ if(curg->lastentry) {
+ g_closepath(curg);
+ }
+
+ if(ol->flags & ft_outline_reverse_fill) {
+ assertpath(curg->entries, __FILE__, __LINE__, curg->name);
+ reversepaths(curg);
+ }
+}
+
+/*
+ * Get the kerning data.
+ */
+
+static void
+kerning(
+ GLYPH *glyph_list
+)
+{
+ int i, j, n;
+ int nglyphs = face->num_glyphs;
+ FT_Vector k;
+ GLYPH *gl;
+
+ if( nglyphs == 0 || !FT_HAS_KERNING(face) ) {
+ WARNING_1 fputs("No Kerning data\n", stderr);
+ return;
+ }
+
+ for(i=0; i<nglyphs; i++) {
+ if( (glyph_list[i].flags & GF_USED) ==0)
+ continue;
+ for(j=0; j<nglyphs; j++) {
+ if( (glyph_list[j].flags & GF_USED) ==0)
+ continue;
+ if( FT_Get_Kerning(face, i, j, ft_kerning_unscaled, &k) )
+ continue;
+ if( k.x == 0 )
+ continue;
+
+ addkernpair(i, j, k.x);
+ }
+ }
+}
+
+#endif