Windows: fontname to ttf filename

169 views
Skip to first unread message

Mirco

unread,
Jul 1, 2009, 4:04:05 AM7/1/09
to libHaru
Hello,

I have a question about font's. If you don't use one of the 14 default
fonts, you must first load the font with HPDF_LoadTTFontFromFile and
later on use the the font with HPDF_GetFont.

I'm working under Windows in Delphi and I have a fontname 'Verdana'.
How do I know where the TTF is located of this font so I can call the
HPDF_LoadTTFontFromFile function ?

Regards,
Mirco

Antony Dovgal

unread,
Jul 1, 2009, 4:43:09 AM7/1/09
to lib...@googlegroups.com

Look for verdana.ttf somewhere in C:/Windows dir.

--
Wbr,
Antony Dovgal
---
http://pinba.org - realtime statistics for PHP

Werner Smekal

unread,
Jul 1, 2009, 5:02:14 AM7/1/09
to lib...@googlegroups.com
Hi,

On 01.07.2009, at 10:43, Antony Dovgal wrote:

>
> On 01.07.2009 12:04, Mirco wrote:
>> Hello,
>>
>> I have a question about font's. If you don't use one of the 14
>> default
>> fonts, you must first load the font with HPDF_LoadTTFontFromFile and
>> later on use the the font with HPDF_GetFont.
>>
>> I'm working under Windows in Delphi and I have a fontname 'Verdana'.
>> How do I know where the TTF is located of this font so I can call the
>> HPDF_LoadTTFontFromFile function ?
>
> Look for verdana.ttf somewhere in C:/Windows dir.

Usually all fonts are placed in C:\Windows\Fonts . But you can load
fonts from any place (e.g. same directory if you place it there).

Werner

Luis Guillermo Dangel

unread,
Jul 1, 2009, 10:18:15 PM7/1/09
to lib...@googlegroups.com
All Windows fonts names and their respective TTF file are stored in the windows registry.

For windows ME, 98 and 95  HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Fonts

For all the others HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Fonts

Hope this helps

Luis

Mirco

unread,
Jul 3, 2009, 9:31:08 AM7/3/09
to libHaru
> All Windows fonts names and their respective TTF file are stored in the
> windows registry.
>
> For windows ME, 98 and 95
> HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Fonts
>
> For all the others HKEY_LOCAL_MACHINE\Software\Microsoft\Windows
> NT\CurrentVersion\Fonts

Finally I got it working, using above registry keys.
I had to extend the libhpdf.dll with a specific function for just
extracting fontdata from a TTF file

I have uploaded a Delphi demo under the name WindowsFonts.zip.
Attention: This zip contains a modified libhpdf.dll.
In the zip the acp_getfontfileinfo.c is the file I added to the
makefile of libhpdf.dll

The function I created:
#include "hpdf_conf.h"
#include "hpdf_mmgr.h"
#include "hpdf_streams.h"
#include "hpdf_fontdef.h"
#include "hpdf.h"
#include "hpdf_utils.h"

HPDF_EXPORT(int)
ACP_GetFontFileInfo_TT(const char *file_name,
char *font_name, unsigned int
font_name_len,
int *bold,
int *italic)
{
HPDF_Error_Rec mmgr_error;
HPDF_MMgr mmgr;
HPDF_Stream font_data;
HPDF_FontDef def;
int ret;
int i;

HPDF_PTRACE ((" ACP_GetFontFileInfo_TT - "));
HPDF_PTRACE ((file_name));
HPDF_PTRACE (("\n"));

HPDF_Error_Init (&mmgr_error, NULL);
mmgr = NULL;
font_data = NULL;
def = NULL;
ret = 0;

mmgr = HPDF_MMgr_New (&mmgr_error, 0, NULL, NULL);
if (mmgr)
{
font_data = HPDF_FileReader_New (mmgr, file_name);
if (HPDF_Stream_Validate (font_data))
{
def = HPDF_TTFontDef_Load (mmgr, font_data, 0);
if (def)
{
i=0;
while(font_name_len > 0)
{
font_name[i] = def->base_font[i];
if (font_name[i] == '\0') break;

font_name_len--;
i++;
}

if (def->flags & HPDF_FONT_FOURCE_BOLD)
*bold = 1;
else
*bold = 0;

if (def->flags & HPDF_FONT_ITALIC)
*italic = 1;
else
*italic = 0;

ret = 1;
}
}
}
HPDF_MMgr_Free(mmgr);

return ret;
}

