From 4f7e2563c11626a10c5470773a8b588f8339c495 Mon Sep 17 00:00:00 2001 From: Chris Young Date: Mon, 11 Jan 2016 19:55:37 +0000 Subject: [PATCH] Separate font cache code into a new file --- amiga/Makefile.target | 2 +- amiga/font.c | 169 +++-------------------------------- amiga/font_cache.c | 203 ++++++++++++++++++++++++++++++++++++++++++ amiga/font_cache.h | 48 ++++++++++ 4 files changed, 262 insertions(+), 160 deletions(-) create mode 100644 amiga/font_cache.c create mode 100644 amiga/font_cache.h diff --git a/amiga/Makefile.target b/amiga/Makefile.target index f42214021..391dd6ec9 100644 --- a/amiga/Makefile.target +++ b/amiga/Makefile.target @@ -76,7 +76,7 @@ S_AMIGA := gui.c tree.c history.c hotlist.c schedule.c file.c \ datatypes.c dt_picture.c dt_anim.c dt_sound.c plugin_hack.c \ stringview/stringview.c stringview/urlhistory.c rtg.c \ agclass/amigaguide_class.c os3support.c font_bitmap.c \ - selectmenu.c hash/xxhash.c + selectmenu.c hash/xxhash.c font_cache.c S_AMIGA := $(addprefix amiga/,$(S_AMIGA)) # This is the final source build list diff --git a/amiga/font.c b/amiga/font.c index 0b9784284..79f887f82 100644 --- a/amiga/font.c +++ b/amiga/font.c @@ -26,8 +26,6 @@ #include #include #include -#include -#include #include #include @@ -47,14 +45,10 @@ #include "desktop/gui_window.h" #include "amiga/font.h" +#include "amiga/font_cache.h" #include "amiga/font_scan.h" #include "amiga/gui.h" #include "amiga/utf8.h" -#include "amiga/object.h" -#include "amiga/schedule.h" -#ifdef __amigaos4__ -#include -#endif #define NSA_UNICODE_FONT PLOT_FONT_FAMILY_COUNT @@ -72,18 +66,6 @@ #define NSA_FONT_EMWIDTH(s) (s / FONT_SIZE_SCALE) * (ami_xdpi / 72.0) -struct ami_font_node -{ -#ifdef __amigaos4__ - struct SkipNode skip_node; -#endif - struct OutlineFont *font; - char *bold; - char *italic; - char *bolditalic; - struct TimeVal lastused; -}; - const uint16 sc_table[] = { 0x0061, 0x1D00, /* a */ 0x0062, 0x0299, /* b */ @@ -151,16 +133,11 @@ const uint16 sc_table[] = { #endif 0, 0}; -#ifdef __amigaos4__ -struct SkipList *ami_font_list = NULL; -#else -struct MinList *ami_font_list = NULL; -#endif -struct List ami_diskfontlib_list; lwc_string *glypharray[0xffff + 1]; ULONG ami_devicedpi; ULONG ami_xdpi; -static struct Hook ami_font_cache_hook; + +static struct List ami_diskfontlib_list; static inline int32 ami_font_plot_glyph(struct OutlineFont *ofont, struct RastPort *rp, uint16 *char1, uint16 *char2, uint32 x, uint32 y, uint32 emwidth, bool aa); @@ -373,29 +350,10 @@ static inline bool amiga_nsfont_split(const plot_font_style_t *fstyle, */ static struct ami_font_node *ami_font_open(const char *font, bool critical) { - struct ami_font_node *nodedata = NULL; - uint32 hash = 0; + struct ami_font_node *nodedata = ami_font_cache_locate(font); + if(nodedata) return nodedata; -#ifdef __amigaos4__ - hash = XXH32(font, strlen(font), 0); - nodedata = (struct ami_font_node *)FindSkipNode(ami_font_list, (APTR)hash); -#else - struct nsObject *node = (struct nsObject *)FindIName((struct List *)ami_font_list, font); - if(node) nodedata = node->objstruct; -#endif - - if(nodedata) { - GetSysTime(&nodedata->lastused); - return nodedata; - } - - LOG("Font cache miss: %s (%lx)", font, hash); - -#ifdef __amigaos4__ - nodedata = (struct ami_font_node *)InsertSkipNode(ami_font_list, (APTR)hash, sizeof(struct ami_font_node)); -#else - nodedata = AllocVecTagList(sizeof(struct ami_font_node), NULL); -#endif + nodedata = ami_font_cache_alloc_entry(font); if(nodedata == NULL) { warn_user("NoMemory", ""); @@ -430,16 +388,7 @@ static struct ami_font_node *ami_font_open(const char *font, bool critical) else LOG("Warning: No designed bold-italic font defined for %s", font); - GetSysTime(&nodedata->lastused); - -#ifndef __amigaos4__ - node = AddObject(ami_font_list, AMINS_FONT); - if(node) { - node->objstruct = nodedata; - node->dtz_Node.ln_Name = strdup(font); - } -#endif - + ami_font_cache_insert(nodedata, font); return nodedata; } @@ -924,119 +873,21 @@ void ami_font_savescanner(void) ami_font_scan_save(nsoption_charp(font_unicode_file), glypharray); } -#ifdef __amigaos4__ -static LONG ami_font_cache_sort(struct Hook *hook, APTR key1, APTR key2) -{ - if(key1 == key2) return 0; - if(key1 < key2) return -1; - return 1; -} -#endif - -#ifdef __amigaos4__ -static void ami_font_cleanup(struct SkipList *skiplist) -{ - struct ami_font_node *node; - struct ami_font_node *nnode; - struct TimeVal curtime; - - node = (struct ami_font_node *)GetFirstSkipNode(skiplist); - if(node == NULL) return; - - do { - nnode = (struct ami_font_node *)GetNextSkipNode(skiplist, (struct SkipNode *)node); - GetSysTime(&curtime); - SubTime(&curtime, &node->lastused); - if(curtime.Seconds > 300) - { - LOG("Freeing font %lx not used for %ld seconds", node->skip_node.sn_Key, curtime.Seconds); - ami_font_close(node); - RemoveSkipNode(skiplist, node->skip_node.sn_Key); - } - } while((node = nnode)); - - /* reschedule to run in five minutes */ - ami_schedule(300000, (void *)ami_font_cleanup, ami_font_list); -} -#else -static void ami_font_cleanup(struct MinList *ami_font_list) -{ - struct nsObject *node; - struct nsObject *nnode; - struct ami_font_node *fnode; - struct TimeVal curtime; - - if(IsMinListEmpty(ami_font_list)) return; - - node = (struct nsObject *)GetHead((struct List *)ami_font_list); - - do - { - nnode=(struct nsObject *)GetSucc((struct Node *)node); - fnode = node->objstruct; - GetSysTime(&curtime); - SubTime(&curtime, &fnode->lastused); - if(curtime.Seconds > 300) - { - LOG("Freeing %s not used for %ld seconds", node->dtz_Node.ln_Name, curtime.Seconds); - DelObject(node); - } - } while((node=nnode)); - - /* reschedule to run in five minutes */ - ami_schedule(300000, (void *)ami_font_cleanup, ami_font_list); -} -#endif - void ami_init_fonts(void) { /* Initialise Unicode font scanner */ ami_font_initscanner(false, true); /* Initialise font caching etc lists */ -#ifdef __amigaos4__ - ami_font_cache_hook.h_Entry = (HOOKFUNC)ami_font_cache_sort; - ami_font_cache_hook.h_Data = 0; - ami_font_list = CreateSkipList(&ami_font_cache_hook, 8); -#else - ami_font_list = NewObjList(); -#endif + ami_font_cache_init(); + /* List for diskfont internal cache */ NewList(&ami_diskfontlib_list); - - /* run first cleanup in ten minutes */ - ami_schedule(600000, (void *)ami_font_cleanup, ami_font_list); } -#ifdef __amigaos4__ -static void ami_font_del_skiplist(struct SkipList *skiplist) -{ - struct ami_font_node *node; - struct SkipNode *nnode; - - node = (struct ami_font_node *)GetFirstSkipNode(skiplist); - if(node == NULL) return; - - do { - nnode = GetNextSkipNode(skiplist, (struct SkipNode *)node); - ami_font_close(node); - - } while((node = nnode)); - - DeleteSkipList(skiplist); -} -#endif - void ami_close_fonts(void) { - LOG("Cleaning up font cache"); - ami_schedule(-1, (void *)ami_font_cleanup, ami_font_list); -#ifdef __amigaos4__ - ami_font_del_skiplist(ami_font_list); -#else - FreeObjList(ami_font_list); -#endif - ami_font_list = NULL; + ami_font_cache_fini(); ami_font_finiscanner(); } diff --git a/amiga/font_cache.c b/amiga/font_cache.c new file mode 100644 index 000000000..4b81aabe1 --- /dev/null +++ b/amiga/font_cache.c @@ -0,0 +1,203 @@ +/* + * Copyright 2015 Chris Young + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "amiga/os3support.h" + +#include +#include + +#include "utils/log.h" + +#include "amiga/font.h" +#include "amiga/font_cache.h" +#include "amiga/schedule.h" + +#ifdef __amigaos4__ +#include "amiga/hash/xxhash.h" +#else +#include "amiga/object.h" +#endif + +#ifdef __amigaos4__ +static struct SkipList *ami_font_list = NULL; +static struct Hook ami_font_cache_hook; +#else +static struct MinList *ami_font_list = NULL; +#endif + + + +#ifdef __amigaos4__ +static LONG ami_font_cache_sort(struct Hook *hook, APTR key1, APTR key2) +{ + if(key1 == key2) return 0; + if(key1 < key2) return -1; + return 1; +} +#endif + +#ifdef __amigaos4__ +static void ami_font_cleanup(struct SkipList *skiplist) +{ + struct ami_font_node *node; + struct ami_font_node *nnode; + struct TimeVal curtime; + + node = (struct ami_font_node *)GetFirstSkipNode(skiplist); + if(node == NULL) return; + + do { + nnode = (struct ami_font_node *)GetNextSkipNode(skiplist, (struct SkipNode *)node); + GetSysTime(&curtime); + SubTime(&curtime, &node->lastused); + if(curtime.Seconds > 300) + { + LOG("Freeing font %lx not used for %ld seconds", node->skip_node.sn_Key, curtime.Seconds); + ami_font_close(node); + RemoveSkipNode(skiplist, node->skip_node.sn_Key); + } + } while((node = nnode)); + + /* reschedule to run in five minutes */ + ami_schedule(300000, (void *)ami_font_cleanup, ami_font_list); +} +#else +static void ami_font_cleanup(struct MinList *ami_font_list) +{ + struct nsObject *node; + struct nsObject *nnode; + struct ami_font_node *fnode; + struct TimeVal curtime; + + if(IsMinListEmpty(ami_font_list)) return; + + node = (struct nsObject *)GetHead((struct List *)ami_font_list); + + do + { + nnode=(struct nsObject *)GetSucc((struct Node *)node); + fnode = node->objstruct; + GetSysTime(&curtime); + SubTime(&curtime, &fnode->lastused); + if(curtime.Seconds > 300) + { + LOG("Freeing %s not used for %ld seconds", node->dtz_Node.ln_Name, curtime.Seconds); + DelObject(node); + } + } while((node=nnode)); + + /* reschedule to run in five minutes */ + ami_schedule(300000, (void *)ami_font_cleanup, ami_font_list); +} +#endif + +#ifdef __amigaos4__ +static void ami_font_del_skiplist(struct SkipList *skiplist) +{ + struct ami_font_node *node; + struct SkipNode *nnode; + + node = (struct ami_font_node *)GetFirstSkipNode(skiplist); + if(node == NULL) return; + + do { + nnode = GetNextSkipNode(skiplist, (struct SkipNode *)node); + ami_font_close(node); + + } while((node = nnode)); + + DeleteSkipList(skiplist); +} +#endif + + +struct ami_font_node *ami_font_cache_locate(const char *font) +{ + struct ami_font_node *nodedata; + uint32 hash = 0; + +#ifdef __amigaos4__ + hash = XXH32(font, strlen(font), 0); + nodedata = (struct ami_font_node *)FindSkipNode(ami_font_list, (APTR)hash); +#else + struct nsObject *node = (struct nsObject *)FindIName((struct List *)ami_font_list, font); + if(node) nodedata = node->objstruct; +#endif + + if(nodedata) { + GetSysTime(&nodedata->lastused); + return nodedata; + } + + LOG("Font cache miss: %s (%lx)", font, hash); + return NULL; +} + +struct ami_font_node *ami_font_cache_alloc_entry(const char *font) +{ + struct ami_font_node *nodedata; + +#ifdef __amigaos4__ + uint32 hash = XXH32(font, strlen(font), 0); + nodedata = (struct ami_font_node *)InsertSkipNode(ami_font_list, (APTR)hash, sizeof(struct ami_font_node)); +#else + nodedata = AllocVecTagList(sizeof(struct ami_font_node), NULL); +#endif + + GetSysTime(&nodedata->lastused); + + return nodedata; +} + +void ami_font_cache_insert(struct ami_font_node *nodedata, const char *font) +{ +#ifndef __amigaos4__ + struct nsObject *node = AddObject(ami_font_list, AMINS_FONT); + if(node) { + node->objstruct = nodedata; + node->dtz_Node.ln_Name = strdup(font); + } +#endif +} + +void ami_font_cache_fini(void) +{ + LOG("Cleaning up font cache"); + ami_schedule(-1, (void *)ami_font_cleanup, ami_font_list); +#ifdef __amigaos4__ + ami_font_del_skiplist(ami_font_list); +#else + FreeObjList(ami_font_list); +#endif + ami_font_list = NULL; +} + +void ami_font_cache_init(void) +{ +#ifdef __amigaos4__ + ami_font_cache_hook.h_Entry = (HOOKFUNC)ami_font_cache_sort; + ami_font_cache_hook.h_Data = 0; + ami_font_list = CreateSkipList(&ami_font_cache_hook, 8); +#else + ami_font_list = NewObjList(); +#endif + + /* run first cleanup in ten minutes */ + ami_schedule(600000, (void *)ami_font_cleanup, ami_font_list); +} + diff --git a/amiga/font_cache.h b/amiga/font_cache.h new file mode 100644 index 000000000..bb462bcfa --- /dev/null +++ b/amiga/font_cache.h @@ -0,0 +1,48 @@ +/* + * Copyright 2015 Chris Young + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef AMIGA_FONT_CACHE_H +#define AMIGA_FONT_CACHE_H +struct ami_font_node +{ +#ifdef __amigaos4__ + struct SkipNode skip_node; +#endif + struct OutlineFont *font; + char *bold; + char *italic; + char *bolditalic; + struct TimeVal lastused; +}; + + +/* locate an entry in the font cache, NULL if not found */ +struct ami_font_node *ami_font_cache_locate(const char *font); + +/* allocate a cache entry */ +struct ami_font_node *ami_font_cache_alloc_entry(const char *font); + +/* insert a cache entry into the list (OS3) */ +void ami_font_cache_insert(struct ami_font_node *nodedata, const char *font); + +void ami_font_cache_init(void); +void ami_font_cache_fini(void); + +#endif + +