#include <stdio.h>
#include <string.h>
#include "fcint.h"
-#include <freetype/freetype.h>
-#include <freetype/internal/ftobjs.h>
-#include <freetype/tttables.h>
-#include <freetype/ftsnames.h>
-#include <freetype/ttnameid.h>
-#include <freetype/t1tables.h>
-
-#if (FREETYPE_MINOR > 1 || (FREETYPE_MINOR == 1 && FREETYPE_PATCH >= 4))
-#include <freetype/ftbdf.h>
-#include <freetype/ftmodule.h>
-#define USE_FTBDF
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include FT_INTERNAL_OBJECTS_H
+#include FT_TRUETYPE_TABLES_H
+#include FT_SFNT_NAMES_H
+#include FT_TRUETYPE_IDS_H
+#include FT_TYPE1_TABLES_H
+
+#if HAVE_FT_GET_BDF_PROPERTY
+#include FT_BDF_H
+#include FT_MODULE_H
#define HAS_BDF_PROPERTY(f) ((f) && (f)->driver && \
(f)->driver->root.clazz->get_interface)
#define MY_Get_BDF_Property(f,n,p) (HAS_BDF_PROPERTY(f) ? \
FT_Err_Invalid_Argument)
#endif
+#if !HAVE_FT_GET_BDF_PROPERTY
+#warning "No FT_Get_BDF_Property"
+#endif
+
+#if !HAVE_FT_GET_PS_FONT_INFO
+#warning "No FT_Get_Font_Info"
+#endif
/*
* Keep Han languages separated by eliminating languages
#define FcIsSlant(s) FcStringIsConst(s,slantConsts,NUM_SLANT_CONSTS)
#define FcContainsSlant(s) FcStringContainsConst (s,slantConsts,NUM_SLANT_CONSTS)
+static double
+FcGetPixelSize (FT_Face face, int i)
+{
+#ifdef HAVE_FT_GET_BDF_PROPERTY
+ if (face->num_fixed_sizes == 1)
+ {
+ BDF_PropertyRec prop;
+ int rc;
+
+ rc = MY_Get_BDF_Property (face, "PIXEL_SIZE", &prop);
+ if (rc == 0 && prop.type == BDF_PROPERTY_TYPE_INTEGER)
+ return (double) prop.u.integer;
+ }
+#endif
+ return (double) face->available_sizes[i].y_ppem / 64.0;
+}
+
FcPattern *
FcFreeTypeQuery (const FcChar8 *file,
int id,
const FcChar8 *foundry = 0;
int spacing;
TT_OS2 *os2;
+#if HAVE_FT_GET_PS_FONT_INFO
PS_FontInfoRec psfontinfo;
+#endif
+#if HAVE_FT_GET_BDF_PROPERTY
+ BDF_PropertyRec prop;
+#endif
TT_Header *head;
const FcChar8 *exclusiveLang = 0;
FT_SfntName sname;
* Code from g2@magestudios.net (Gerard Escalante)
*/
+#if HAVE_FT_GET_PS_FONT_INFO
if (FT_Get_PS_Font_Info(face, &psfontinfo) == 0)
{
if (weight == -1 && psfontinfo.weight)
if(!foundry)
foundry = FcNoticeFoundry(psfontinfo.notice);
}
+#endif /* HAVE_FT_GET_PS_FONT_INFO */
-#ifdef USE_FTBDF
+#if HAVE_FT_GET_BDF_PROPERTY
/*
* Finally, look for a FOUNDRY BDF property if no other
* mechanism has managed to locate a foundry
if (width == -1)
{
- BDF_PropertyRec prop;
if (MY_Get_BDF_Property(face, "RELATIVE_SETWIDTH", &prop) == 0 &&
(prop.type == BDF_PROPERTY_TYPE_INTEGER ||
prop.type == BDF_PROPERTY_TYPE_CARDINAL))
printf ("\tsetwidth %s maps to %d\n", prop.u.atom, width);
}
}
-
#endif
/*
if (!cs)
goto bail1;
-#ifdef USE_FTBDF
+#if HAVE_FT_GET_BDF_PROPERTY
/* For PCF fonts, override the computed spacing with the one from
the property */
if(MY_Get_BDF_Property(face, "SPACING", &prop) == 0 &&
goto bail2;
if (!FcPatternAddLangSet (pat, FC_LANG, ls))
+ {
+ FcLangSetDestroy (ls);
goto bail2;
+ }
+
+ FcLangSetDestroy (ls);
if (spacing != FC_PROPORTIONAL)
if (!FcPatternAddInteger (pat, FC_SPACING, spacing))
{
for (i = 0; i < face->num_fixed_sizes; i++)
if (!FcPatternAddDouble (pat, FC_PIXEL_SIZE,
- (double) face->available_sizes[i].height))
+ FcGetPixelSize (face, i)))
goto bail1;
if (!FcPatternAddBool (pat, FC_ANTIALIAS, FcFalse))
goto bail1;
-#ifdef USE_FTBDF
+#if HAVE_FT_GET_BDF_PROPERTY
if(face->num_fixed_sizes == 1) {
int rc;
int value;
BDF_PropertyRec prop;
- rc = MY_Get_BDF_Property(face, "PIXEL_SIZE", &prop);
- if(rc == 0 && prop.type == BDF_PROPERTY_TYPE_INTEGER)
- value = prop.u.integer;
- else if(rc == 0 && prop.type == BDF_PROPERTY_TYPE_CARDINAL)
- value = prop.u.cardinal;
- else
- goto nevermind;
- if(value != face->available_sizes[0].height)
- /* ``impossible'' */
- goto nevermind;
-
rc = MY_Get_BDF_Property(face, "POINT_SIZE", &prop);
if(rc == 0 && prop.type == BDF_PROPERTY_TYPE_INTEGER)
value = prop.u.integer;
}
-/*
- * Figure out whether the available freetype has FT_Get_Next_Char
- */
-
-#if FREETYPE_MAJOR > 2
-# define HAS_NEXT_CHAR
-#else
-# if FREETYPE_MAJOR == 2
-# if FREETYPE_MINOR > 0
-# define HAS_NEXT_CHAR
-# else
-# if FREETYPE_MINOR == 0
-# if FREETYPE_PATCH >= 9
-# define HAS_NEXT_CHAR
-# endif
-# endif
-# endif
-# endif
-#endif
-
/*
* For our purposes, this approximation is sufficient
*/
-#ifndef HAS_NEXT_CHAR
-#define FT_Get_First_Char(face, gi) ((*(gi) = 1), 1)
+#if !HAVE_FT_GET_NEXT_CHAR
#define FT_Get_Next_Char(face, ucs4, gi) ((ucs4) >= 0xffffff ? \
(*(gi) = 0), 0 : \
(*(gi) = 1), (ucs4) + 1)
return h;
}
+#if HAVE_FT_HAS_PS_GLYPH_NAMES
/*
* Use Type1 glyph names for fonts which have reliable names
* and which export an Adobe Custom mapping
}
return 0;
}
+#endif
/*
* Map a UCS4 glyph to a glyph index. Use all available encoding
if (glyphindex)
return glyphindex;
}
+#if HAVE_FT_HAS_PS_GLYPH_NAMES
/*
* Check postscript name table if present
*/
return glyphindex;
}
}
+#endif
return 0;
}
FT_Int load_flags = FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH | FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
FT_GlyphSlot slot;
+ /*
+ * For bitmap-only fonts, assume that they're OK.
+ */
+ if ((face->face_flags & FT_FACE_FLAG_SCALABLE) == 0)
+ return FcTrue;
+
/*
* When using scalable fonts, only report those glyphs
* which can be scaled; otherwise those fonts will
return FcFalse;
}
+#define APPROXIMATELY_EQUAL(x,y) (ABS ((x) - (y)) <= MAX (ABS (x), ABS (y)) / 33)
+
FcCharSet *
FcFreeTypeCharSetAndSpacing (FT_Face face, FcBlanks *blanks, int *spacing)
{
int o;
int i;
FT_UInt glyph;
- FT_Pos advance, all_advance = 0;
- FcBool has_advance = FcFalse, fixed_advance = FcTrue;
+ FT_Pos advance, advance_one = 0, advance_two = 0;
+ FcBool has_advance = FcFalse, fixed_advance = FcTrue, dual_advance = FcFalse;
fcs = FcCharSetCreate ();
if (!fcs)
if (!has_advance)
{
has_advance = FcTrue;
- all_advance = advance;
+ advance_one = advance;
}
- else if (advance != all_advance)
- fixed_advance = FcFalse;
+ else if (!APPROXIMATELY_EQUAL (advance, advance_one))
+ {
+ if (fixed_advance)
+ {
+ dual_advance = FcTrue;
+ fixed_advance = FcFalse;
+ advance_two = advance;
+ }
+ else if (!APPROXIMATELY_EQUAL (advance, advance_two))
+ dual_advance = FcFalse;
+ }
+
leaf = FcCharSetFindLeafCreate (fcs, ucs4);
if (!leaf)
goto bail1;
if (!has_advance)
{
has_advance = FcTrue;
- all_advance = advance;
+ advance_one = advance;
}
- else if (advance != all_advance)
- fixed_advance = FcFalse;
+ else if (!APPROXIMATELY_EQUAL (advance, advance_one))
+ {
+ if (fixed_advance)
+ {
+ dual_advance = FcTrue;
+ fixed_advance = FcFalse;
+ advance_two = advance;
+ }
+ else if (!APPROXIMATELY_EQUAL (advance, advance_two))
+ dual_advance = FcFalse;
+ }
+
if (!leaf)
{
leaf = FcCharSetFindLeafCreate (fcs, ucs4);
#endif
}
}
+#if HAVE_FT_HAS_PS_GLYPH_NAMES
/*
* Add mapping from PS glyph names if available
*/
if (!has_advance)
{
has_advance = FcTrue;
- all_advance = advance;
+ advance_one = advance;
}
- else if (advance != all_advance)
- fixed_advance = FcFalse;
+ else if (!APPROXIMATELY_EQUAL (advance, advance_one))
+ {
+ if (fixed_advance)
+ {
+ dual_advance = FcTrue;
+ fixed_advance = FcFalse;
+ advance_two = advance;
+ }
+ else if (!APPROXIMATELY_EQUAL (advance, advance_two))
+ dual_advance = FcFalse;
+ }
leaf = FcCharSetFindLeafCreate (fcs, ucs4);
if (!leaf)
goto bail1;
}
}
}
+#endif
#ifdef CHECK
printf ("%d glyphs %d encoded\n", (int) face->num_glyphs, FcCharSetCount (fcs));
for (ucs4 = 0; ucs4 <= font_max; ucs4++)
#endif
if (fixed_advance)
*spacing = FC_MONO;
+ else if (dual_advance && APPROXIMATELY_EQUAL (2 * MIN (advance_one, advance_two), MAX (advance_one, advance_two)))
+ *spacing = FC_DUAL;
else
*spacing = FC_PROPORTIONAL;
return fcs;