along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+#include <assert.h>
#include "../config.h"
#include "gfxdevice.h"
#include "gfxtools.h"
#include "gfxfont.h"
#include "ttf.h"
+#include "mem.h"
+#include "log.h"
static int loadfont_scale = 64;
static int full_unicode = 1;
free(font);
}
+static inline int invalid_unicode(int u)
+{
+ return (u<32 || (u>=0xe000 && u<0xf900));
+}
+void gfxfont_fix_unicode(gfxfont_t*font)
+{
+ int t;
+
+ /* find the current maximum unicode2glyph */
+ int max = 0;
+ for(t=0;t<font->num_glyphs;t++) {
+ int u = font->glyphs[t].unicode;
+ if(u > max)
+ max = u;
+ }
+ char*used = rfx_calloc(max+1);
+
+ /* now, remap all duplicates (and invalid characters) and
+ calculate the new maximum */
+ int remap_pos=0;
+ max = 0;
+ for(t=0;t<font->num_glyphs;t++) {
+ int u = font->glyphs[t].unicode;
+ if(u>=0) {
+ if(used[u] || invalid_unicode(u)) {
+ u = font->glyphs[t].unicode = 0xe000 + remap_pos++;
+ } else {
+ used[u] = 1;
+ }
+ }
+ if(u > max)
+ max = u;
+ }
+ free(used);
+
+ if(!font->unicode2glyph) {
+ /* (re)generate unicode2glyph-to-glyph mapping table by reverse mapping
+ the glyph unicode2glyph's indexes into the mapping table. For collisions,
+ we prefer the smaller unicode2glyph value.*/
+ font->max_unicode = max+1;
+ font->unicode2glyph = malloc(sizeof(font->unicode2glyph[0])*(font->max_unicode));
+ memset(font->unicode2glyph, -1, sizeof(font->unicode2glyph[0])*(font->max_unicode));
+
+ for(t=0;t<font->num_glyphs;t++) {
+ int u = font->glyphs[t].unicode;
+ if(u>=0) {
+ assert(font->unicode2glyph[u]<0); // we took care of duplicates, right?
+ assert(u<font->max_unicode);
+ font->unicode2glyph[u] = t;
+ }
+ }
+ } else {
+ /* add the new glyph indexes (most probably, that's only the remapped values
+ at 0xe000) to the unicode2glyph table. Notice: Unlike glyph2unicode, we don't
+ care about collisions in the unicode2glyph table */
+ int new_max_unicode = max+1;
+ if(font->max_unicode < new_max_unicode) {
+ font->unicode2glyph = rfx_realloc(font->unicode2glyph, sizeof(font->unicode2glyph[0])*(font->max_unicode));
+ memset(font->unicode2glyph+font->max_unicode, -1, sizeof(font->unicode2glyph[0])*(new_max_unicode - font->max_unicode));
+ }
+ for(t=0;t<font->num_glyphs;t++) {
+ int u = font->glyphs[t].unicode;
+ if(u>=0 && font->unicode2glyph[u]<0) {
+ font->unicode2glyph[u] = t;
+ }
+ }
+ font->max_unicode = new_max_unicode;
+ }
+}
+
ttf_t* gfxfont_to_ttf(gfxfont_t*font)
{
ttf_t*ttf = ttf_new();
ttf->glyphs = rfx_calloc(num_glyphs*sizeof(ttfglyph_t));
double scale = 1.0;
int max_unicode = font->max_unicode;
+ int remap_pos=0;
for(t=0;t<font->num_glyphs;t++) {
gfxglyph_t*src = &font->glyphs[t];
ttfglyph_t*dest = &ttf->glyphs[t+offset];
}
}
+ dest->bearing = dest->xmin;
dest->advance = src->advance*scale;
- if(src->unicode > max_unicode)
- max_unicode = src->unicode;
+
+ int u = font->glyphs[t].unicode;
+ if(u > max_unicode)
+ max_unicode = u;
}
ttf->unicode_size = max_unicode+1;
ttf->unicode = rfx_calloc(sizeof(unicode_t)*ttf->unicode_size);
- int remap_pos=0;
- for(t=0;t<font->num_glyphs;t++) {
- gfxglyph_t*src = &font->glyphs[t];
- int u = font->glyphs[t].unicode;
- if(u<32 || (u>=0xe000 && u<0xf900)) {
- u = 0xe000 + remap_pos++;
+
+ if(!font->unicode2glyph) {
+ for(t=0;t<font->num_glyphs;t++) {
+ gfxglyph_t*src = &font->glyphs[t];
+ int u = font->glyphs[t].unicode;
+ if(u<=0)
+ continue;
+ if(u<32) {
+ msg("<warning> gfxfont_to_ttf: glyph %d has an invalid unicode (%d)", t, u);
+ continue;
+ } else if(ttf->unicode[u]) {
+ msg("<warning> gfxfont_to_ttf: glyph %d has a duplicate unicode (%d)", t, u);
+ continue;
+ }
+ if(u<ttf->unicode_size)
+ ttf->unicode[u] = t+offset;
}
- if(u>=0)
- ttf->unicode[u] = t+offset;
- }
- int u;
- for(u=0;u<font->max_unicode;u++) {
- int g = font->unicode2glyph[u];
- if(u<32 || (u>=0xe000 && u<0xf900))
- continue;
- if(g>=0 && !ttf->unicode[u]) {
- ttf->unicode[u] = g+offset;
+ } else {
+ int u;
+ for(u=1;u<font->max_unicode;u++) {
+ int g = font->unicode2glyph[u];
+ if(g>=0 && u<32) {
+ msg("<warning> gfxfont_to_ttf: Font contains an invalid unicode (%d)", u);
+ continue;
+ }
+ if(g>=0 && g<font->num_glyphs && !ttf->unicode[u]) {
+ ttf->unicode[u] = g+offset;
+ }
}
}
+
ttf->ascent = font->ascent;
- ttf->descent = font->descent;
- ttf->lineGap = font->ascent + font->descent;
+ ttf->descent = -font->descent;
+ ttf->lineGap = 0;
- ttf->name = strdup(font->id);
+ ttf->full_name = strdup(font->id);
+ ttf->family_name = strdup(font->id);
+ ttf->subfamily_name = strdup(font->id);
+ ttf->postscript_name = strdup(font->id);
+ ttf->version_string = strdup("Version 1.0");
+ ttf->font_uid = strdup(font->id);
ttf_create_truetype_tables(ttf);
return ttf;
{
ttf_t*ttf = gfxfont_to_ttf(font);
ttf_save(ttf, filename);
+ ttf_destroy(ttf);
+}
+
+void gfxfont_save_eot(gfxfont_t*font, const char*filename)
+{
+ ttf_t*ttf = gfxfont_to_ttf(font);
+ ttf_save_eot(ttf, filename);
+ ttf_destroy(ttf);
}