campo-sirio/pdf/font/ft_font.c
guy 3bf951f42c Patch level : 10.0
Files correlati     : pdflib
Ricompilazione Demo : [ ]
Commento            :
Aggiornata pdflib.dll alla versione 7.0.4


git-svn-id: svn://10.65.10.50/trunk@18580 c028cbd2-c16b-5b4b-a496-9718f37d4682
2009-03-23 08:55:58 +00:00

545 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.3 2009-03-23 08:51: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},
{"0", FNT_FW_DONTCARE},
{"100", FNT_FW_THIN},
{"200", FNT_FW_EXTRALIGHT},
{"300", FNT_FW_LIGHT},
{"400", FNT_FW_NORMAL},
{"500", FNT_FW_MEDIUM},
{"600", FNT_FW_SEMIBOLD},
{"700", FNT_FW_BOLD},
{"800", FNT_FW_EXTRABOLD},
{"900", 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);
}
}