Mirco

unread,
Jul 3, 2009, 9:46:15 AM7/3/09
to libHaru
>                     def = HPDF_TTFontDef_Load (mmgr, font_data, 0);
>                     if (def)
>                         {

At this point the font_data stream is automatically closed by
HPDF_TTFontDef_Load because the embedded parameter is false. It took
me half a day to figure out why I got memory exceptions when I used
HPDF_Stream_Free (font_data);

Maybe someone can change this behaviour, it's just not logical to
automatically close a stream.

Regards,
Mirco

Antony Dovgal

unread,
Jul 3, 2009, 9:48:42 AM7/3/09
to lib...@googlegroups.com

I can take a look at it, but I need to know at least which file you're talking about.
A line number would be also good to know.

Mirco

unread,
Jul 3, 2009, 10:00:43 AM7/3/09
to libHaru
File hpdf_doc.c
line 1461 (starting point)
line 1538 (starting point)

File hpdf_fontdef_tt.c
line 243
line 298
line 326
line 376
line 402
line 474

But be carefull, it seems like it's designed to automatically close
the stream (or not). I think it's a design failure.

Regards,
Mirco

Antony Dovgal

unread,
Jul 3, 2009, 10:04:39 AM7/3/09
to lib...@googlegroups.com
On 03.07.2009 18:00, Mirco wrote:
> File hpdf_doc.c
> line 1461 (starting point)
> line 1538 (starting point)
>
> File hpdf_fontdef_tt.c
> line 243
> line 298
> line 326
> line 376
> line 402
> line 474
>
> But be carefull, it seems like it's designed to automatically close
> the stream (or not). I think it's a design failure.

I truly do not understand what you're talking about.
Please point me to the problem in the code below:

def = HPDF_Type1FontDef_Load (pdf->mmgr, afmdata, pfmdata);
if (def) {
HPDF_FontDef tmpdef = HPDF_Doc_FindFontDef (pdf, def->base_font);
if (tmpdef) {
HPDF_FontDef_Free (def);
HPDF_SetError (&pdf->error, HPDF_FONT_EXISTS, 0);
return NULL;
}

if (HPDF_List_Add (pdf->fontdef_list, def) != HPDF_OK) {
HPDF_FontDef_Free (def);
return NULL;
}
return def->base_font;
}
return NULL;

Mirco

unread,
Jul 6, 2009, 4:24:23 AM7/6/09
to libHaru
Well,

1) In hpdf_doc.c a stream is created:
HPDF_EXPORT(const char*)
HPDF_LoadTTFontFromFile (HPDF_Doc pdf,
const char *file_name,
HPDF_BOOL embedding)
{
HPDF_Stream font_data;
const char *ret;

HPDF_PTRACE ((" HPDF_LoadTTFontFromFile\n"));

if (!HPDF_HasDoc (pdf))
return NULL;

/* create file stream */
font_data = HPDF_FileReader_New (pdf->mmgr, file_name);

if (HPDF_Stream_Validate (font_data)) {
ret = LoadTTFontFromStream (pdf, font_data, embedding,
file_name);
} else
ret = NULL;

if (!ret)
HPDF_CheckError (&pdf->error);

return ret;
}



2) In hpdf_doc.c the stream is used:
static const char*
LoadTTFontFromStream (HPDF_Doc pdf,
HPDF_Stream font_data,
HPDF_BOOL embedding,
const char *file_name)
{
HPDF_FontDef def;

HPDF_PTRACE ((" HPDF_LoadTTFontFromStream\n"));

def = HPDF_TTFontDef_Load (pdf->mmgr, font_data,
embedding); //ON ERROR or not EMBEDDING the
stream is auto closed, not logical
if (def) {
HPDF_FontDef tmpdef = HPDF_Doc_FindFontDef (pdf, def-
>base_font);
if (tmpdef) {
HPDF_FontDef_Free (def);
HPDF_SetError (&pdf->error, HPDF_FONT_EXISTS, 0);
return NULL;
}

if (HPDF_List_Add (pdf->fontdef_list, def) != HPDF_OK) {
HPDF_FontDef_Free (def);
return NULL;
}
} else
return NULL;

if (embedding) { //
EMBEDDING: open stream is registered.
if (pdf->ttfont_tag[0] == 0) {
HPDF_MemCpy (pdf->ttfont_tag, (HPDF_BYTE *)"HPDFAA", 6);
} else {
HPDF_INT i;

for (i = 5; i >= 0; i--) {
pdf->ttfont_tag[i] += 1;
if (pdf->ttfont_tag[i] > 'Z')
pdf->ttfont_tag[i] = 'A';
else
break;
}
}

HPDF_TTFontDef_SetTagName (def, (char *)pdf->ttfont_tag);
}

return def-
>base_font; //NOT
EMBEDDING: open stream has been automatically closed
}



