Modify init code to handle const data types.
This commit is contained in:
parent
e4ca13ea82
commit
4bc1ebb5ed
|
@ -31,6 +31,10 @@ FONTFAMILY *PSDRV_AFMFontList = NULL;
|
||||||
/* qsort/bsearch callback functions */
|
/* qsort/bsearch callback functions */
|
||||||
typedef int (*compar_callback_fn) (const void *, const void *);
|
typedef int (*compar_callback_fn) (const void *, const void *);
|
||||||
|
|
||||||
|
static VOID SortFontMetrics(AFM *afm, AFMMETRICS *metrics);
|
||||||
|
static VOID CalcWindowsMetrics(AFM *afm);
|
||||||
|
static void PSDRV_ReencodeCharWidths(AFM *afm);
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* IsWinANSI
|
* IsWinANSI
|
||||||
*
|
*
|
||||||
|
@ -94,28 +98,6 @@ inline static BOOL CheckMetrics(const AFMMETRICS *metrics)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
* FreeAFM
|
|
||||||
*
|
|
||||||
* Free an AFM structure and any subsidiary objects that have been allocated.
|
|
||||||
* AFM must have been allocated with HEAP_ZERO_MEMORY.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
static void FreeAFM(AFM *afm)
|
|
||||||
{
|
|
||||||
if (afm->FontName != NULL)
|
|
||||||
HeapFree(PSDRV_Heap, 0, afm->FontName);
|
|
||||||
if (afm->FullName != NULL)
|
|
||||||
HeapFree(PSDRV_Heap, 0, afm->FullName);
|
|
||||||
if (afm->FamilyName != NULL)
|
|
||||||
HeapFree(PSDRV_Heap, 0, afm->FamilyName);
|
|
||||||
if (afm->EncodingScheme != NULL)
|
|
||||||
HeapFree(PSDRV_Heap, 0, afm->EncodingScheme);
|
|
||||||
if (afm->Metrics != NULL)
|
|
||||||
HeapFree(PSDRV_Heap, 0, afm->Metrics);
|
|
||||||
|
|
||||||
HeapFree(PSDRV_Heap, 0, afm);
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************
|
/***********************************************************
|
||||||
*
|
*
|
||||||
|
@ -131,13 +113,14 @@ static BOOL PSDRV_AFMGetCharMetrics(AFM *afm, FILE *fp)
|
||||||
unsigned char line[256], valbuf[256];
|
unsigned char line[256], valbuf[256];
|
||||||
unsigned char *cp, *item, *value, *curpos, *endpos;
|
unsigned char *cp, *item, *value, *curpos, *endpos;
|
||||||
int i;
|
int i;
|
||||||
AFMMETRICS *metric;
|
AFMMETRICS *metric, *retval;
|
||||||
|
|
||||||
afm->Metrics = metric = HeapAlloc( PSDRV_Heap, 0,
|
metric = HeapAlloc( PSDRV_Heap, 0, afm->NumofMetrics * sizeof(AFMMETRICS));
|
||||||
afm->NumofMetrics * sizeof(AFMMETRICS) );
|
|
||||||
if (metric == NULL)
|
if (metric == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
retval = metric;
|
||||||
|
|
||||||
for(i = 0; i < afm->NumofMetrics; i++, metric++) {
|
for(i = 0; i < afm->NumofMetrics; i++, metric++) {
|
||||||
|
|
||||||
*metric = badMetrics;
|
*metric = badMetrics;
|
||||||
|
@ -145,8 +128,7 @@ static BOOL PSDRV_AFMGetCharMetrics(AFM *afm, FILE *fp)
|
||||||
do {
|
do {
|
||||||
if(!fgets(line, sizeof(line), fp)) {
|
if(!fgets(line, sizeof(line), fp)) {
|
||||||
ERR("Unexpected EOF\n");
|
ERR("Unexpected EOF\n");
|
||||||
HeapFree(PSDRV_Heap, 0, afm->Metrics);
|
HeapFree(PSDRV_Heap, 0, retval);
|
||||||
afm->Metrics = NULL;
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
cp = line + strlen(line);
|
cp = line + strlen(line);
|
||||||
|
@ -164,8 +146,7 @@ static BOOL PSDRV_AFMGetCharMetrics(AFM *afm, FILE *fp)
|
||||||
value = strpbrk(item, " \t");
|
value = strpbrk(item, " \t");
|
||||||
if (!value) {
|
if (!value) {
|
||||||
ERR("No whitespace found.\n");
|
ERR("No whitespace found.\n");
|
||||||
HeapFree(PSDRV_Heap, 0, afm->Metrics);
|
HeapFree(PSDRV_Heap, 0, retval);
|
||||||
afm->Metrics = NULL;
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
while(isspace(*value))
|
while(isspace(*value))
|
||||||
|
@ -173,8 +154,7 @@ static BOOL PSDRV_AFMGetCharMetrics(AFM *afm, FILE *fp)
|
||||||
cp = endpos = strchr(value, ';');
|
cp = endpos = strchr(value, ';');
|
||||||
if (!cp) {
|
if (!cp) {
|
||||||
ERR("missing ;, failed. [%s]\n", line);
|
ERR("missing ;, failed. [%s]\n", line);
|
||||||
HeapFree(PSDRV_Heap, 0, afm->Metrics);
|
HeapFree(PSDRV_Heap, 0, retval);
|
||||||
afm->Metrics = NULL;
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
while(isspace(*--cp))
|
while(isspace(*--cp))
|
||||||
|
@ -218,8 +198,7 @@ static BOOL PSDRV_AFMGetCharMetrics(AFM *afm, FILE *fp)
|
||||||
|
|
||||||
if (CheckMetrics(metric) == FALSE) {
|
if (CheckMetrics(metric) == FALSE) {
|
||||||
ERR("Error parsing character metrics\n");
|
ERR("Error parsing character metrics\n");
|
||||||
HeapFree(PSDRV_Heap, 0, afm->Metrics);
|
HeapFree(PSDRV_Heap, 0, retval);
|
||||||
afm->Metrics = NULL;
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,6 +207,10 @@ static BOOL PSDRV_AFMGetCharMetrics(AFM *afm, FILE *fp)
|
||||||
metric->B.urx, metric->B.ury);
|
metric->B.urx, metric->B.ury);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SortFontMetrics(afm, retval);
|
||||||
|
|
||||||
|
afm->Metrics = retval;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,13 +220,13 @@ static BOOL PSDRV_AFMGetCharMetrics(AFM *afm, FILE *fp)
|
||||||
* PSDRV_AFMParse
|
* PSDRV_AFMParse
|
||||||
*
|
*
|
||||||
* Fills out an AFM structure and associated substructures (see psdrv.h)
|
* Fills out an AFM structure and associated substructures (see psdrv.h)
|
||||||
* for a given AFM file. All memory is allocated from the process heap.
|
* for a given AFM file. All memory is allocated from the driver heap.
|
||||||
* Returns a ptr to the AFM structure or NULL on error.
|
* Returns a ptr to the AFM structure or NULL on error.
|
||||||
*
|
*
|
||||||
* This is not complete (we don't handle kerning yet) and not efficient
|
* This is not complete (we don't handle kerning yet) and not efficient
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static AFM *PSDRV_AFMParse(char const *file)
|
static const AFM *PSDRV_AFMParse(char const *file)
|
||||||
{
|
{
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
unsigned char buf[256];
|
unsigned char buf[256];
|
||||||
|
@ -252,6 +235,8 @@ static AFM *PSDRV_AFMParse(char const *file)
|
||||||
unsigned char *cp;
|
unsigned char *cp;
|
||||||
int afmfile = 0;
|
int afmfile = 0;
|
||||||
int c;
|
int c;
|
||||||
|
LPSTR font_name = NULL, full_name = NULL, family_name = NULL,
|
||||||
|
encoding_scheme = NULL;
|
||||||
|
|
||||||
TRACE("parsing '%s'\n", file);
|
TRACE("parsing '%s'\n", file);
|
||||||
|
|
||||||
|
@ -260,7 +245,7 @@ static AFM *PSDRV_AFMParse(char const *file)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
afm = HeapAlloc(PSDRV_Heap, HEAP_ZERO_MEMORY, sizeof(AFM));
|
afm = HeapAlloc(PSDRV_Heap, 0, sizeof(AFM));
|
||||||
if(!afm) {
|
if(!afm) {
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -297,32 +282,23 @@ static AFM *PSDRV_AFMParse(char const *file)
|
||||||
value++;
|
value++;
|
||||||
|
|
||||||
if(!strncmp("FontName", buf, 8)) {
|
if(!strncmp("FontName", buf, 8)) {
|
||||||
afm->FontName = HEAP_strdupA(PSDRV_Heap, 0, value);
|
afm->FontName = font_name = HEAP_strdupA(PSDRV_Heap, 0, value);
|
||||||
if (afm->FontName == NULL) {
|
if (afm->FontName == NULL)
|
||||||
fclose(fp);
|
goto cleanup_fp;
|
||||||
FreeAFM(afm);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!strncmp("FullName", buf, 8)) {
|
if(!strncmp("FullName", buf, 8)) {
|
||||||
afm->FullName = HEAP_strdupA(PSDRV_Heap, 0, value);
|
afm->FullName = full_name = HEAP_strdupA(PSDRV_Heap, 0, value);
|
||||||
if (afm->FullName == NULL) {
|
if (afm->FullName == NULL)
|
||||||
fclose(fp);
|
goto cleanup_fp;
|
||||||
FreeAFM(afm);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!strncmp("FamilyName", buf, 10)) {
|
if(!strncmp("FamilyName", buf, 10)) {
|
||||||
afm->FamilyName = HEAP_strdupA(PSDRV_Heap, 0, value);
|
afm->FamilyName = family_name = HEAP_strdupA(PSDRV_Heap, 0, value);
|
||||||
if (afm->FamilyName == NULL) {
|
if (afm->FamilyName == NULL)
|
||||||
fclose(fp);
|
goto cleanup_fp;
|
||||||
FreeAFM(afm);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -399,21 +375,16 @@ static AFM *PSDRV_AFMParse(char const *file)
|
||||||
|
|
||||||
if(!strncmp("StartCharMetrics", buf, 16)) {
|
if(!strncmp("StartCharMetrics", buf, 16)) {
|
||||||
sscanf(value, "%d", &(afm->NumofMetrics) );
|
sscanf(value, "%d", &(afm->NumofMetrics) );
|
||||||
if (PSDRV_AFMGetCharMetrics(afm, fp) == FALSE) {
|
if (PSDRV_AFMGetCharMetrics(afm, fp) == FALSE)
|
||||||
fclose(fp);
|
goto cleanup_fp;
|
||||||
FreeAFM(afm);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!strncmp("EncodingScheme", buf, 14)) {
|
if(!strncmp("EncodingScheme", buf, 14)) {
|
||||||
afm->EncodingScheme = HEAP_strdupA(PSDRV_Heap, 0, value);
|
afm->EncodingScheme = encoding_scheme =
|
||||||
if (afm->EncodingScheme == NULL) {
|
HEAP_strdupA(PSDRV_Heap, 0, value);
|
||||||
fclose(fp);
|
if (afm->EncodingScheme == NULL)
|
||||||
FreeAFM(afm);
|
goto cleanup_fp;
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -427,21 +398,20 @@ static AFM *PSDRV_AFMParse(char const *file)
|
||||||
|
|
||||||
if(afm->FontName == NULL) {
|
if(afm->FontName == NULL) {
|
||||||
WARN("%s contains no FontName.\n", file);
|
WARN("%s contains no FontName.\n", file);
|
||||||
afm->FontName = HEAP_strdupA(PSDRV_Heap, 0, "nofont");
|
afm->FontName = font_name = HEAP_strdupA(PSDRV_Heap, 0, "nofont");
|
||||||
if (afm->FontName == NULL) {
|
if (afm->FontName == NULL)
|
||||||
FreeAFM(afm);
|
goto cleanup;
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(afm->FullName == NULL)
|
if(afm->FullName == NULL)
|
||||||
afm->FullName = HEAP_strdupA(PSDRV_Heap, 0, afm->FontName);
|
afm->FullName = full_name = HEAP_strdupA(PSDRV_Heap, 0, afm->FontName);
|
||||||
|
|
||||||
if(afm->FamilyName == NULL)
|
if(afm->FamilyName == NULL)
|
||||||
afm->FamilyName = HEAP_strdupA(PSDRV_Heap, 0, afm->FontName);
|
afm->FamilyName = family_name =
|
||||||
if (afm->FullName == NULL || afm->FamilyName == NULL) {
|
HEAP_strdupA(PSDRV_Heap, 0, afm->FontName);
|
||||||
FreeAFM(afm);
|
|
||||||
return NULL;
|
if (afm->FullName == NULL || afm->FamilyName == NULL)
|
||||||
}
|
goto cleanup;
|
||||||
|
|
||||||
if(afm->Ascender == 0.0)
|
if(afm->Ascender == 0.0)
|
||||||
afm->Ascender = afm->FontBBox.ury;
|
afm->Ascender = afm->FontBBox.ury;
|
||||||
|
@ -452,7 +422,32 @@ static AFM *PSDRV_AFMParse(char const *file)
|
||||||
if(afm->Weight == 0)
|
if(afm->Weight == 0)
|
||||||
afm->Weight = FW_NORMAL;
|
afm->Weight = FW_NORMAL;
|
||||||
|
|
||||||
|
CalcWindowsMetrics(afm);
|
||||||
|
|
||||||
|
if (afm->EncodingScheme != NULL &&
|
||||||
|
strcmp(afm->EncodingScheme, "AdobeStandardEncoding") == 0)
|
||||||
|
PSDRV_ReencodeCharWidths(afm);
|
||||||
|
|
||||||
return afm;
|
return afm;
|
||||||
|
|
||||||
|
cleanup_fp:
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
|
||||||
|
if (font_name == NULL)
|
||||||
|
HeapFree(PSDRV_Heap, 0, font_name);
|
||||||
|
if (full_name == NULL)
|
||||||
|
HeapFree(PSDRV_Heap, 0, full_name);
|
||||||
|
if (family_name == NULL)
|
||||||
|
HeapFree(PSDRV_Heap, 0, family_name);
|
||||||
|
if (encoding_scheme == NULL)
|
||||||
|
HeapFree(PSDRV_Heap, 0, encoding_scheme);
|
||||||
|
|
||||||
|
HeapFree(PSDRV_Heap, 0, afm);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************
|
/***********************************************************
|
||||||
|
@ -484,7 +479,7 @@ void PSDRV_FreeAFMList( FONTFAMILY *head )
|
||||||
* Returns ptr to an AFM if name (which is a PS font name) exists in list
|
* Returns ptr to an AFM if name (which is a PS font name) exists in list
|
||||||
* headed by head.
|
* headed by head.
|
||||||
*/
|
*/
|
||||||
AFM *PSDRV_FindAFMinList(FONTFAMILY *head, char *name)
|
const AFM *PSDRV_FindAFMinList(FONTFAMILY *head, char *name)
|
||||||
{
|
{
|
||||||
FONTFAMILY *family;
|
FONTFAMILY *family;
|
||||||
AFMLISTENTRY *afmle;
|
AFMLISTENTRY *afmle;
|
||||||
|
@ -505,7 +500,7 @@ AFM *PSDRV_FindAFMinList(FONTFAMILY *head, char *name)
|
||||||
* Adds an afm to the list whose head is pointed to by head. Creates new
|
* Adds an afm to the list whose head is pointed to by head. Creates new
|
||||||
* family node if necessary and always creates a new AFMLISTENTRY.
|
* family node if necessary and always creates a new AFMLISTENTRY.
|
||||||
*/
|
*/
|
||||||
BOOL PSDRV_AddAFMtoList(FONTFAMILY **head, AFM *afm)
|
BOOL PSDRV_AddAFMtoList(FONTFAMILY **head, const AFM *afm)
|
||||||
{
|
{
|
||||||
FONTFAMILY *family = *head;
|
FONTFAMILY *family = *head;
|
||||||
FONTFAMILY **insert = head;
|
FONTFAMILY **insert = head;
|
||||||
|
@ -574,7 +569,7 @@ BOOL PSDRV_AddAFMtoList(FONTFAMILY **head, AFM *afm)
|
||||||
static void PSDRV_ReencodeCharWidths(AFM *afm)
|
static void PSDRV_ReencodeCharWidths(AFM *afm)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
AFMMETRICS *metric;
|
const AFMMETRICS *metric;
|
||||||
|
|
||||||
for(i = 0; i < 256; i++) {
|
for(i = 0; i < 256; i++) {
|
||||||
if(isalnum(i))
|
if(isalnum(i))
|
||||||
|
@ -649,68 +644,56 @@ static int AFMMetricsByUV(const AFMMETRICS *a, const AFMMETRICS *b)
|
||||||
return a->UV - b->UV;
|
return a->UV - b->UV;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL SortFontMetrics()
|
static VOID SortFontMetrics(AFM *afm, AFMMETRICS *metrics)
|
||||||
{
|
{
|
||||||
FONTFAMILY *family = PSDRV_AFMFontList;
|
INT i;
|
||||||
|
|
||||||
while (family != NULL)
|
TRACE("%s\n", afm->FontName);
|
||||||
|
|
||||||
|
if (strcmp(afm->EncodingScheme, "FontSpecific") != 0)
|
||||||
{
|
{
|
||||||
AFMLISTENTRY *afmle = family->afmlist;
|
PSDRV_IndexGlyphList(); /* enable searching by name index */
|
||||||
|
|
||||||
while (afmle != NULL)
|
for (i = 0; i < afm->NumofMetrics; ++i)
|
||||||
{
|
{
|
||||||
AFM *afm = afmle->afm; /* should always be valid */
|
UNICODEGLYPH ug, *pug;
|
||||||
INT i;
|
|
||||||
|
|
||||||
if (strcmp(afm->EncodingScheme, "FontSpecific") != 0)
|
ug.name = metrics[i].N;
|
||||||
|
|
||||||
|
pug = bsearch(&ug, PSDRV_AGLbyName, PSDRV_AGLbyNameSize,
|
||||||
|
sizeof(UNICODEGLYPH),
|
||||||
|
(compar_callback_fn)UnicodeGlyphByNameIndex);
|
||||||
|
if (pug == NULL)
|
||||||
{
|
{
|
||||||
PSDRV_IndexGlyphList(); /* enable searching by name index */
|
WARN("Glyph '%s' in font '%s' does not have a UV\n",
|
||||||
|
ug.name->sz, afm->FullName);
|
||||||
for (i = 0; i < afm->NumofMetrics; ++i)
|
metrics[i].UV = -1;
|
||||||
{
|
|
||||||
UNICODEGLYPH ug, *pug;
|
|
||||||
|
|
||||||
ug.name = afm->Metrics[i].N;
|
|
||||||
ug.UV = -1;
|
|
||||||
|
|
||||||
pug = bsearch(&ug, PSDRV_AGLbyName, PSDRV_AGLbyNameSize,
|
|
||||||
sizeof(UNICODEGLYPH),
|
|
||||||
(compar_callback_fn)UnicodeGlyphByNameIndex);
|
|
||||||
if (pug == NULL)
|
|
||||||
{
|
|
||||||
WARN("Glyph '%s' in font '%s' does not have a UV\n",
|
|
||||||
ug.name->sz, afm->FullName);
|
|
||||||
afm->Metrics[i].UV = -1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
afm->Metrics[i].UV = pug->UV;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else /* FontSpecific encoding */
|
else
|
||||||
{
|
{
|
||||||
for (i = 0; i < afm->NumofMetrics; ++i)
|
metrics[i].UV = pug->UV;
|
||||||
afm->Metrics[i].UV = afm->Metrics[i].C;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
qsort(afm->Metrics, afm->NumofMetrics, sizeof(AFMMETRICS),
|
|
||||||
(compar_callback_fn)AFMMetricsByUV);
|
|
||||||
|
|
||||||
for (i = 0; i < afm->NumofMetrics; ++i)
|
|
||||||
if (afm->Metrics[i].UV >= 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
afm->NumofMetrics -= i; /* Ignore unencoded glyphs */
|
|
||||||
afm->Metrics += i;
|
|
||||||
|
|
||||||
afmle = afmle->next;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
family = family->next;
|
else /* FontSpecific encoding */
|
||||||
|
{
|
||||||
|
for (i = 0; i < afm->NumofMetrics; ++i)
|
||||||
|
metrics[i].UV = metrics[i].C;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
qsort(metrics, afm->NumofMetrics, sizeof(AFMMETRICS),
|
||||||
|
(compar_callback_fn)AFMMetricsByUV);
|
||||||
|
|
||||||
|
for (i = 0; i < afm->NumofMetrics; ++i) /* count unencoded glyphs */
|
||||||
|
if (metrics[i].UV >= 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (i != 0)
|
||||||
|
{
|
||||||
|
TRACE("Ignoring %i unencoded glyphs\n", i);
|
||||||
|
afm->NumofMetrics -= i;
|
||||||
|
memmove(metrics, metrics + i, afm->NumofMetrics * sizeof(*metrics));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
@ -770,98 +753,78 @@ SHORT PSDRV_CalcAvgCharWidth(const AFM *afm)
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* CalcWindowsMetrics
|
* CalcWindowsMetrics
|
||||||
*
|
*
|
||||||
* Calculates several Windows-specific font metrics for each font. Relies on
|
* Calculates several Windows-specific font metrics for each font.
|
||||||
* the fact that AFMs are allocated with HEAP_ZERO_MEMORY to distinguish
|
|
||||||
* TrueType fonts (when implemented), which already have these filled in.
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static VOID CalcWindowsMetrics()
|
static VOID CalcWindowsMetrics(AFM *afm)
|
||||||
{
|
{
|
||||||
FONTFAMILY *family = PSDRV_AFMFontList;
|
WINMETRICS wm;
|
||||||
|
INT i;
|
||||||
|
|
||||||
while (family != NULL)
|
wm.usUnitsPerEm = 1000; /* for PostScript fonts */
|
||||||
|
wm.sTypoAscender = (SHORT)(afm->Ascender + 0.5);
|
||||||
|
wm.sTypoDescender = (SHORT)(afm->Descender - 0.5);
|
||||||
|
|
||||||
|
wm.sTypoLineGap = 1200 - (wm.sTypoAscender - wm.sTypoDescender);
|
||||||
|
if (wm.sTypoLineGap < 0)
|
||||||
|
wm.sTypoLineGap = 0;
|
||||||
|
|
||||||
|
wm.usWinAscent = 0;
|
||||||
|
wm.usWinDescent = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < afm->NumofMetrics; ++i)
|
||||||
{
|
{
|
||||||
AFMLISTENTRY *afmle = family->afmlist;
|
if (IsWinANSI(afm->Metrics[i].UV) == FALSE)
|
||||||
|
continue;
|
||||||
|
|
||||||
while (afmle != NULL)
|
if (afm->Metrics[i].B.ury > 0)
|
||||||
{
|
{
|
||||||
WINMETRICS wm;
|
USHORT ascent = (USHORT)(afm->Metrics[i].B.ury + 0.5);
|
||||||
AFM *afm = afmle->afm; /* should always be valid */
|
|
||||||
INT i;
|
|
||||||
|
|
||||||
if (afm->WinMetrics.usUnitsPerEm != 0)
|
if (ascent > wm.usWinAscent)
|
||||||
continue; /* TrueType font */
|
wm.usWinAscent = ascent;
|
||||||
|
|
||||||
wm.usUnitsPerEm = 1000; /* for PostScript fonts */
|
|
||||||
wm.sTypoAscender = (SHORT)(afm->Ascender + 0.5);
|
|
||||||
wm.sTypoDescender = (SHORT)(afm->Descender - 0.5);
|
|
||||||
|
|
||||||
wm.sTypoLineGap = 1200 - (wm.sTypoAscender - wm.sTypoDescender);
|
|
||||||
if (wm.sTypoLineGap < 0)
|
|
||||||
wm.sTypoLineGap = 0;
|
|
||||||
|
|
||||||
wm.usWinAscent = 0;
|
|
||||||
wm.usWinDescent = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < afm->NumofMetrics; ++i)
|
|
||||||
{
|
|
||||||
if (IsWinANSI(afm->Metrics[i].UV) == FALSE)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (afm->Metrics[i].B.ury > 0)
|
|
||||||
{
|
|
||||||
USHORT ascent = (USHORT)(afm->Metrics[i].B.ury + 0.5);
|
|
||||||
|
|
||||||
if (ascent > wm.usWinAscent)
|
|
||||||
wm.usWinAscent = ascent;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (afm->Metrics[i].B.lly < 0)
|
|
||||||
{
|
|
||||||
USHORT descent = (USHORT)(-(afm->Metrics[i].B.lly) + 0.5);
|
|
||||||
|
|
||||||
if (descent > wm.usWinDescent)
|
|
||||||
wm.usWinDescent = descent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wm.usWinAscent == 0 && afm->FontBBox.ury > 0)
|
|
||||||
wm.usWinAscent = (USHORT)(afm->FontBBox.ury + 0.5);
|
|
||||||
|
|
||||||
if (wm.usWinDescent == 0 && afm->FontBBox.lly < 0)
|
|
||||||
wm.usWinDescent = (USHORT)(-(afm->FontBBox.lly) + 0.5);
|
|
||||||
|
|
||||||
wm.sAscender = wm.usWinAscent;
|
|
||||||
wm.sDescender = -(wm.usWinDescent);
|
|
||||||
|
|
||||||
wm.sLineGap = 1150 - (wm.sAscender - wm.sDescender);
|
|
||||||
if (wm.sLineGap < 0)
|
|
||||||
wm.sLineGap = 0;
|
|
||||||
|
|
||||||
wm.sAvgCharWidth = PSDRV_CalcAvgCharWidth(afm);
|
|
||||||
|
|
||||||
TRACE("Windows metrics for '%s':\n", afm->FullName);
|
|
||||||
TRACE("\tsAscender = %i\n", wm.sAscender);
|
|
||||||
TRACE("\tsDescender = %i\n", wm.sDescender);
|
|
||||||
TRACE("\tsLineGap = %i\n", wm.sLineGap);
|
|
||||||
TRACE("\tusUnitsPerEm = %u\n", wm.usUnitsPerEm);
|
|
||||||
TRACE("\tsTypoAscender = %i\n", wm.sTypoAscender);
|
|
||||||
TRACE("\tsTypoDescender = %i\n", wm.sTypoDescender);
|
|
||||||
TRACE("\tsTypoLineGap = %i\n", wm.sTypoLineGap);
|
|
||||||
TRACE("\tusWinAscent = %u\n", wm.usWinAscent);
|
|
||||||
TRACE("\tusWinDescent = %u\n", wm.usWinDescent);
|
|
||||||
TRACE("\tsAvgCharWidth = %i\n", wm.sAvgCharWidth);
|
|
||||||
|
|
||||||
afm->WinMetrics = wm;
|
|
||||||
|
|
||||||
/* See afm2c.c and mkagl.c for an explanation of this */
|
|
||||||
/* PSDRV_AFM2C(afm); */
|
|
||||||
|
|
||||||
afmle = afmle->next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
family = family ->next;
|
if (afm->Metrics[i].B.lly < 0)
|
||||||
|
{
|
||||||
|
USHORT descent = (USHORT)(-(afm->Metrics[i].B.lly) + 0.5);
|
||||||
|
|
||||||
|
if (descent > wm.usWinDescent)
|
||||||
|
wm.usWinDescent = descent;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (wm.usWinAscent == 0 && afm->FontBBox.ury > 0)
|
||||||
|
wm.usWinAscent = (USHORT)(afm->FontBBox.ury + 0.5);
|
||||||
|
|
||||||
|
if (wm.usWinDescent == 0 && afm->FontBBox.lly < 0)
|
||||||
|
wm.usWinDescent = (USHORT)(-(afm->FontBBox.lly) + 0.5);
|
||||||
|
|
||||||
|
wm.sAscender = wm.usWinAscent;
|
||||||
|
wm.sDescender = -(wm.usWinDescent);
|
||||||
|
|
||||||
|
wm.sLineGap = 1150 - (wm.sAscender - wm.sDescender);
|
||||||
|
if (wm.sLineGap < 0)
|
||||||
|
wm.sLineGap = 0;
|
||||||
|
|
||||||
|
wm.sAvgCharWidth = PSDRV_CalcAvgCharWidth(afm);
|
||||||
|
|
||||||
|
TRACE("Windows metrics for '%s':\n", afm->FullName);
|
||||||
|
TRACE("\tsAscender = %i\n", wm.sAscender);
|
||||||
|
TRACE("\tsDescender = %i\n", wm.sDescender);
|
||||||
|
TRACE("\tsLineGap = %i\n", wm.sLineGap);
|
||||||
|
TRACE("\tusUnitsPerEm = %u\n", wm.usUnitsPerEm);
|
||||||
|
TRACE("\tsTypoAscender = %i\n", wm.sTypoAscender);
|
||||||
|
TRACE("\tsTypoDescender = %i\n", wm.sTypoDescender);
|
||||||
|
TRACE("\tsTypoLineGap = %i\n", wm.sTypoLineGap);
|
||||||
|
TRACE("\tusWinAscent = %u\n", wm.usWinAscent);
|
||||||
|
TRACE("\tusWinDescent = %u\n", wm.usWinDescent);
|
||||||
|
TRACE("\tsAvgCharWidth = %i\n", wm.sAvgCharWidth);
|
||||||
|
|
||||||
|
afm->WinMetrics = wm;
|
||||||
|
|
||||||
|
/* See afm2c.c and mkagl.c for an explanation of this */
|
||||||
|
/* PSDRV_AFM2C(afm); */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -898,7 +861,7 @@ static BOOL AddBuiltinAFMs()
|
||||||
|
|
||||||
static BOOL PSDRV_ReadAFMDir(const char* afmdir) {
|
static BOOL PSDRV_ReadAFMDir(const char* afmdir) {
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
AFM *afm;
|
const AFM *afm;
|
||||||
|
|
||||||
dir = opendir(afmdir);
|
dir = opendir(afmdir);
|
||||||
if (dir) {
|
if (dir) {
|
||||||
|
@ -919,13 +882,8 @@ static BOOL PSDRV_ReadAFMDir(const char* afmdir) {
|
||||||
TRACE("loading AFM %s\n",afmfn);
|
TRACE("loading AFM %s\n",afmfn);
|
||||||
afm = PSDRV_AFMParse(afmfn);
|
afm = PSDRV_AFMParse(afmfn);
|
||||||
if (afm) {
|
if (afm) {
|
||||||
if(afm->EncodingScheme &&
|
|
||||||
!strcmp(afm->EncodingScheme,"AdobeStandardEncoding")) {
|
|
||||||
PSDRV_ReencodeCharWidths(afm);
|
|
||||||
}
|
|
||||||
if (PSDRV_AddAFMtoList(&PSDRV_AFMFontList, afm) == FALSE) {
|
if (PSDRV_AddAFMtoList(&PSDRV_AFMFontList, afm) == FALSE) {
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
FreeAFM(afm);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -964,13 +922,9 @@ BOOL PSDRV_GetFontMetrics(void)
|
||||||
value_len = sizeof(value);
|
value_len = sizeof(value);
|
||||||
while(!RegEnumValueA(hkey, idx++, key, &key_len, NULL, &type, value, &value_len))
|
while(!RegEnumValueA(hkey, idx++, key, &key_len, NULL, &type, value, &value_len))
|
||||||
{
|
{
|
||||||
AFM* afm = PSDRV_AFMParse(value);
|
const AFM* afm = PSDRV_AFMParse(value);
|
||||||
|
|
||||||
if (afm) {
|
if (afm) {
|
||||||
if(afm->EncodingScheme &&
|
|
||||||
!strcmp(afm->EncodingScheme, "AdobeStandardEncoding")) {
|
|
||||||
PSDRV_ReencodeCharWidths(afm);
|
|
||||||
}
|
|
||||||
if (PSDRV_AddAFMtoList(&PSDRV_AFMFontList, afm) == FALSE) {
|
if (PSDRV_AddAFMtoList(&PSDRV_AFMFontList, afm) == FALSE) {
|
||||||
RegCloseKey(hkey);
|
RegCloseKey(hkey);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -1011,9 +965,6 @@ no_afmfiles:
|
||||||
|
|
||||||
no_afmdirs:
|
no_afmdirs:
|
||||||
|
|
||||||
if (SortFontMetrics() == FALSE)
|
|
||||||
return FALSE;
|
|
||||||
CalcWindowsMetrics();
|
|
||||||
if (AddBuiltinAFMs() == FALSE)
|
if (AddBuiltinAFMs() == FALSE)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
|
|
@ -26,13 +26,13 @@ inline static float round(float f)
|
||||||
|
|
||||||
static void ScaleFont(DC *dc, LOGFONTW *lf, PSDRV_PDEVICE *physDev)
|
static void ScaleFont(DC *dc, LOGFONTW *lf, PSDRV_PDEVICE *physDev)
|
||||||
{
|
{
|
||||||
PSFONT *font = &(physDev->font);
|
PSFONT *font = &(physDev->font);
|
||||||
WINMETRICS *wm = &(font->afm->WinMetrics);
|
const WINMETRICS *wm = &(font->afm->WinMetrics);
|
||||||
TEXTMETRICW *tm = &(font->tm);
|
TEXTMETRICW *tm = &(font->tm);
|
||||||
LONG lfHeight_ds;
|
LONG lfHeight_ds;
|
||||||
USHORT usUnitsPerEm, usWinAscent, usWinDescent;
|
USHORT usUnitsPerEm, usWinAscent, usWinDescent;
|
||||||
SHORT sAscender, sDescender, sLineGap, sTypoAscender;
|
SHORT sAscender, sDescender, sLineGap, sTypoAscender;
|
||||||
SHORT sTypoDescender, sTypoLineGap, sAvgCharWidth;
|
SHORT sTypoDescender, sTypoLineGap, sAvgCharWidth;
|
||||||
|
|
||||||
TRACE("'%s' %li\n", font->afm->FontName, lf->lfHeight);
|
TRACE("'%s' %li\n", font->afm->FontName, lf->lfHeight);
|
||||||
|
|
||||||
|
@ -452,8 +452,8 @@ BOOL PSDRV_SetFont( DC *dc )
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* PSDRV_GetFontMetric
|
* PSDRV_GetFontMetric
|
||||||
*/
|
*/
|
||||||
static UINT PSDRV_GetFontMetric(HDC hdc, AFM *pafm, NEWTEXTMETRICEXW *pTM,
|
static UINT PSDRV_GetFontMetric(HDC hdc, const AFM *pafm,
|
||||||
ENUMLOGFONTEXW *pLF, INT16 size)
|
NEWTEXTMETRICEXW *pTM, ENUMLOGFONTEXW *pLF, INT16 size)
|
||||||
|
|
||||||
{
|
{
|
||||||
DC *dc = DC_GetDCPtr( hdc );
|
DC *dc = DC_GetDCPtr( hdc );
|
||||||
|
|
|
@ -157,7 +157,7 @@ static INT GlyphListSearch(LPCSTR szName, INT loIndex, INT hiIndex)
|
||||||
* necessary, and returns a pointer to it (NULL if unable to add it)
|
* necessary, and returns a pointer to it (NULL if unable to add it)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
GLYPHNAME *PSDRV_GlyphName(LPCSTR szName)
|
const GLYPHNAME *PSDRV_GlyphName(LPCSTR szName)
|
||||||
{
|
{
|
||||||
INT index;
|
INT index;
|
||||||
|
|
||||||
|
|
|
@ -462,7 +462,7 @@ PRINTERINFO *PSDRV_FindPrinterInfo(LPCSTR name)
|
||||||
DWORD type = REG_BINARY, needed, res, dwPaperSize;
|
DWORD type = REG_BINARY, needed, res, dwPaperSize;
|
||||||
PRINTERINFO *pi = PSDRV_PrinterList, **last = &PSDRV_PrinterList;
|
PRINTERINFO *pi = PSDRV_PrinterList, **last = &PSDRV_PrinterList;
|
||||||
FONTNAME *font;
|
FONTNAME *font;
|
||||||
AFM *afm;
|
const AFM *afm;
|
||||||
HANDLE hPrinter;
|
HANDLE hPrinter;
|
||||||
const char *ppd = NULL;
|
const char *ppd = NULL;
|
||||||
char ppdFileName[256];
|
char ppdFileName[256];
|
||||||
|
|
|
@ -19,7 +19,7 @@ typedef struct {
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
LONG UV;
|
LONG UV;
|
||||||
GLYPHNAME *name;
|
const GLYPHNAME *name;
|
||||||
} UNICODEGLYPH;
|
} UNICODEGLYPH;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -36,9 +36,9 @@ typedef struct _tagAFMMETRICS {
|
||||||
int C; /* character */
|
int C; /* character */
|
||||||
LONG UV;
|
LONG UV;
|
||||||
float WX;
|
float WX;
|
||||||
GLYPHNAME *N; /* name */
|
const GLYPHNAME *N; /* name */
|
||||||
AFMBBOX B;
|
AFMBBOX B;
|
||||||
AFMLIGS *L; /* Ligatures */
|
const AFMLIGS *L; /* Ligatures */
|
||||||
} AFMMETRICS;
|
} AFMMETRICS;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -55,10 +55,10 @@ typedef struct {
|
||||||
} WINMETRICS;
|
} WINMETRICS;
|
||||||
|
|
||||||
typedef struct _tagAFM {
|
typedef struct _tagAFM {
|
||||||
char *FontName;
|
LPCSTR FontName;
|
||||||
char *FullName;
|
LPCSTR FullName;
|
||||||
char *FamilyName;
|
LPCSTR FamilyName;
|
||||||
char *EncodingScheme;
|
LPCSTR EncodingScheme;
|
||||||
LONG Weight; /* FW_NORMAL etc. */
|
LONG Weight; /* FW_NORMAL etc. */
|
||||||
float ItalicAngle;
|
float ItalicAngle;
|
||||||
BOOL IsFixedPitch;
|
BOOL IsFixedPitch;
|
||||||
|
@ -73,7 +73,7 @@ typedef struct _tagAFM {
|
||||||
WINMETRICS WinMetrics;
|
WINMETRICS WinMetrics;
|
||||||
float CharWidths[256];
|
float CharWidths[256];
|
||||||
int NumofMetrics;
|
int NumofMetrics;
|
||||||
AFMMETRICS *Metrics;
|
const AFMMETRICS *Metrics;
|
||||||
} AFM; /* CharWidths is a shortcut to the WX values of numbered glyphs */
|
} AFM; /* CharWidths is a shortcut to the WX values of numbered glyphs */
|
||||||
|
|
||||||
/* Note no 'next' in AFM. Use AFMLISTENTRY as a container. This allow more than
|
/* Note no 'next' in AFM. Use AFMLISTENTRY as a container. This allow more than
|
||||||
|
@ -82,7 +82,7 @@ typedef struct _tagAFM {
|
||||||
fonts for each DC (dc->physDev->Fonts) */
|
fonts for each DC (dc->physDev->Fonts) */
|
||||||
|
|
||||||
typedef struct _tagAFMLISTENTRY {
|
typedef struct _tagAFMLISTENTRY {
|
||||||
AFM *afm;
|
const AFM *afm;
|
||||||
struct _tagAFMLISTENTRY *next;
|
struct _tagAFMLISTENTRY *next;
|
||||||
} AFMLISTENTRY;
|
} AFMLISTENTRY;
|
||||||
|
|
||||||
|
@ -218,7 +218,7 @@ typedef struct {
|
||||||
} PSCOLOR;
|
} PSCOLOR;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
AFM *afm;
|
const AFM *afm;
|
||||||
TEXTMETRICW tm;
|
TEXTMETRICW tm;
|
||||||
INT size;
|
INT size;
|
||||||
float scale;
|
float scale;
|
||||||
|
@ -297,8 +297,8 @@ extern void PSDRV_MergeDevmodes(PSDRV_DEVMODEA *dm1, PSDRV_DEVMODEA *dm2,
|
||||||
extern BOOL PSDRV_GetFontMetrics(void);
|
extern BOOL PSDRV_GetFontMetrics(void);
|
||||||
extern PPD *PSDRV_ParsePPD(char *fname);
|
extern PPD *PSDRV_ParsePPD(char *fname);
|
||||||
extern PRINTERINFO *PSDRV_FindPrinterInfo(LPCSTR name);
|
extern PRINTERINFO *PSDRV_FindPrinterInfo(LPCSTR name);
|
||||||
extern AFM *PSDRV_FindAFMinList(FONTFAMILY *head, char *name);
|
extern const AFM *PSDRV_FindAFMinList(FONTFAMILY *head, char *name);
|
||||||
extern BOOL PSDRV_AddAFMtoList(FONTFAMILY **head, AFM *afm);
|
extern BOOL PSDRV_AddAFMtoList(FONTFAMILY **head, const AFM *afm);
|
||||||
extern void PSDRV_FreeAFMList( FONTFAMILY *head );
|
extern void PSDRV_FreeAFMList( FONTFAMILY *head );
|
||||||
|
|
||||||
extern BOOL WINAPI PSDRV_Init(HINSTANCE hinst, DWORD reason, LPVOID reserved);
|
extern BOOL WINAPI PSDRV_Init(HINSTANCE hinst, DWORD reason, LPVOID reserved);
|
||||||
|
@ -425,7 +425,7 @@ extern DWORD PSDRV_DeviceCapabilities(LPSTR lpszDriver, LPCSTR lpszDevice,
|
||||||
LPDEVMODEA lpdm);
|
LPDEVMODEA lpdm);
|
||||||
VOID PSDRV_DrawLine( DC *dc );
|
VOID PSDRV_DrawLine( DC *dc );
|
||||||
INT PSDRV_GlyphListInit();
|
INT PSDRV_GlyphListInit();
|
||||||
GLYPHNAME *PSDRV_GlyphName(LPCSTR szName);
|
const GLYPHNAME *PSDRV_GlyphName(LPCSTR szName);
|
||||||
VOID PSDRV_IndexGlyphList();
|
VOID PSDRV_IndexGlyphList();
|
||||||
BOOL PSDRV_GetTrueTypeMetrics();
|
BOOL PSDRV_GetTrueTypeMetrics();
|
||||||
const AFMMETRICS *PSDRV_UVMetrics(LONG UV, const AFM *afm);
|
const AFMMETRICS *PSDRV_UVMetrics(LONG UV, const AFM *afm);
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "winnt.h"
|
#include "winnt.h"
|
||||||
|
#include "winerror.h"
|
||||||
#include "winreg.h"
|
#include "winreg.h"
|
||||||
#include "psdrv.h"
|
#include "psdrv.h"
|
||||||
#include "debugtools.h"
|
#include "debugtools.h"
|
||||||
|
@ -60,6 +61,16 @@ static TT_Postscript *post;
|
||||||
static TT_OS2 *os2;
|
static TT_OS2 *os2;
|
||||||
static TT_HoriHeader *hhea;
|
static TT_HoriHeader *hhea;
|
||||||
|
|
||||||
|
/* This is now officially a pain in the ass! */
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
LPSTR FontName;
|
||||||
|
LPSTR FullName;
|
||||||
|
LPSTR FamilyName;
|
||||||
|
LPSTR EncodingScheme;
|
||||||
|
} AFMSTRINGS;
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
*
|
*
|
||||||
* FindCharMap
|
* FindCharMap
|
||||||
|
@ -81,7 +92,7 @@ static const char *encoding_names[7] =
|
||||||
"WindowsJohab" /* TT_MS_ID_JOHAB */
|
"WindowsJohab" /* TT_MS_ID_JOHAB */
|
||||||
};
|
};
|
||||||
|
|
||||||
static BOOL FindCharMap(AFM *afm)
|
static BOOL FindCharMap(AFM *afm, AFMSTRINGS *str)
|
||||||
{
|
{
|
||||||
FT_Int i;
|
FT_Int i;
|
||||||
FT_Error error;
|
FT_Error error;
|
||||||
|
@ -115,22 +126,24 @@ static BOOL FindCharMap(AFM *afm)
|
||||||
|
|
||||||
if (charmap->encoding_id < 7)
|
if (charmap->encoding_id < 7)
|
||||||
{
|
{
|
||||||
afm->EncodingScheme = HEAP_strdupA(PSDRV_Heap, 0,
|
str->EncodingScheme = HEAP_strdupA(PSDRV_Heap, 0,
|
||||||
encoding_names[charmap->encoding_id]);
|
encoding_names[charmap->encoding_id]);
|
||||||
if (afm->EncodingScheme == NULL)
|
if (str->EncodingScheme == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
afm->EncodingScheme = HeapAlloc(PSDRV_Heap, 0, /* encoding_id */
|
str->EncodingScheme =
|
||||||
sizeof("WindowsUnknown65535")); /* is a UShort */
|
HeapAlloc(PSDRV_Heap, 0, sizeof("WindowsUnknown65535"));
|
||||||
if (afm->EncodingScheme == NULL)
|
if (str->EncodingScheme == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
sprintf(afm->EncodingScheme, "%s%u", "WindowsUnknown",
|
sprintf(str->EncodingScheme, "%s%u", "WindowsUnknown",
|
||||||
charmap->encoding_id);
|
charmap->encoding_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
afm->EncodingScheme = str->EncodingScheme;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,7 +173,7 @@ static BOOL NameTableString(LPSTR *sz, const FT_SfntName *name)
|
||||||
}
|
}
|
||||||
|
|
||||||
len = name->string_len / 2;
|
len = name->string_len / 2;
|
||||||
s = *sz = HeapAlloc(PSDRV_Heap, 0, len + 1);
|
*sz = s = HeapAlloc(PSDRV_Heap, 0, len + 1);
|
||||||
if (s == NULL)
|
if (s == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
ws = (FT_UShort *)(name->string);
|
ws = (FT_UShort *)(name->string);
|
||||||
|
@ -198,7 +211,7 @@ static BOOL NameTableString(LPSTR *sz, const FT_SfntName *name)
|
||||||
* returns FALSE only in the event of an unexpected error.
|
* returns FALSE only in the event of an unexpected error.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static BOOL ReadNameTable(AFM *afm)
|
static BOOL ReadNameTable(AFM *afm, AFMSTRINGS *str)
|
||||||
{
|
{
|
||||||
FT_UInt numStrings, stringIndex;
|
FT_UInt numStrings, stringIndex;
|
||||||
FT_SfntName name;
|
FT_SfntName name;
|
||||||
|
@ -226,20 +239,23 @@ static BOOL ReadNameTable(AFM *afm)
|
||||||
{
|
{
|
||||||
case TT_NAME_ID_FONT_FAMILY:
|
case TT_NAME_ID_FONT_FAMILY:
|
||||||
|
|
||||||
if (NameTableString(&(afm->FamilyName), &name) == FALSE)
|
if (NameTableString(&(str->FamilyName), &name) == FALSE)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
afm->FamilyName = str->FamilyName;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TT_NAME_ID_FULL_NAME:
|
case TT_NAME_ID_FULL_NAME:
|
||||||
|
|
||||||
if (NameTableString(&(afm->FullName), &name) == FALSE)
|
if (NameTableString(&(str->FullName), &name) == FALSE)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
afm->FullName = str->FullName;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TT_NAME_ID_PS_NAME:
|
case TT_NAME_ID_PS_NAME:
|
||||||
|
|
||||||
if (NameTableString(&(afm->FontName), &name) == FALSE)
|
if (NameTableString(&(str->FontName), &name) == FALSE)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
afm->FontName = str->FontName;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -247,30 +263,6 @@ static BOOL ReadNameTable(AFM *afm)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
* FreeAFM
|
|
||||||
*
|
|
||||||
* Frees an AFM and all subsidiary objects. For this function to work
|
|
||||||
* properly, the AFM must have been allocated with HEAP_ZERO_MEMORY, and the
|
|
||||||
* UNICODEVECTOR and it's associated array of UNICODEGLYPHs must have been
|
|
||||||
* allocated as a single object.
|
|
||||||
*/
|
|
||||||
static void FreeAFM(AFM *afm)
|
|
||||||
{
|
|
||||||
if (afm->FontName != NULL)
|
|
||||||
HeapFree(PSDRV_Heap, 0, afm->FontName);
|
|
||||||
if (afm->FullName != NULL)
|
|
||||||
HeapFree(PSDRV_Heap, 0, afm->FullName);
|
|
||||||
if (afm->FamilyName != NULL)
|
|
||||||
HeapFree(PSDRV_Heap, 0, afm->FamilyName);
|
|
||||||
if (afm->EncodingScheme != NULL)
|
|
||||||
HeapFree(PSDRV_Heap, 0, afm->EncodingScheme);
|
|
||||||
if (afm->Metrics != NULL)
|
|
||||||
HeapFree(PSDRV_Heap, 0, afm->Metrics);
|
|
||||||
|
|
||||||
HeapFree(PSDRV_Heap, 0, afm);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* PSUnits
|
* PSUnits
|
||||||
*
|
*
|
||||||
|
@ -335,14 +327,13 @@ static BOOL ReadMetricsTables(AFM *afm)
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* ReadCharMetrics
|
* ReadCharMetrics
|
||||||
*
|
*
|
||||||
* Reads metrics for each glyph in a TrueType font. Since FreeAFM will try to
|
* Reads metrics for each glyph in a TrueType font.
|
||||||
* free afm->Metrics and afm->Encoding if they are non-NULL, don't free them
|
|
||||||
* in the event of an error.
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static BOOL ReadCharMetrics(AFM *afm)
|
static AFMMETRICS *ReadCharMetrics(AFM *afm)
|
||||||
{
|
{
|
||||||
FT_ULong charcode, index;
|
FT_ULong charcode, index;
|
||||||
|
AFMMETRICS *metrics;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* There does not seem to be an easy way to get the number of characters
|
* There does not seem to be an easy way to get the number of characters
|
||||||
|
@ -356,9 +347,9 @@ static BOOL ReadCharMetrics(AFM *afm)
|
||||||
|
|
||||||
afm->NumofMetrics = index;
|
afm->NumofMetrics = index;
|
||||||
|
|
||||||
afm->Metrics = HeapAlloc(PSDRV_Heap, 0, index * sizeof(AFMMETRICS));
|
metrics = HeapAlloc(PSDRV_Heap, 0, index * sizeof(AFMMETRICS));
|
||||||
if (afm->Metrics == NULL)
|
if (metrics == NULL)
|
||||||
return FALSE;
|
return NULL;
|
||||||
|
|
||||||
for (charcode = 0, index = 0; charcode <= 65536; ++charcode)
|
for (charcode = 0, index = 0; charcode <= 65536; ++charcode)
|
||||||
{
|
{
|
||||||
|
@ -376,14 +367,14 @@ static BOOL ReadCharMetrics(AFM *afm)
|
||||||
if (error != FT_Err_Ok)
|
if (error != FT_Err_Ok)
|
||||||
{
|
{
|
||||||
ERR("%s returned %i\n", "FT_Load_Glyph", error);
|
ERR("%s returned %i\n", "FT_Load_Glyph", error);
|
||||||
return FALSE;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
error = FT_Get_Glyph(face->glyph, &glyph);
|
error = FT_Get_Glyph(face->glyph, &glyph);
|
||||||
if (error != FT_Err_Ok)
|
if (error != FT_Err_Ok)
|
||||||
{
|
{
|
||||||
ERR("%s returned %i\n", "FT_Get_Glyph", error);
|
ERR("%s returned %i\n", "FT_Get_Glyph", error);
|
||||||
return FALSE;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
FT_Glyph_Get_CBox(glyph, ft_glyph_bbox_unscaled, &bbox);
|
FT_Glyph_Get_CBox(glyph, ft_glyph_bbox_unscaled, &bbox);
|
||||||
|
@ -392,26 +383,26 @@ static BOOL ReadCharMetrics(AFM *afm)
|
||||||
if (error != FT_Err_Ok)
|
if (error != FT_Err_Ok)
|
||||||
{
|
{
|
||||||
ERR("%s returned %i\n", "FT_Get_Glyph_Name", error);
|
ERR("%s returned %i\n", "FT_Get_Glyph_Name", error);
|
||||||
return FALSE;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
afm->Metrics[index].N = PSDRV_GlyphName(buffer);
|
metrics[index].N = PSDRV_GlyphName(buffer);
|
||||||
if (afm->Metrics[index].N == NULL)
|
if (metrics[index].N == NULL)
|
||||||
return FALSE;
|
goto cleanup;;
|
||||||
|
|
||||||
afm->Metrics[index].C = charcode;
|
metrics[index].C = charcode;
|
||||||
afm->Metrics[index].UV = charcode;
|
metrics[index].UV = charcode;
|
||||||
afm->Metrics[index].WX = PSUnits(face->glyph->metrics.horiAdvance);
|
metrics[index].WX = PSUnits(face->glyph->metrics.horiAdvance);
|
||||||
afm->Metrics[index].B.llx = PSUnits(bbox.xMin);
|
metrics[index].B.llx = PSUnits(bbox.xMin);
|
||||||
afm->Metrics[index].B.lly = PSUnits(bbox.yMin);
|
metrics[index].B.lly = PSUnits(bbox.yMin);
|
||||||
afm->Metrics[index].B.urx = PSUnits(bbox.xMax);
|
metrics[index].B.urx = PSUnits(bbox.xMax);
|
||||||
afm->Metrics[index].B.ury = PSUnits(bbox.yMax);
|
metrics[index].B.ury = PSUnits(bbox.yMax);
|
||||||
afm->Metrics[index].L = NULL;
|
metrics[index].L = NULL;
|
||||||
|
|
||||||
TRACE("Metrics for '%s' WX = %f B = %f,%f - %f,%f\n",
|
TRACE("Metrics for '%s' WX = %f B = %f,%f - %f,%f\n",
|
||||||
afm->Metrics[index].N->sz, afm->Metrics[index].WX,
|
metrics[index].N->sz, metrics[index].WX,
|
||||||
afm->Metrics[index].B.llx, afm->Metrics[index].B.lly,
|
metrics[index].B.llx, metrics[index].B.lly,
|
||||||
afm->Metrics[index].B.urx, afm->Metrics[index].B.ury);
|
metrics[index].B.urx, metrics[index].B.ury);
|
||||||
|
|
||||||
if (charcode == 0x0048) /* 'H' */
|
if (charcode == 0x0048) /* 'H' */
|
||||||
afm->CapHeight = PSUnits(bbox.yMax);
|
afm->CapHeight = PSUnits(bbox.yMax);
|
||||||
|
@ -421,7 +412,12 @@ static BOOL ReadCharMetrics(AFM *afm)
|
||||||
++index;
|
++index;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return metrics;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
|
||||||
|
HeapFree(PSDRV_Heap, 0, metrics);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
@ -429,11 +425,13 @@ static BOOL ReadCharMetrics(AFM *afm)
|
||||||
*
|
*
|
||||||
* Fills in AFM structure for opened TrueType font file. Returns FALSE only on
|
* Fills in AFM structure for opened TrueType font file. Returns FALSE only on
|
||||||
* an unexpected error (memory allocation failure or FreeType error); otherwise
|
* an unexpected error (memory allocation failure or FreeType error); otherwise
|
||||||
* returns TRUE. Leaves it to the caller (ReadTrueTypeFile) to clean up.
|
* returns TRUE.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static BOOL ReadTrueTypeAFM(AFM *afm)
|
static BOOL ReadTrueTypeAFM(AFM *afm)
|
||||||
{
|
{
|
||||||
|
AFMSTRINGS str = { NULL, NULL, NULL, NULL };
|
||||||
|
AFMMETRICS *metrics;
|
||||||
|
|
||||||
if ((face->face_flags & REQUIRED_FACE_FLAGS) != REQUIRED_FACE_FLAGS)
|
if ((face->face_flags & REQUIRED_FACE_FLAGS) != REQUIRED_FACE_FLAGS)
|
||||||
{
|
{
|
||||||
|
@ -441,7 +439,7 @@ static BOOL ReadTrueTypeAFM(AFM *afm)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FindCharMap(afm) == FALSE)
|
if (FindCharMap(afm, &str) == FALSE)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (charmap == NULL)
|
if (charmap == NULL)
|
||||||
|
@ -452,13 +450,22 @@ static BOOL ReadTrueTypeAFM(AFM *afm)
|
||||||
|
|
||||||
TRACE("Using encoding '%s'\n", afm->EncodingScheme);
|
TRACE("Using encoding '%s'\n", afm->EncodingScheme);
|
||||||
|
|
||||||
if (ReadNameTable(afm) == FALSE)
|
if (ReadNameTable(afm, &str) == FALSE)
|
||||||
|
{
|
||||||
|
if (str.FontName != NULL) HeapFree(PSDRV_Heap, 0, str.FontName);
|
||||||
|
if (str.FullName != NULL) HeapFree(PSDRV_Heap, 0, str.FullName);
|
||||||
|
if (str.FamilyName != NULL) HeapFree(PSDRV_Heap, 0, str.FamilyName);
|
||||||
|
HeapFree(PSDRV_Heap, 0, str.EncodingScheme);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
if (afm->FamilyName == NULL || afm->FullName == NULL ||
|
if (str.FamilyName == NULL || str.FullName == NULL || str.FontName == NULL)
|
||||||
afm->FontName == NULL)
|
|
||||||
{
|
{
|
||||||
WARN("Required strings missing from font\n");
|
WARN("Required strings missing from font\n");
|
||||||
|
if (str.FontName != NULL) HeapFree(PSDRV_Heap, 0, str.FontName);
|
||||||
|
if (str.FullName != NULL) HeapFree(PSDRV_Heap, 0, str.FullName);
|
||||||
|
if (str.FamilyName != NULL) HeapFree(PSDRV_Heap, 0, str.FamilyName);
|
||||||
|
HeapFree(PSDRV_Heap, 0, str.EncodingScheme);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -468,14 +475,31 @@ static BOOL ReadTrueTypeAFM(AFM *afm)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ReadCharMetrics(afm) == FALSE)
|
afm->Metrics = metrics = ReadCharMetrics(afm);
|
||||||
|
if (metrics == NULL)
|
||||||
|
{
|
||||||
|
HeapFree(PSDRV_Heap, 0, str.FontName);
|
||||||
|
HeapFree(PSDRV_Heap, 0, str.FullName);
|
||||||
|
HeapFree(PSDRV_Heap, 0, str.FamilyName);
|
||||||
|
HeapFree(PSDRV_Heap, 0, str.EncodingScheme);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/* Can't do this check until character metrics are read */
|
/* Can't do this check until character metrics are read */
|
||||||
|
|
||||||
if (afm->WinMetrics.sAvgCharWidth == 0)
|
if (afm->WinMetrics.sAvgCharWidth == 0)
|
||||||
afm->WinMetrics.sAvgCharWidth = PSDRV_CalcAvgCharWidth(afm);
|
afm->WinMetrics.sAvgCharWidth = PSDRV_CalcAvgCharWidth(afm);
|
||||||
|
|
||||||
|
if (PSDRV_AddAFMtoList(&PSDRV_AFMFontList, afm) == FALSE)
|
||||||
|
{
|
||||||
|
HeapFree(PSDRV_Heap, 0, str.FontName);
|
||||||
|
HeapFree(PSDRV_Heap, 0, str.FullName);
|
||||||
|
HeapFree(PSDRV_Heap, 0, str.FamilyName);
|
||||||
|
HeapFree(PSDRV_Heap, 0, str.EncodingScheme);
|
||||||
|
HeapFree(PSDRV_Heap, 0, metrics);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -490,7 +514,7 @@ static BOOL ReadTrueTypeAFM(AFM *afm)
|
||||||
static BOOL ReadTrueTypeFile(LPCSTR filename)
|
static BOOL ReadTrueTypeFile(LPCSTR filename)
|
||||||
{
|
{
|
||||||
FT_Error error;
|
FT_Error error;
|
||||||
AFM *afm;
|
AFM *afm;
|
||||||
|
|
||||||
TRACE("'%s'\n", filename);
|
TRACE("'%s'\n", filename);
|
||||||
|
|
||||||
|
@ -499,7 +523,6 @@ static BOOL ReadTrueTypeFile(LPCSTR filename)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
error = FT_New_Face(library, filename, 0, &face);
|
error = FT_New_Face(library, filename, 0, &face);
|
||||||
|
|
||||||
if (error != FT_Err_Ok)
|
if (error != FT_Err_Ok)
|
||||||
{
|
{
|
||||||
WARN("FreeType error %i opening '%s'\n", error, filename);
|
WARN("FreeType error %i opening '%s'\n", error, filename);
|
||||||
|
@ -509,7 +532,7 @@ static BOOL ReadTrueTypeFile(LPCSTR filename)
|
||||||
|
|
||||||
if (ReadTrueTypeAFM(afm) == FALSE)
|
if (ReadTrueTypeAFM(afm) == FALSE)
|
||||||
{
|
{
|
||||||
FreeAFM(afm);
|
HeapFree(PSDRV_Heap, 0, afm);
|
||||||
FT_Done_Face(face);
|
FT_Done_Face(face);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -518,22 +541,16 @@ static BOOL ReadTrueTypeFile(LPCSTR filename)
|
||||||
if (error != FT_Err_Ok)
|
if (error != FT_Err_Ok)
|
||||||
{
|
{
|
||||||
ERR("%s returned %i\n", "FT_Done_Face", error);
|
ERR("%s returned %i\n", "FT_Done_Face", error);
|
||||||
FreeAFM(afm);
|
HeapFree(PSDRV_Heap, 0, afm);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (afm->Metrics == NULL) /* last element to be set */
|
if (afm->Metrics == NULL) /* last element to be set */
|
||||||
{
|
{
|
||||||
FreeAFM(afm);
|
HeapFree(PSDRV_Heap, 0, afm);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PSDRV_AddAFMtoList(&PSDRV_AFMFontList, afm) == FALSE)
|
|
||||||
{
|
|
||||||
FreeAFM(afm);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -556,8 +573,8 @@ BOOL PSDRV_GetTrueTypeMetrics(void)
|
||||||
CHAR keybuf[256], namebuf[256];
|
CHAR keybuf[256], namebuf[256];
|
||||||
INT i = 0;
|
INT i = 0;
|
||||||
FT_Error error;
|
FT_Error error;
|
||||||
HKEY hkey;
|
HKEY hkey;
|
||||||
DWORD type, key_len, name_len;
|
DWORD type, key_len, name_len;
|
||||||
|
|
||||||
error = FT_Init_FreeType(&library);
|
error = FT_Init_FreeType(&library);
|
||||||
if (error != FT_Err_Ok)
|
if (error != FT_Err_Ok)
|
||||||
|
@ -566,13 +583,16 @@ BOOL PSDRV_GetTrueTypeMetrics(void)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\Wine\\Config\\TrueType Font Directories",
|
if(RegOpenKeyExA(HKEY_LOCAL_MACHINE,
|
||||||
0, KEY_READ, &hkey))
|
"Software\\Wine\\Wine\\Config\\TrueType Font Directories",
|
||||||
|
0, KEY_READ, &hkey) != ERROR_SUCCESS)
|
||||||
goto no_metrics;
|
goto no_metrics;
|
||||||
|
|
||||||
key_len = sizeof(keybuf);
|
key_len = sizeof(keybuf);
|
||||||
name_len = sizeof(namebuf);
|
name_len = sizeof(namebuf);
|
||||||
while(!RegEnumValueA(hkey, i++, keybuf, &key_len, NULL, &type, namebuf, &name_len))
|
|
||||||
|
while(RegEnumValueA(hkey, i++, keybuf, &key_len, NULL, &type, namebuf,
|
||||||
|
&name_len) == ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
struct dirent *dent;
|
struct dirent *dent;
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
|
@ -626,9 +646,11 @@ BOOL PSDRV_GetTrueTypeMetrics(void)
|
||||||
key_len = sizeof(keybuf);
|
key_len = sizeof(keybuf);
|
||||||
name_len = sizeof(namebuf);
|
name_len = sizeof(namebuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
RegCloseKey(hkey);
|
RegCloseKey(hkey);
|
||||||
|
|
||||||
no_metrics:
|
no_metrics:
|
||||||
|
|
||||||
FT_Done_FreeType(library);
|
FT_Done_FreeType(library);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue