429faed747
Files correlati : pdflib Ricompilazione Demo : [ ] Commento : Aggiornata PDFlib git-svn-id: svn://10.65.10.50/trunk@17433 c028cbd2-c16b-5b4b-a496-9718f37d4682
534 lines
13 KiB
C
Executable File
534 lines
13 KiB
C
Executable File
/*---------------------------------------------------------------------------*
|
|
| PDFlib - A library for generating PDF on the fly |
|
|
+---------------------------------------------------------------------------+
|
|
| Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. |
|
|
+---------------------------------------------------------------------------+
|
|
| |
|
|
| This software is subject to the PDFlib license. It is NOT in the |
|
|
| public domain. Extended versions and commercial licenses are |
|
|
| available, please check http://www.pdflib.com. |
|
|
| |
|
|
*---------------------------------------------------------------------------*/
|
|
|
|
/* $Id: ft_font.c,v 1.2 2008-10-20 14:33:17 guy Exp $
|
|
*
|
|
* FONT basic font functions
|
|
*
|
|
*/
|
|
|
|
#define FT_FONT_C
|
|
|
|
#include "ft_font.h"
|
|
|
|
|
|
static pdc_error_info fnt_errors[] =
|
|
{
|
|
#define fnt_genInfo 1
|
|
#include "ft_generr.h"
|
|
};
|
|
|
|
#define N_FNT_ERRORS (sizeof fnt_errors / sizeof (pdc_error_info))
|
|
|
|
void
|
|
fnt_register_errtab(pdc_core *pdc)
|
|
{
|
|
pdc_register_errtab(pdc, PDC_ET_FONT, fnt_errors, N_FNT_ERRORS);
|
|
}
|
|
|
|
static void
|
|
fnt_init_font_metric(fnt_font_metric *metric)
|
|
{
|
|
metric->name = NULL;
|
|
metric->flags = 0L;
|
|
metric->type = fnt_unknownType;
|
|
metric->charcoll = (int) cc_none;
|
|
|
|
/*
|
|
* Fill in some reasonable default values in global font info in
|
|
* case they're missing from the metrics data.
|
|
*/
|
|
metric->italicAngle = 0;
|
|
metric->isFixedPitch = pdc_false;
|
|
metric->llx = FNT_MISSING_FONTVAL;
|
|
metric->lly = FNT_MISSING_FONTVAL;
|
|
metric->urx = FNT_MISSING_FONTVAL;
|
|
metric->ury = FNT_MISSING_FONTVAL;
|
|
metric->underlinePosition = -100;
|
|
metric->underlineThickness = FNT_DEFAULT_UNDERLINEWIDTH;
|
|
metric->ascender = FNT_MISSING_FONTVAL;
|
|
metric->descender = FNT_MISSING_FONTVAL;
|
|
metric->capHeight = FNT_MISSING_FONTVAL;
|
|
metric->xHeight = FNT_MISSING_FONTVAL;
|
|
metric->StdHW = 0;
|
|
metric->StdVW = 0;
|
|
|
|
metric->defwidth = FNT_DEFAULT_WIDTH;
|
|
metric->numwidths = 0;
|
|
metric->widths = NULL;
|
|
metric->numinters = 0;
|
|
metric->ciw = NULL;
|
|
metric->numglwidths = 0;
|
|
metric->glw = NULL;
|
|
|
|
}
|
|
|
|
void
|
|
fnt_init_font(fnt_font *font)
|
|
{
|
|
fnt_init_font_metric(&font->m);
|
|
|
|
font->name = NULL;
|
|
font->utf8name = NULL;
|
|
font->filename = NULL;
|
|
font->isstdfont = pdc_false;
|
|
font->ishostfont = pdc_false;
|
|
font->issymbfont = pdc_true;
|
|
font->hasdescr = pdc_false;
|
|
font->vertical = pdc_false;
|
|
font->spacechar = 0;
|
|
font->spacewidth = 0;
|
|
font->linegap = FNT_MISSING_FONTVAL;
|
|
font->weight = 0;
|
|
font->vertical = pdc_false;
|
|
pdc_identity_matrix(&font->matrix);
|
|
font->bbox.llx = 0;
|
|
font->bbox.lly = 0;
|
|
font->bbox.urx = 0;
|
|
font->bbox.ury = 0;
|
|
font->fsscale = 1.0;
|
|
font->enc = pdc_invalidenc;
|
|
font->numglyphs = 0;
|
|
font->numcodes = 0;
|
|
font->gid2code = NULL;
|
|
font->code2gid = NULL;
|
|
font->embedded = pdc_false;
|
|
font->cmapname = NULL;
|
|
font->imgname = NULL;
|
|
font->filelen = 0;
|
|
font->img = NULL;
|
|
}
|
|
|
|
static void
|
|
fnt_cleanup_font_metric(pdc_core *pdc, fnt_font_metric *metric)
|
|
{
|
|
if (metric->name != NULL)
|
|
{
|
|
pdc_free(pdc, metric->name);
|
|
metric->name = NULL;
|
|
}
|
|
|
|
if (metric->widths != NULL)
|
|
{
|
|
pdc_free(pdc, metric->widths);
|
|
metric->widths = NULL;
|
|
}
|
|
|
|
if (metric->ciw != NULL)
|
|
{
|
|
pdc_free(pdc, metric->ciw);
|
|
metric->ciw = NULL;
|
|
}
|
|
|
|
if (metric->glw != NULL)
|
|
{
|
|
pdc_free(pdc, metric->glw);
|
|
metric->glw = NULL;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
void
|
|
fnt_cleanup_fontimg(pdc_core *pdc, fnt_font *font)
|
|
{
|
|
if (font->img != NULL && font->imgname == NULL)
|
|
{
|
|
pdc_free(pdc, font->img);
|
|
font->img = NULL;
|
|
}
|
|
|
|
if (font->imgname != NULL)
|
|
{
|
|
pdc_free(pdc, font->imgname);
|
|
font->imgname = NULL;
|
|
}
|
|
}
|
|
|
|
void
|
|
fnt_cleanup_font(pdc_core *pdc, fnt_font *font)
|
|
{
|
|
int i = 0;
|
|
|
|
(void) i;
|
|
|
|
fnt_cleanup_font_metric(pdc, &font->m);
|
|
|
|
if (font->name != NULL)
|
|
{
|
|
pdc_free(pdc, font->name);
|
|
font->name = NULL;
|
|
}
|
|
|
|
if (font->utf8name != NULL)
|
|
{
|
|
pdc_free(pdc, font->utf8name);
|
|
font->utf8name = NULL;
|
|
}
|
|
|
|
if (font->filename != NULL)
|
|
{
|
|
pdc_free(pdc, font->filename);
|
|
font->filename = NULL;
|
|
}
|
|
|
|
/* delete font specific encoding vector */
|
|
if (font->enc >= pdc_firstvarenc)
|
|
{
|
|
pdc_encodingvector *ev = pdc_get_encoding_vector(pdc, font->enc);
|
|
|
|
if (ev != NULL && ev->flags & PDC_ENC_FONT)
|
|
pdc_remove_encoding_vector(pdc, (int) font->enc);
|
|
}
|
|
|
|
if (font->gid2code != NULL)
|
|
{
|
|
pdc_free(pdc, font->gid2code);
|
|
font->gid2code = NULL;
|
|
}
|
|
|
|
if (font->code2gid != NULL)
|
|
{
|
|
pdc_free(pdc, font->code2gid);
|
|
font->code2gid = NULL;
|
|
}
|
|
|
|
|
|
|
|
if (font->cmapname != NULL)
|
|
{
|
|
pdc_free(pdc, font->cmapname);
|
|
font->cmapname = NULL;
|
|
}
|
|
|
|
|
|
fnt_cleanup_fontimg(pdc, font);
|
|
}
|
|
|
|
/*
|
|
* we assume:
|
|
* code!=0 --> gid=0 --> gid=-1 or code=0 <--> gid=0
|
|
*
|
|
*/
|
|
int
|
|
fnt_get_glyphid(int code, fnt_font *font)
|
|
{
|
|
if (code >= 0 && code < font->numcodes)
|
|
{
|
|
if (font->code2gid != NULL)
|
|
{
|
|
int gid = font->code2gid[code];
|
|
|
|
if (gid)
|
|
return gid;
|
|
}
|
|
else
|
|
{
|
|
/* this is temporary. for Type1 fonts there is no information
|
|
* about glyphs at present. we assume identity code = glyph id.
|
|
*/
|
|
return code;
|
|
}
|
|
}
|
|
|
|
if (!code)
|
|
return 0;
|
|
|
|
return -1;
|
|
}
|
|
|
|
/*
|
|
* we assume:
|
|
* gid!=0 --> code=0 --> code=-1 or gid=0 <--> code=0
|
|
*
|
|
*/
|
|
int
|
|
fnt_get_code(int gid, fnt_font *font)
|
|
{
|
|
if (gid >= 0 && gid < font->numglyphs)
|
|
{
|
|
if (font->gid2code != NULL)
|
|
{
|
|
int code = font->gid2code[gid];
|
|
|
|
if (code)
|
|
return code;
|
|
}
|
|
}
|
|
|
|
if (!gid)
|
|
return 0;
|
|
|
|
return -1;
|
|
}
|
|
|
|
int
|
|
fnt_get_glyphwidth(int code, fnt_font *font)
|
|
{
|
|
int i;
|
|
|
|
if (font->m.widths != NULL)
|
|
{
|
|
if (code < font->m.numwidths)
|
|
return font->m.widths[code];
|
|
}
|
|
else if (font->m.ciw != NULL)
|
|
{
|
|
fnt_interwidth *wd = font->m.ciw;
|
|
int lo = 0;
|
|
int hi = font->m.numinters - 1;
|
|
|
|
while (lo < hi)
|
|
{
|
|
i = (lo + hi) / 2;
|
|
|
|
if (code >= wd[i].startcode && code < wd[i+1].startcode)
|
|
return (int) wd[i].width;
|
|
|
|
if (code < wd[i].startcode)
|
|
hi = i;
|
|
else
|
|
lo = i + 1;
|
|
}
|
|
}
|
|
else if (font->m.glw != NULL)
|
|
{
|
|
for (i = 0; i < font->m.numglwidths; i++)
|
|
{
|
|
if (font->m.glw[i].unicode == (pdc_ushort) code)
|
|
{
|
|
return font->m.glw[i].width;
|
|
}
|
|
}
|
|
}
|
|
|
|
return FNT_MISSING_WIDTH;
|
|
}
|
|
|
|
void
|
|
fnt_font_logg_widths(pdc_core *pdc, fnt_font *font)
|
|
{
|
|
if (font != NULL &&
|
|
pdc_logg_is_enabled(pdc, 2, trc_font))
|
|
{
|
|
int code, width;
|
|
|
|
for (code = 0; code < PDC_NUM_UNIVAL; code++)
|
|
{
|
|
width = fnt_get_glyphwidth(code, font);
|
|
if (width == FNT_MISSING_WIDTH)
|
|
break;
|
|
pdc_logg(pdc,
|
|
"\t\tWidth[%d]: %d\n", code, width);
|
|
}
|
|
}
|
|
}
|
|
|
|
static const pdc_keyconn pdf_fonttype_pdfkeylist[] =
|
|
{
|
|
{"Type0", fnt_Type0},
|
|
{"Type1", fnt_Type1},
|
|
{"MMType1", fnt_MMType1},
|
|
{"TrueType", fnt_TrueType},
|
|
{"CIDFontType2", fnt_CIDFontType2},
|
|
{"Type1C", fnt_Type1C},
|
|
{"CIDFontType0", fnt_CIDFontType0},
|
|
{"CIDFontType0C", fnt_CIDFontType0C},
|
|
{"OpenType", fnt_OpenType},
|
|
{"OpenType", fnt_OpenTypeC},
|
|
{"Type3", fnt_Type3},
|
|
{"(unknown)", fnt_unknownType},
|
|
{NULL, 0}
|
|
};
|
|
|
|
int
|
|
fnt_get_pdf_fonttype_code(const char *typenam)
|
|
{
|
|
int type = pdc_get_keycode(typenam, pdf_fonttype_pdfkeylist);
|
|
return (type != PDC_KEY_NOTFOUND) ? type : fnt_unknownType;
|
|
}
|
|
|
|
const char *
|
|
fnt_get_pdf_fonttype_name(int typecode)
|
|
{
|
|
const char *name = pdc_get_keyword(typecode, pdf_fonttype_pdfkeylist);
|
|
return name ? name : "";
|
|
}
|
|
|
|
static const pdc_keyconn pdf_fonttype_descrkeylist[] =
|
|
{
|
|
/* Acrobat 7 names for comparison */
|
|
{"Composite", fnt_Type0}, /* - */
|
|
{"Type 1", fnt_Type1}, /* Type 1 */
|
|
{"Multiple Master", fnt_MMType1}, /* MM */
|
|
{"TrueType", fnt_TrueType}, /* TrueType */
|
|
{"TrueType (CID)", fnt_CIDFontType2}, /* TrueType (CID) */
|
|
{"Type 1 CFF", fnt_Type1C}, /* Type 1 */
|
|
{"Type 1 (CID)", fnt_CIDFontType0}, /* Type 1 (CID) */
|
|
{"Type 1 CFF (CID)",fnt_CIDFontType0C}, /* Type 1 (CID) */
|
|
{"OpenType", fnt_OpenType}, /* OpenType */
|
|
{"OpenType", fnt_OpenTypeC},
|
|
{"Type 3", fnt_Type3}, /* Type 3 */
|
|
{"(unknown)", fnt_unknownType},
|
|
{NULL, 0}
|
|
};
|
|
|
|
const char *
|
|
fnt_get_pdf_fonttype_desc(int typecode)
|
|
{
|
|
const char *name = pdc_get_keyword(typecode, pdf_fonttype_descrkeylist);
|
|
return name ? name : "";
|
|
}
|
|
|
|
pdc_encodingvector *
|
|
fnt_create_font_ev(pdc_core *pdc, fnt_font *font)
|
|
{
|
|
pdc_encodingvector *ev = NULL;
|
|
char encname[PDC_GEN_BUFSIZE];
|
|
|
|
pdc->uniqueno++;
|
|
pdc_sprintf(pdc, pdc_false, encname, "encoding_%s_%d",
|
|
font->name, pdc->uniqueno);
|
|
ev = pdc_new_encoding(pdc, encname);
|
|
pdc_insert_encoding_vector(pdc, ev);
|
|
font->enc = pdc_find_encoding(pdc, encname);
|
|
ev->flags |= PDC_ENC_FONT;
|
|
|
|
return ev;
|
|
}
|
|
|
|
int
|
|
fnt_check_weight(int weight)
|
|
{
|
|
if (weight == PDC_KEY_NOTFOUND)
|
|
weight = FNT_FW_NORMAL;
|
|
|
|
if (weight > 1000)
|
|
weight = 1000;
|
|
|
|
if (weight <= 10)
|
|
weight *= 100;
|
|
else
|
|
weight = 100 * (weight / 100);
|
|
|
|
return weight;
|
|
}
|
|
|
|
static const pdc_keyconn fnt_fontweight_keylist[] =
|
|
{
|
|
{"none", FNT_FW_DONTCARE},
|
|
{"thin", FNT_FW_THIN},
|
|
{"extralight", FNT_FW_EXTRALIGHT},
|
|
{"ultralight", FNT_FW_ULTRALIGHT},
|
|
{"light", FNT_FW_LIGHT},
|
|
{"normal", FNT_FW_NORMAL},
|
|
{"regular", FNT_FW_REGULAR},
|
|
{"", FNT_FW_REGULAR},
|
|
{"medium", FNT_FW_MEDIUM},
|
|
{"semibold", FNT_FW_SEMIBOLD},
|
|
{"semi", FNT_FW_SEMIBOLD},
|
|
{"demibold", FNT_FW_DEMIBOLD},
|
|
{"bold", FNT_FW_BOLD},
|
|
{"extrabold", FNT_FW_EXTRABOLD},
|
|
{"extra", FNT_FW_EXTRABOLD},
|
|
{"ultrabold", FNT_FW_ULTRABOLD},
|
|
{"heavy", FNT_FW_HEAVY},
|
|
{"black", FNT_FW_BLACK},
|
|
{NULL, 0}
|
|
};
|
|
|
|
int
|
|
fnt_weightname2weight(const char *weightname)
|
|
{
|
|
return pdc_get_keycode_ci(weightname, fnt_fontweight_keylist);
|
|
}
|
|
|
|
const char *
|
|
fnt_weight2weightname(int weight)
|
|
{
|
|
return pdc_get_keyword(weight, fnt_fontweight_keylist);
|
|
}
|
|
|
|
int
|
|
fnt_macfontstyle2weight(int macfontstyle)
|
|
{
|
|
return (macfontstyle & (1<<0)) ? FNT_FW_BOLD : FNT_FW_NORMAL;
|
|
}
|
|
|
|
#define FNT_STEMV_WEIGHT 65.0
|
|
|
|
int
|
|
fnt_weight2stemv(int weight)
|
|
{
|
|
double w = weight / FNT_STEMV_WEIGHT;
|
|
return (int) (FNT_STEMV_MIN + w * w + 0.5);
|
|
}
|
|
|
|
int
|
|
fnt_stemv2weight(int stemv)
|
|
{
|
|
double w;
|
|
int weight = 0;
|
|
|
|
w = (double) (stemv - FNT_STEMV_MIN);
|
|
if (w > 0)
|
|
weight = (int) (FNT_STEMV_WEIGHT * sqrt(w) + 0.5);
|
|
|
|
return weight;
|
|
}
|
|
|
|
void
|
|
fnt_font_logg_protocol(pdc_core *pdc, fnt_font *font)
|
|
{
|
|
if (font != NULL &&
|
|
pdc_logg_is_enabled(pdc, 2, trc_font))
|
|
{
|
|
const char *wname = fnt_weight2weightname(font->weight);
|
|
char dwname[16];
|
|
|
|
dwname[0] = 0;
|
|
if (wname && *wname)
|
|
sprintf(dwname, " (%s)", wname);
|
|
|
|
pdc_logg(pdc,
|
|
"\n"
|
|
"\t\tFont type: %s\n"
|
|
"\t\tFlags: %d\n"
|
|
"\t\tFontBBox: %g,%g %g,%g\n"
|
|
"\t\titalicAngle: %g\n"
|
|
"\t\tisFixedPitch: %d\n"
|
|
"\t\tunderlinePosition: %d\n"
|
|
"\t\tunderlineThickness: %d\n"
|
|
"\t\tcapHeight: %d\n"
|
|
"\t\txHeight: %d\n"
|
|
"\t\tascender: %d\n"
|
|
"\t\tdescender: %d\n"
|
|
"\t\tlinegap: %d\n"
|
|
"\t\tweight: %d%s\n"
|
|
"\t\tStdVW: %d\n"
|
|
"\t\tStdHW: %d\n"
|
|
"\t\tdefWidth: %d\n",
|
|
fnt_get_pdf_fonttype_name(font->m.type),
|
|
font->m.flags,
|
|
font->m.llx, font->m.lly, font->m.urx, font->m.ury,
|
|
font->m.italicAngle, font->m.isFixedPitch,
|
|
font->m.underlinePosition, font->m.underlineThickness,
|
|
font->m.capHeight, font->m.xHeight, font->m.ascender,
|
|
font->m.descender, font->linegap, font->weight,
|
|
dwname,
|
|
font->m.StdVW, font->m.StdHW,
|
|
font->m.defwidth);
|
|
}
|
|
}
|
|
|
|
|