Tidy-up, split into sensible functions for NetSurf integration,

documentation. Cache file loading needs adding and ami_font_scan_fonts
needs to add to a list of fonts, and then send those to the scanner so we
can put some preferred fonts on the top of the list and avoid duplication.

svn path=/trunk/netsurf/; revision=13903
This commit is contained in:
Chris Young 2012-05-05 11:09:19 +00:00
parent febea7ec4b
commit e635d907aa
1 changed files with 120 additions and 27 deletions

View File

@ -16,8 +16,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* scan fonts
* gcc -o scan_font font_scan.c -lwapcaplet -lauto -D__USE_INLINE__
/** \file
* Font glyph scanner for Unicode substitutions.
*/
#include <stdio.h>
@ -31,7 +31,14 @@
#include <libwapcaplet/libwapcaplet.h>
ULONG scan_font(const char *fontname, lwc_string **glypharray)
/**
* Scan a font for glyphs not present in glypharray.
*
* \param fontname font to scan
* \param glypharray an array of 0xffff lwc_string pointers
* \return number of new glyphs found
*/
ULONG ami_font_scan_font(const char *fontname, lwc_string **glypharray)
{
struct OutlineFont *ofont;
struct MinList *widthlist;
@ -55,7 +62,7 @@ ULONG scan_font(const char *fontname, lwc_string **glypharray)
gwnode = (struct GlyphWidthEntry *)GetHead((struct List *)widthlist);
do {
if(gwnode && (glypharray[gwnode->gwe_Code] == NULL)) {
lwc_intern_string(fontname, strlen(fontname), &glypharray[gwnode->gwe_Code]);
lwc_intern_string(fontname, strlen(fontname) - 5, &glypharray[gwnode->gwe_Code]);
//printf("%lx\n",gwnode->gwe_Code);
foundglyphs++;
}
@ -68,8 +75,15 @@ ULONG scan_font(const char *fontname, lwc_string **glypharray)
return foundglyphs;
}
ULONG scan_fonts(lwc_string **glypharray)
/**
* Scan all fonts for glyphs.
*
* \param glypharray an array of 0xffff lwc_string pointers
* \return number of glyphs found
*/
ULONG ami_font_scan_fonts(lwc_string **glypharray)
{
/* TODO: this function should take a list of fonts and add to it, ignoring duplicates */
int afShortage, afSize = 100, i;
struct AvailFontsHeader *afh;
struct AvailFonts *af;
@ -95,7 +109,7 @@ printf("af = %lx entries = %ld\n", af, afh->afh_NumEntries);
for(i = 0; i < afh->afh_NumEntries; i++) {
if((af[i].af_Attr.ta_YSize == 0) && (af[i].af_Attr.ta_Style == FS_NORMAL)) {
printf("%s (%ld) %ld\n", af[i].af_Attr.ta_Name, af[i].af_Attr.ta_Style, af[i].af_Attr.ta_YSize);
found = scan_font(af[i].af_Attr.ta_Name, glypharray);
found = ami_font_scan_font(af[i].af_Attr.ta_Name, glypharray);
total += found;
printf("Found %ld new glyphs (total = %ld)\n", found, total);
}
@ -107,36 +121,115 @@ printf("af = %lx entries = %ld\n", af, afh->afh_NumEntries);
}
}
/**
* Load a font glyph cache
*
* \param filename name of cache file to load
* \param glypharray an array of 0xffff lwc_string pointers
* \return number of glyphs loaded
*/
ULONG ami_font_scan_load(const char *filename, lwc_string **glypharray)
{
ULONG found = 0;
BPTR fh = 0;
if(fh = FOpen(filename, MODE_OLDFILE, 0)) {
printf("Reading %s\n", filename);
/* TODO: read lines using ReadArgs() */
FClose(fh);
}
return found;
}
/**
* Save a font glyph cache
*
* \param filename name of cache file to save
* \param glypharray an array of 0xffff lwc_string pointers
*/
void ami_font_scan_save(const char *filename, lwc_string **glypharray)
{
ULONG i;
BPTR fh = 0;
if(fh = FOpen(filename, MODE_NEWFILE, 0)) {
printf("Writing %s\n", filename);
FPrintf(fh, "; This file is auto-generated. To recreate the cache, delete this file.\n");
FPrintf(fh, "; This file is parsed using ReadArgs() with the following template:\n");
FPrintf(fh, "; CODE/A,FONT/A\n;\n");
for(i=0x0000; i<=0xffff; i++)
{
if(glypharray[i]) {
FPrintf(fh, "%04lx \"%s\"\n", i, lwc_string_data(glypharray[i]));
lwc_string_unref(glypharray[i]);
}
}
FClose(fh);
}
}
/**
* Finalise the font glyph cache.
*
* \param glypharray an array of 0xffff lwc_string pointers to free
*/
void ami_font_scan_fini(lwc_string **glypharray)
{
ULONG i;
for(i=0x0000; i<=0xffff; i++)
{
if(glypharray[i]) {
lwc_string_unref(glypharray[i]);
glypharray[i] = NULL;
}
}
}
/**
* Initialise the font glyph cache.
* Reads an existing file or, if not present, generates a new cache.
*
* \param filename cache file to attempt to read
* \param glypharray an array of 0xffff lwc_string pointers
*/
void ami_font_scan_init(const char *filename, lwc_string **glypharray)
{
ULONG i, found;
/* Ensure array zeroed */
for(i=0x0000; i<=0xffff; i++)
glypharray[i] = NULL;
found = ami_font_scan_load(filename, glypharray);
if(found == 0) {
found = ami_font_scan_fonts(glypharray);
ami_font_scan_save(filename, glypharray);
}
printf("Initialised with %ld glyphs\n", found);
}
#ifdef AMI_FONT_SCAN_STANDALONE
/* This can be compiled as standalone using:
* gcc -o font_scan font_scan.c -lwapcaplet -lauto -D__USE_INLINE__ -DAMI_FONT_SCAN_STANDALONE
*/
int main(int argc, char** argv)
{
lwc_string *glypharray[0xffff + 1];
ULONG i, found = 0;
ULONG found = 0;
BPTR fh;
if(argc < 2) return 5;
printf("%s\n",argv[1]);
/* Ensure array zeroed */
for(i=0x0000; i<=0xffff; i++)
glypharray[i] = NULL;
scan_fonts(glypharray);
if(fh = FOpen(argv[1], ACCESS_WRITE, 0)) {
printf("Writing %s\n", argv[1]);
for(i=0x0000; i<=0xffff; i++)
{
if(glypharray[i]) {
FPrintf(fh, "%04lx \"%s\"\n", i, lwc_string_data(glypharray[i]));
lwc_string_unref(glypharray[i]);
found++;
}
}
FClose(fh);
}
printf("Found %ld glyphs\n", found);
ami_font_scan_init(argv[1], glypharray);
ami_font_scan_fini(glypharray);
return 0;
}
#endif