2012-09-03 12:57:14 +00:00
|
|
|
/*
|
|
|
|
* ff.c
|
|
|
|
*
|
|
|
|
* Processing fonts using Fontforge
|
|
|
|
*
|
|
|
|
* by WangLu
|
|
|
|
* 2012.09.03
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdarg.h>
|
2012-09-05 17:01:47 +00:00
|
|
|
#include <assert.h>
|
2012-09-03 12:57:14 +00:00
|
|
|
|
|
|
|
#include <fontforge.h>
|
|
|
|
#include <baseviews.h>
|
|
|
|
|
|
|
|
#include "ff.h"
|
|
|
|
|
2012-09-05 17:01:47 +00:00
|
|
|
static FontViewBase * cur_fv = NULL;
|
|
|
|
static Encoding * original_enc = NULL;
|
2012-09-06 23:55:10 +00:00
|
|
|
static Encoding * enc_head = NULL;
|
2012-09-03 12:57:14 +00:00
|
|
|
|
|
|
|
static void err(const char * format, ...)
|
|
|
|
{
|
|
|
|
va_list al;
|
|
|
|
va_start(al, format);
|
|
|
|
vfprintf(stderr, format, al);
|
|
|
|
va_end(al);
|
|
|
|
exit(-1);
|
|
|
|
}
|
|
|
|
static char * strcopy(const char * str)
|
|
|
|
{
|
|
|
|
if(str == NULL) return NULL;
|
|
|
|
|
|
|
|
char * _ = strdup(str);
|
|
|
|
if(!_)
|
|
|
|
err("Not enough memory");
|
|
|
|
return _;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int max(int a, int b)
|
|
|
|
{
|
|
|
|
return (a>b) ? a : b;
|
|
|
|
}
|
|
|
|
|
2012-09-03 13:54:48 +00:00
|
|
|
static void dummy(const char * format, ...)
|
|
|
|
{
|
|
|
|
va_list al;
|
|
|
|
va_start(al, format);
|
|
|
|
va_end(al);
|
|
|
|
}
|
|
|
|
|
2012-09-03 12:57:14 +00:00
|
|
|
void ff_init(void)
|
|
|
|
{
|
|
|
|
InitSimpleStuff();
|
|
|
|
if ( default_encoding==NULL )
|
|
|
|
default_encoding=FindOrMakeEncoding("ISO8859-1");
|
|
|
|
if ( default_encoding==NULL )
|
|
|
|
default_encoding=&custom; /* In case iconv is broken */
|
2012-09-03 13:54:48 +00:00
|
|
|
|
|
|
|
//disable error output of Fontforge
|
|
|
|
ui_interface->logwarning = &dummy;
|
2012-09-05 17:01:47 +00:00
|
|
|
|
|
|
|
original_enc = FindOrMakeEncoding("original");
|
2012-09-03 12:57:14 +00:00
|
|
|
}
|
2012-09-06 23:55:10 +00:00
|
|
|
|
|
|
|
void ff_fin(void)
|
|
|
|
{
|
|
|
|
while(enc_head)
|
|
|
|
{
|
|
|
|
Encoding * next = enc_head->next;
|
|
|
|
free(enc_head->enc_name);
|
|
|
|
free(enc_head->unicode);
|
|
|
|
if(enc_head->psnames)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
for(i = 0; i < enc_head->char_cnt; ++i)
|
|
|
|
free(enc_head->psnames[i]);
|
|
|
|
free(enc_head->psnames);
|
|
|
|
}
|
|
|
|
free(enc_head);
|
|
|
|
enc_head = next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-09-03 12:57:14 +00:00
|
|
|
void ff_load_font(const char * filename)
|
|
|
|
{
|
|
|
|
char * _filename = strcopy(filename);
|
2012-09-03 15:19:06 +00:00
|
|
|
SplineFont * font = LoadSplineFont(_filename, 1);
|
2012-09-16 05:55:13 +00:00
|
|
|
|
2012-09-03 12:57:14 +00:00
|
|
|
free(_filename);
|
|
|
|
|
2012-09-03 15:19:06 +00:00
|
|
|
if(!font)
|
2012-09-03 12:57:14 +00:00
|
|
|
err("Cannot load font %s\n", filename);
|
|
|
|
|
2012-09-03 15:19:06 +00:00
|
|
|
if(!font->fv)
|
|
|
|
FVAppend(_FontViewCreate(font));
|
|
|
|
|
|
|
|
cur_fv = font->fv;
|
2012-09-03 12:57:14 +00:00
|
|
|
}
|
|
|
|
|
2012-09-03 14:32:56 +00:00
|
|
|
static void ff_do_reencode(Encoding * encoding, int force)
|
2012-09-03 12:57:14 +00:00
|
|
|
{
|
2012-09-05 17:01:47 +00:00
|
|
|
assert(encoding);
|
|
|
|
|
2012-09-03 12:57:14 +00:00
|
|
|
if(force)
|
|
|
|
{
|
2012-09-03 15:19:06 +00:00
|
|
|
SFForceEncoding(cur_fv->sf, cur_fv->map, encoding);
|
2012-09-03 12:57:14 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-09-03 15:19:06 +00:00
|
|
|
EncMapFree(cur_fv->map);
|
2012-09-05 17:01:47 +00:00
|
|
|
cur_fv->map = EncMapFromEncoding(cur_fv->sf, encoding);
|
|
|
|
}
|
|
|
|
if(cur_fv->normal)
|
|
|
|
{
|
|
|
|
EncMapFree(cur_fv->normal);
|
|
|
|
cur_fv->normal = NULL;
|
2012-09-03 12:57:14 +00:00
|
|
|
}
|
|
|
|
|
2012-09-03 15:19:06 +00:00
|
|
|
SFReplaceEncodingBDFProps(cur_fv->sf, cur_fv->map);
|
2012-09-03 12:57:14 +00:00
|
|
|
}
|
|
|
|
|
2012-09-05 17:01:47 +00:00
|
|
|
void ff_reencode_glyph_order(void)
|
|
|
|
{
|
|
|
|
ff_do_reencode(original_enc, 0);
|
|
|
|
}
|
2012-09-03 14:32:56 +00:00
|
|
|
|
|
|
|
void ff_reencode(const char * encname, int force)
|
|
|
|
{
|
|
|
|
Encoding * enc = FindOrMakeEncoding(encname);
|
|
|
|
if(!enc)
|
|
|
|
err("Unknown encoding %s\n", encname);
|
|
|
|
|
|
|
|
ff_do_reencode(enc, force);
|
|
|
|
}
|
|
|
|
|
2012-09-03 13:54:48 +00:00
|
|
|
void ff_reencode_raw(int32 * mapping, int mapping_len, int force)
|
|
|
|
{
|
|
|
|
Encoding * enc = calloc(1, sizeof(Encoding));
|
|
|
|
enc->only_1byte = enc->has_1byte = true;
|
|
|
|
enc->char_cnt = mapping_len;
|
|
|
|
enc->unicode = (int32_t*)malloc(mapping_len * sizeof(int32_t));
|
|
|
|
memcpy(enc->unicode, mapping, mapping_len * sizeof(int32_t));
|
|
|
|
enc->enc_name = strcopy("");
|
|
|
|
|
2012-09-06 23:55:10 +00:00
|
|
|
enc->next = enc_head;
|
|
|
|
enc_head = enc;
|
|
|
|
|
2012-09-03 14:32:56 +00:00
|
|
|
ff_do_reencode(enc, force);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ff_reencode_raw2(char ** mapping, int mapping_len, int force)
|
|
|
|
{
|
|
|
|
Encoding * enc = calloc(1, sizeof(Encoding));
|
|
|
|
enc->enc_name = strcopy("");
|
|
|
|
enc->char_cnt = mapping_len;
|
|
|
|
enc->unicode = (int32_t*)malloc(mapping_len * sizeof(int32_t));
|
|
|
|
enc->psnames = (char**)calloc(mapping_len, sizeof(char*));
|
|
|
|
int i;
|
|
|
|
for(i = 0; i < mapping_len; ++i)
|
2012-09-03 13:54:48 +00:00
|
|
|
{
|
2012-09-03 14:32:56 +00:00
|
|
|
if(mapping[i])
|
|
|
|
{
|
|
|
|
enc->unicode[i] = UniFromName(mapping[i], ui_none, &custom);
|
|
|
|
enc->psnames[i] = strcopy(mapping[i]);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
enc->unicode[i] = -1;
|
|
|
|
}
|
2012-09-03 13:54:48 +00:00
|
|
|
}
|
|
|
|
|
2012-09-06 23:55:10 +00:00
|
|
|
enc->next = enc_head;
|
|
|
|
enc_head = enc;
|
|
|
|
|
2012-09-03 14:32:56 +00:00
|
|
|
ff_do_reencode(enc, force);
|
2012-09-03 13:54:48 +00:00
|
|
|
}
|
|
|
|
|
2012-09-03 12:57:14 +00:00
|
|
|
void ff_cidflatten(void)
|
|
|
|
{
|
2012-09-03 15:19:06 +00:00
|
|
|
if(!cur_fv->sf->cidmaster)
|
2012-09-03 12:57:14 +00:00
|
|
|
err("Cannot flatten a non-CID font");
|
2012-09-03 15:19:06 +00:00
|
|
|
SFFlatten(cur_fv->sf->cidmaster);
|
2012-09-03 12:57:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ff_save(const char * filename)
|
|
|
|
{
|
|
|
|
char * _filename = strcopy(filename);
|
|
|
|
char * _ = strcopy("");
|
|
|
|
|
2012-09-03 15:19:06 +00:00
|
|
|
int r = GenerateScript(cur_fv->sf, _filename
|
|
|
|
, _, -1, -1, NULL, NULL, cur_fv->map, NULL, ly_fore);
|
2012-09-03 12:57:14 +00:00
|
|
|
|
|
|
|
free(_);
|
|
|
|
free(_filename);
|
|
|
|
|
|
|
|
if(!r)
|
|
|
|
err("Cannot save font to %s\n", filename);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ff_close(void)
|
|
|
|
{
|
2012-09-03 15:19:06 +00:00
|
|
|
FontViewClose(cur_fv);
|
|
|
|
cur_fv = NULL;
|
2012-09-03 12:57:14 +00:00
|
|
|
}
|
|
|
|
|
2012-09-16 17:14:58 +00:00
|
|
|
void ff_metric(int * ascent, int * descent)
|
|
|
|
{
|
|
|
|
*ascent = cur_fv->sf->ascent;
|
|
|
|
*descent = cur_fv->sf->descent;
|
|
|
|
|
|
|
|
cur_fv->sf->pfminfo.os2_winascent = 0;
|
|
|
|
cur_fv->sf->pfminfo.os2_typoascent = 0;
|
|
|
|
cur_fv->sf->pfminfo.hhead_ascent = 0;
|
|
|
|
cur_fv->sf->pfminfo.winascent_add = 0;
|
|
|
|
cur_fv->sf->pfminfo.typoascent_add = 0;
|
|
|
|
cur_fv->sf->pfminfo.hheadascent_add = 0;
|
|
|
|
|
|
|
|
cur_fv->sf->pfminfo.os2_windescent = 0;
|
|
|
|
cur_fv->sf->pfminfo.os2_typodescent = 0;
|
|
|
|
cur_fv->sf->pfminfo.hhead_descent = 0;
|
|
|
|
cur_fv->sf->pfminfo.windescent_add = 0;
|
|
|
|
cur_fv->sf->pfminfo.typodescent_add = 0;
|
|
|
|
cur_fv->sf->pfminfo.hheaddescent_add = 0;
|
|
|
|
}
|
|
|
|
|
2012-09-03 12:57:14 +00:00
|
|
|
int ff_get_em_size(void)
|
|
|
|
{
|
2012-09-03 15:19:06 +00:00
|
|
|
return (cur_fv->sf->pfminfo.os2_typoascent - cur_fv->sf->pfminfo.os2_typodescent);
|
2012-09-03 12:57:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int ff_get_max_ascent(void)
|
|
|
|
{
|
2012-09-03 15:19:06 +00:00
|
|
|
return max(cur_fv->sf->pfminfo.os2_winascent,
|
|
|
|
max(cur_fv->sf->pfminfo.os2_typoascent,
|
|
|
|
cur_fv->sf->pfminfo.hhead_ascent));
|
2012-09-03 12:57:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int ff_get_max_descent(void)
|
|
|
|
{
|
2012-09-03 15:19:06 +00:00
|
|
|
return max(cur_fv->sf->pfminfo.os2_windescent,
|
|
|
|
max(-cur_fv->sf->pfminfo.os2_typodescent,
|
|
|
|
-cur_fv->sf->pfminfo.hhead_descent));
|
2012-09-03 12:57:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ff_set_ascent(int a)
|
|
|
|
{
|
2012-09-03 15:19:06 +00:00
|
|
|
cur_fv->sf->pfminfo.os2_winascent = a;
|
2012-09-16 13:34:07 +00:00
|
|
|
cur_fv->sf->pfminfo.os2_typoascent = a;
|
2012-09-03 15:19:06 +00:00
|
|
|
cur_fv->sf->pfminfo.hhead_ascent = a;
|
2012-09-03 12:57:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ff_set_descent(int d)
|
|
|
|
{
|
2012-09-03 15:19:06 +00:00
|
|
|
cur_fv->sf->pfminfo.os2_windescent = d;
|
2012-09-16 13:34:07 +00:00
|
|
|
cur_fv->sf->pfminfo.os2_typodescent = -d;
|
2012-09-03 15:19:06 +00:00
|
|
|
cur_fv->sf->pfminfo.hhead_descent = -d;
|
2012-09-03 12:57:14 +00:00
|
|
|
}
|
|
|
|
|