summaryrefslogtreecommitdiff
path: root/amiga/font.c
diff options
context:
space:
mode:
authorChris Young <chris@unsatisfactorysoftware.co.uk>2011-04-30 19:05:11 +0000
committerChris Young <chris@unsatisfactorysoftware.co.uk>2011-04-30 19:05:11 +0000
commit11a028442758a0e4cfe065d0649f79ad5430a04a (patch)
tree6d41a21988b32f8374750af7b46831a77a020649 /amiga/font.c
parent003f3537c6f6d45f9f04f04df98d502bfe45f550 (diff)
downloadnetsurf-11a028442758a0e4cfe065d0649f79ad5430a04a.tar.gz
netsurf-11a028442758a0e4cfe065d0649f79ad5430a04a.tar.bz2
Don't open fonts until they are needed
svn path=/trunk/netsurf/; revision=12264
Diffstat (limited to 'amiga/font.c')
-rw-r--r--amiga/font.c211
1 files changed, 92 insertions, 119 deletions
diff --git a/amiga/font.c b/amiga/font.c
index f884d9dc2..0f2c3e7d9 100644
--- a/amiga/font.c
+++ b/amiga/font.c
@@ -21,6 +21,7 @@
#include "amiga/font.h"
#include "amiga/gui.h"
#include "amiga/utf8.h"
+#include "amiga/object.h"
#include "amiga/options.h"
#include "css/css.h"
#include "css/utils.h"
@@ -55,11 +56,15 @@
#define NSA_VALUE_SHEARSIN (1 << 14)
#define NSA_VALUE_SHEARCOS (1 << 16)
-static struct OutlineFont *of[PLOT_FONT_FAMILY_COUNT+1];
-static struct OutlineFont *ofb[PLOT_FONT_FAMILY_COUNT+1];
-static struct OutlineFont *ofi[PLOT_FONT_FAMILY_COUNT+1];
-static struct OutlineFont *ofbi[PLOT_FONT_FAMILY_COUNT+1];
+struct ami_font_node
+{
+ struct OutlineFont *font;
+ char *bold;
+ char *italic;
+ char *bolditalic;
+};
+struct MinList *ami_font_list = NULL;
ULONG ami_devicedpi;
int32 ami_font_plot_glyph(struct OutlineFont *ofont, struct RastPort *rp,
@@ -300,6 +305,45 @@ bool nsfont_split(const plot_font_style_t *fstyle,
}
/**
+ * Search for a font in the list and load from disk if not present
+ */
+struct ami_font_node *ami_font_open(const char *font)
+{
+ struct nsObject *node;
+ struct ami_font_node *nodedata;
+
+ node = (struct nsObject *)FindIName((struct List *)ami_font_list, font);
+ if(node) return node->objstruct;
+
+ LOG(("Font cache miss: %s", font));
+
+ nodedata = AllocVec(sizeof(struct ami_font_node), MEMF_PRIVATE | MEMF_CLEAR);
+
+ node = AddObject(ami_font_list, AMINS_FONT);
+ if(!node) return NULL;
+
+ node->objstruct = nodedata;
+ node->dtz_Node.ln_Name = strdup(font);
+
+ nodedata->font = OpenOutlineFont(font, NULL, OFF_OPEN);
+ if(!nodedata->font)
+ {
+ LOG(("Requested font not found: %s", font));
+ warn_user("CompError", font);
+ return NULL;
+ }
+
+ nodedata->bold = (char *)GetTagData(OT_BName, 0, nodedata->font->olf_OTagList);
+ if(!nodedata->bold) LOG(("Warning: No designed bold font defined for %s", font));
+ nodedata->italic = (char *)GetTagData(OT_IName, 0, nodedata->font->olf_OTagList);
+ if(!nodedata->italic) LOG(("Warning: No designed italic font defined for %s", font));
+ nodedata->bolditalic = (char *)GetTagData(OT_BIName, 0, nodedata->font->olf_OTagList);
+ if(!nodedata->bolditalic) LOG(("Warning: No designed bold/italic font defined for %s", font));
+
+ return nodedata;
+}
+
+/**
* Open an outline font in the specified size and style
*
* \param fstyle font style structure
@@ -308,6 +352,7 @@ bool nsfont_split(const plot_font_style_t *fstyle,
*/
struct OutlineFont *ami_open_outline_font(const plot_font_style_t *fstyle, BOOL fallback)
{
+ struct ami_font_node *node;
struct OutlineFont *ofont;
char *fontname;
ULONG ysize;
@@ -321,6 +366,32 @@ struct OutlineFont *ami_open_outline_font(const plot_font_style_t *fstyle, BOOL
if(fallback) fontfamily = NSA_UNICODE_FONT;
else fontfamily = fstyle->family;
+ switch(fontfamily)
+ {
+ case PLOT_FONT_FAMILY_SANS_SERIF:
+ fontname = option_font_sans;
+ break;
+ case PLOT_FONT_FAMILY_SERIF:
+ fontname = option_font_serif;
+ break;
+ case PLOT_FONT_FAMILY_MONOSPACE:
+ fontname = option_font_mono;
+ break;
+ case PLOT_FONT_FAMILY_CURSIVE:
+ fontname = option_font_cursive;
+ break;
+ case PLOT_FONT_FAMILY_FANTASY:
+ fontname = option_font_fantasy;
+ break;
+ case NSA_UNICODE_FONT:
+ default:
+ fontname = option_font_unicode;
+ break;
+ }
+
+ node = ami_font_open(fontname);
+ if(!node) return NULL;
+
if ((fstyle->flags & FONTF_ITALIC) || (fstyle->flags & FONTF_OBLIQUE))
tstyle += NSA_ITALIC;
@@ -330,54 +401,49 @@ struct OutlineFont *ami_open_outline_font(const plot_font_style_t *fstyle, BOOL
switch(tstyle)
{
case NSA_ITALIC:
- if(ofi[fontfamily])
+ if(node->italic)
{
- ofont = ofi[fontfamily];
+ node = ami_font_open(node->italic);
}
else
{
- ofont = of[fontfamily];
shearsin = NSA_VALUE_SHEARSIN;
shearcos = NSA_VALUE_SHEARCOS;
}
break;
case NSA_BOLD:
- if(ofb[fontfamily])
+ if(node->bold)
{
- ofont = ofb[fontfamily];
+ node = ami_font_open(node->bold);
}
else
{
- ofont = of[fontfamily];
emboldenx = NSA_VALUE_BOLDX;
emboldeny = NSA_VALUE_BOLDY;
}
break;
case NSA_BOLDITALIC:
- if(ofbi[fontfamily])
+ if(node->bolditalic)
{
- ofont = ofbi[fontfamily];
+ node = ami_font_open(node->bolditalic);
}
else
{
- ofont = of[fontfamily];
emboldenx = NSA_VALUE_BOLDX;
emboldeny = NSA_VALUE_BOLDY;
shearsin = NSA_VALUE_SHEARSIN;
shearcos = NSA_VALUE_SHEARCOS;
}
break;
-
- default:
- ofont = of[fontfamily];
- break;
}
/* Scale to 16.16 fixed point */
ysize = fstyle->size * ((1 << 16) / FONT_SIZE_SCALE);
+ ofont = node->font;
+
if(ESetInfo(&ofont->olf_EEngine,
OT_DeviceDPI, ami_devicedpi,
OT_PointHeight, ysize,
@@ -509,113 +575,20 @@ ULONG ami_unicode_text(struct RastPort *rp,const char *string,ULONG length,const
void ami_init_fonts(void)
{
- int i;
- char *bname,*iname,*biname;
- char *deffont;
-
- switch(option_font_default)
- {
- case PLOT_FONT_FAMILY_SANS_SERIF:
- deffont = strdup(option_font_sans);
- break;
- case PLOT_FONT_FAMILY_SERIF:
- deffont = strdup(option_font_serif);
- break;
- case PLOT_FONT_FAMILY_MONOSPACE:
- deffont = strdup(option_font_mono);
- break;
- case PLOT_FONT_FAMILY_CURSIVE:
- deffont = strdup(option_font_cursive);
- break;
- case PLOT_FONT_FAMILY_FANTASY:
- deffont = strdup(option_font_fantasy);
- break;
- default:
- deffont = strdup(option_font_sans);
- break;
- }
-
- of[PLOT_FONT_FAMILY_SANS_SERIF] = OpenOutlineFont(option_font_sans,NULL,OFF_OPEN);
- of[PLOT_FONT_FAMILY_SERIF] = OpenOutlineFont(option_font_serif,NULL,OFF_OPEN);
- of[PLOT_FONT_FAMILY_MONOSPACE] = OpenOutlineFont(option_font_mono,NULL,OFF_OPEN);
- of[PLOT_FONT_FAMILY_CURSIVE] = OpenOutlineFont(option_font_cursive,NULL,OFF_OPEN);
- of[PLOT_FONT_FAMILY_FANTASY] = OpenOutlineFont(option_font_fantasy,NULL,OFF_OPEN);
- of[NSA_UNICODE_FONT] = OpenOutlineFont(option_font_unicode,NULL,OFF_OPEN);
-
- for(i=PLOT_FONT_FAMILY_SANS_SERIF;i<=NSA_UNICODE_FONT;i++)
- {
- if(!of[i])
- {
- char *tmpfontname = NULL;
- switch(i)
- {
- case PLOT_FONT_FAMILY_SANS_SERIF:
- tmpfontname = option_font_sans;
- break;
- case PLOT_FONT_FAMILY_SERIF:
- tmpfontname = option_font_serif;
- break;
- case PLOT_FONT_FAMILY_MONOSPACE:
- tmpfontname = option_font_mono;
- break;
- case PLOT_FONT_FAMILY_CURSIVE:
- tmpfontname = option_font_cursive;
- break;
- case PLOT_FONT_FAMILY_FANTASY:
- tmpfontname = option_font_fantasy;
- break;
- case NSA_UNICODE_FONT:
- tmpfontname = option_font_unicode;
- break;
- default:
- /* should never get here, but just in case */
- tmpfontname = strdup("{unknown font}");
- break;
- }
- warn_user("CompError",tmpfontname);
- }
-
- if(bname = (char *)GetTagData(OT_BName,0,of[i]->olf_OTagList))
- {
- ofb[i] = OpenOutlineFont(bname,NULL,OFF_OPEN);
- }
- else
- {
- ofb[i] = NULL;
- }
-
- if(iname = (char *)GetTagData(OT_IName,0,of[i]->olf_OTagList))
- {
- ofi[i] = OpenOutlineFont(iname,NULL,OFF_OPEN);
- }
- else
- {
- ofi[i] = NULL;
- }
-
- if(biname = (char *)GetTagData(OT_BIName,0,of[i]->olf_OTagList))
- {
- ofbi[i] = OpenOutlineFont(biname,NULL,OFF_OPEN);
- }
- else
- {
- ofbi[i] = NULL;
- }
- }
- if(deffont) free(deffont);
+ ami_font_list = NewObjList();
}
void ami_close_fonts(void)
{
- int i=0;
+ FreeObjList(ami_font_list);
+ ami_font_list = NULL;
+}
- for(i=PLOT_FONT_FAMILY_SANS_SERIF;i<=NSA_UNICODE_FONT;i++)
- {
- if(of[i]) CloseOutlineFont(of[i],NULL);
- if(ofb[i]) CloseOutlineFont(ofb[i],NULL);
- if(ofi[i]) CloseOutlineFont(ofi[i],NULL);
- if(ofbi[i]) CloseOutlineFont(ofbi[i],NULL);
- }
+void ami_font_close(struct ami_font_node *node)
+{
+ /* Called from FreeObjList if node type is AMINS_FONT */
+
+ CloseOutlineFont(node->font, NULL);
}
void ami_font_setdevicedpi(int id)