3) In hpdf_fontdef_tt.c the stream is closed:
HPDF_FontDef
HPDF_TTFontDef_Load (HPDF_MMgr mmgr,
HPDF_Stream stream,
HPDF_BOOL embedding)
{
HPDF_STATUS ret;
HPDF_FontDef fontdef;

HPDF_PTRACE ((" HPDF_TTFontDef_Load\n"));

fontdef = HPDF_TTFontDef_New (mmgr);

if (!fontdef) {
HPDF_Stream_Free (stream); //On error,
STREAM IS CLOSED HERE, this confused me, it is not logical
return NULL;
}

ret = LoadFontData (fontdef, stream, embedding, 0);
if (ret != HPDF_OK) {
HPDF_FontDef_Free (fontdef);
return NULL;
}

return fontdef;
}

4) In hpdf_fontdef_tt.c the stream is closed:
static HPDF_STATUS
LoadFontData (HPDF_FontDef fontdef,
HPDF_Stream stream,
HPDF_BOOL embedding,
HPDF_UINT offset)
{
HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
HPDF_STATUS ret;
HPDF_TTFTable *tbl;

HPDF_PTRACE ((" HPDF_TTFontDef_LoadFontData\n"));

attr->stream = stream;
attr->embedding = embedding;

if ((ret = HPDF_Stream_Seek (stream, offset, HPDF_SEEK_SET)) !=
HPDF_OK)
return ret;

if ((ret = LoadTTFTable (fontdef)) != HPDF_OK)
return ret;

#ifdef HPDF_DUMP_FONTDATA
DumpTable (fontdef);
#endif /* HPDF_DUMP_FONTDATA */

if ((ret = ParseHead (fontdef)) != HPDF_OK)
return ret;

if ((ret = ParseMaxp (fontdef)) != HPDF_OK)
return ret;

if ((ret = ParseHhea (fontdef)) != HPDF_OK)
return ret;

if ((ret = ParseCMap (fontdef)) != HPDF_OK)
return ret;

if ((ret = ParseHmtx (fontdef)) != HPDF_OK)
return ret;

if ((ret = ParseLoca (fontdef)) != HPDF_OK)
return ret;

if ((ret = ParseName (fontdef)) != HPDF_OK)
return ret;

if ((ret = ParseOS2 (fontdef)) != HPDF_OK)
return ret;

tbl = FindTable (fontdef, "glyf");
if (!tbl)
return HPDF_SetError (fontdef->error, HPDF_TTF_MISSING_TABLE,
4);

attr->glyph_tbl.base_offset = tbl->offset;
fontdef->cap_height =
HPDF_TTFontDef_GetCharBBox (fontdef,
(HPDF_UINT16)'H').top;
fontdef->x_height =
HPDF_TTFontDef_GetCharBBox (fontdef,
(HPDF_UINT16)'x').top;
fontdef->missing_width = (HPDF_UINT32)attr->h_metric
[0].advance_width * 1000 /
attr->header.units_per_em;

HPDF_PTRACE ((" fontdef->cap_height=%d\n", fontdef->cap_height));
HPDF_PTRACE ((" fontdef->x_height=%d\n", fontdef->x_height));
HPDF_PTRACE ((" fontdef->missing_width=%d\n", fontdef-
>missing_width));

if (!embedding) {
HPDF_Stream_Free (attr->stream); //Not embedding, THE
STREAM IS CLOSED, this is not logical.
attr->stream = NULL;
}

return HPDF_OK;
}



I expected that the stream is the responsibility of the opener. I
expected that in 1) the stream is closed if needed. This is not the
case. To me this is not logical, opening a stream in source hpdf_doc.c
and closing the stream in hpdf_typedef_tt.c

In my case, I opened the stream in acp_getfontfileinfo.c and then I
found out that MY stream was automatically closed in hpdf_typedef_tt.c

Regards,
Mirco
Reply all
Reply to author
Forward
0 new messages