1
0
mirror of https://github.com/pdf2htmlEX/pdf2htmlEX.git synced 2024-08-25 12:57:40 +00:00
pdf2htmlEX/src/ffw.c

306 lines
6.6 KiB
C
Raw Normal View History

/*
2012-09-17 12:40:10 +00:00
* ffw.c: Fontforge wrapper
*
* 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>
#include <math.h>
#include <fontforge.h>
#include <baseviews.h>
2012-09-17 12:40:10 +00:00
#include "ffw.h"
static inline int min(int a, int b)
{
return (a<b)?a:b;
}
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;
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 _;
}
2012-09-17 12:40:10 +00:00
static void dumb_logwarning(const char * format, ...)
{
}
static void dumb_post_error(const char * title, const char * error, ...)
2012-09-03 13:54:48 +00:00
{
}
2012-09-17 12:40:10 +00:00
void ffw_init(int debug)
{
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
2012-09-17 12:40:10 +00:00
if(!debug)
{
//disable error output of Fontforge
ui_interface->logwarning = &dumb_logwarning;
ui_interface->post_error = &dumb_post_error;
}
2012-09-05 17:01:47 +00:00
original_enc = FindOrMakeEncoding("original");
}
2012-09-06 23:55:10 +00:00
2012-09-17 12:40:10 +00:00
void ffw_fin(void)
2012-09-06 23:55:10 +00:00
{
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-17 12:40:10 +00:00
void ffw_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
free(_filename);
2012-09-03 15:19:06 +00:00
if(!font)
err("Cannot load font %s\n", filename);
2012-09-03 15:19:06 +00:00
if(!font->fv)
FVAppend(_FontViewCreate(font));
2012-09-17 14:16:07 +00:00
assert(font->fv);
2012-09-03 15:19:06 +00:00
cur_fv = font->fv;
}
2012-09-17 12:40:10 +00:00
static void ffw_do_reencode(Encoding * encoding, int force)
{
2012-09-05 17:01:47 +00:00
assert(encoding);
if(force)
{
2012-09-03 15:19:06 +00:00
SFForceEncoding(cur_fv->sf, cur_fv->map, encoding);
}
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 15:19:06 +00:00
SFReplaceEncodingBDFProps(cur_fv->sf, cur_fv->map);
}
2012-09-17 12:40:10 +00:00
void ffw_reencode_glyph_order(void)
2012-09-05 17:01:47 +00:00
{
2012-09-17 12:40:10 +00:00
ffw_do_reencode(original_enc, 0);
2012-09-05 17:01:47 +00:00
}
2012-09-17 12:40:10 +00:00
void ffw_reencode(const char * encname, int force)
{
Encoding * enc = FindOrMakeEncoding(encname);
if(!enc)
err("Unknown encoding %s\n", encname);
2012-09-17 12:40:10 +00:00
ffw_do_reencode(enc, force);
}
2012-09-17 12:40:10 +00:00
void ffw_reencode_raw(int32 * mapping, int mapping_len, int force)
2012-09-03 13:54:48 +00:00
{
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-17 12:40:10 +00:00
ffw_do_reencode(enc, force);
}
2012-09-17 12:40:10 +00:00
void ffw_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
{
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-17 12:40:10 +00:00
ffw_do_reencode(enc, force);
2012-09-03 13:54:48 +00:00
}
2012-09-17 12:40:10 +00:00
void ffw_cidflatten(void)
{
2012-09-03 15:19:06 +00:00
if(!cur_fv->sf->cidmaster)
err("Cannot flatten a non-CID font");
2012-09-03 15:19:06 +00:00
SFFlatten(cur_fv->sf->cidmaster);
}
2012-09-17 12:40:10 +00:00
void ffw_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);
free(_);
free(_filename);
if(!r)
err("Cannot save font to %s\n", filename);
}
2012-09-17 12:40:10 +00:00
void ffw_close(void)
{
2012-09-03 15:19:06 +00:00
FontViewClose(cur_fv);
cur_fv = NULL;
}
void ffw_metric(double * ascent, double * descent, int * em_size)
2012-09-16 17:14:58 +00:00
{
2012-09-18 18:13:26 +00:00
SplineFont * sf = cur_fv->sf;
DBounds bb;
2012-09-18 18:13:26 +00:00
SplineFontFindBounds(sf, &bb);
2012-09-18 18:13:26 +00:00
struct pfminfo * info = &sf->pfminfo;
*em_size = sf->ascent + sf->descent;
/*
2012-09-18 18:13:26 +00:00
//debug
2012-09-18 19:20:34 +00:00
printf("bb %lf %lf\n", bb.maxy, bb.miny);
printf("_ %d %d\n", sf->ascent, sf->descent);
printf("win %d %d\n", info->os2_winascent, info->os2_windescent);
printf("%d %d\n", info->winascent_add, info->windescent_add);
printf("typo %d %d\n", info->os2_typoascent, info->os2_typodescent);
printf("%d %d\n", info->typoascent_add, info->typodescent_add);
printf("hhead %d %d\n", info->hhead_ascent, info->hhead_descent);
printf("%d %d\n", info->hheadascent_add, info->hheaddescent_add);
*/
2012-09-18 19:20:34 +00:00
int em = sf->ascent + sf->descent;
if (em > 0)
{
*ascent = ((double)bb.maxy) / em;
*descent = ((double)bb.miny) / em;
}
else
{
*ascent = *descent = 0;
}
2012-09-18 18:13:26 +00:00
2012-09-18 19:26:52 +00:00
int a = bb.maxy;
int d = bb.miny;
sf->ascent = min((int)round(bb.maxy), em);
sf->descent = em - bb.maxy;
2012-09-18 19:26:52 +00:00
info->os2_winascent = a;
info->os2_typoascent = a;
info->hhead_ascent = a;
2012-09-18 18:13:26 +00:00
info->winascent_add = 0;
info->typoascent_add = 0;
info->hheadascent_add = 0;
2012-09-18 19:26:52 +00:00
info->os2_windescent = -d;
info->os2_typodescent = d;
info->hhead_descent = d;
2012-09-18 18:13:26 +00:00
info->windescent_add = 0;
info->typodescent_add = 0;
info->hheaddescent_add = 0;
2012-09-16 17:14:58 +00:00
info->os2_typolinegap = 0;
info->linegap = 0;
2012-09-18 19:20:34 +00:00
info->pfmset = 1;
sf->changed = true;
}
/*
* TODO:bitmap, reference have not been considered in this function
*/
void ffw_set_widths(int * width_list, int mapping_len)
{
SplineFont * sf = cur_fv->sf;
EncMap * map = cur_fv->map;
int i;
int imax = min(mapping_len, map->enccount);
for(i = 0; i < imax; ++i)
{
// TODO why need this
// when width_list[i] == -1, the code itself should be unused.
// but might be reference within ttf etc
if(width_list[i] == -1) continue;
int j = map->map[i];
if(j == -1) continue;
SplineChar * sc = sf->glyphs[j];
if(sc == NULL) continue;
sc->width = width_list[i];
}
}