From 46f181b3488ddc1b8d11f2bf89327bb49ad4955c Mon Sep 17 00:00:00 2001 From: Chris Young Date: Sat, 16 Jan 2016 00:00:57 +0000 Subject: More font-related tidy-up --- amiga/Makefile.target | 2 +- amiga/filetype.c | 93 ++++++++-------- amiga/filetype.h | 1 - amiga/font.c | 24 ++--- amiga/font.h | 13 --- amiga/font_bitmap.c | 293 -------------------------------------------------- amiga/font_bullet.c | 36 ++++--- amiga/font_cache.c | 10 +- amiga/font_diskfont.c | 287 ++++++++++++++++++++++++++++++++++++++++++++++++ amiga/gui_options.c | 1 + amiga/object.c | 10 +- amiga/object.h | 2 + amiga/options.h | 2 +- amiga/plotters.c | 1 + 14 files changed, 380 insertions(+), 395 deletions(-) delete mode 100644 amiga/font_bitmap.c create mode 100644 amiga/font_diskfont.c diff --git a/amiga/Makefile.target b/amiga/Makefile.target index 626110bc5..8c850d1db 100644 --- a/amiga/Makefile.target +++ b/amiga/Makefile.target @@ -75,7 +75,7 @@ S_AMIGA := gui.c tree.c history.c hotlist.c schedule.c file.c \ sslcert.c gui_options.c print.c theme.c drag.c icon.c libs.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 \ + agclass/amigaguide_class.c os3support.c font_diskfont.c \ selectmenu.c hash/xxhash.c font_cache.c font_bullet.c S_AMIGA := $(addprefix amiga/,$(S_AMIGA)) diff --git a/amiga/filetype.c b/amiga/filetype.c index 4419d712f..39058b41c 100644 --- a/amiga/filetype.c +++ b/amiga/filetype.c @@ -164,6 +164,15 @@ const char *ami_content_type_to_file_type(content_type type) } } +static void ami_mime_entry_free(void *nso) +{ + struct ami_mime_entry *mimeentry = (struct ami_mime_entry *)nso; + + if(mimeentry->mimetype) lwc_string_unref(mimeentry->mimetype); + if(mimeentry->datatype) lwc_string_unref(mimeentry->datatype); + if(mimeentry->filetype) lwc_string_unref(mimeentry->filetype); + if(mimeentry->plugincmd) lwc_string_unref(mimeentry->plugincmd); +} nserror ami_mime_init(const char *mimefile) { @@ -205,40 +214,42 @@ nserror ami_mime_init(const char *mimefile) if(ReadArgs(template, rarray, rargs)) { - node = AddObject(ami_mime_list, AMINS_MIME); - mimeentry = ami_misc_allocvec_clear(sizeof(struct ami_mime_entry), 0); - node->objstruct = mimeentry; - - if(rarray[AMI_MIME_MIMETYPE]) - { - lerror = lwc_intern_string((char *)rarray[AMI_MIME_MIMETYPE], - strlen((char *)rarray[AMI_MIME_MIMETYPE]), &mimeentry->mimetype); - if (lerror != lwc_error_ok) - return NSERROR_NOMEM; - } - - if(rarray[AMI_MIME_DATATYPE]) - { - lerror = lwc_intern_string((char *)rarray[AMI_MIME_DATATYPE], - strlen((char *)rarray[AMI_MIME_DATATYPE]), &mimeentry->datatype); - if (lerror != lwc_error_ok) - return NSERROR_NOMEM; - } - - if(rarray[AMI_MIME_FILETYPE]) - { - lerror = lwc_intern_string((char *)rarray[AMI_MIME_FILETYPE], - strlen((char *)rarray[AMI_MIME_FILETYPE]), &mimeentry->filetype); - if (lerror != lwc_error_ok) - return NSERROR_NOMEM; - } - - if(rarray[AMI_MIME_PLUGINCMD]) - { - lerror = lwc_intern_string((char *)rarray[AMI_MIME_PLUGINCMD], - strlen((char *)rarray[AMI_MIME_PLUGINCMD]), &mimeentry->plugincmd); - if (lerror != lwc_error_ok) - return NSERROR_NOMEM; + if ((node = AddObject(ami_mime_list, AMINS_MIME))) { + ObjectCallback(node, ami_mime_entry_free); + mimeentry = ami_misc_allocvec_clear(sizeof(struct ami_mime_entry), 0); + node->objstruct = mimeentry; + + if(rarray[AMI_MIME_MIMETYPE]) + { + lerror = lwc_intern_string((char *)rarray[AMI_MIME_MIMETYPE], + strlen((char *)rarray[AMI_MIME_MIMETYPE]), &mimeentry->mimetype); + if (lerror != lwc_error_ok) + return NSERROR_NOMEM; + } + + if(rarray[AMI_MIME_DATATYPE]) + { + lerror = lwc_intern_string((char *)rarray[AMI_MIME_DATATYPE], + strlen((char *)rarray[AMI_MIME_DATATYPE]), &mimeentry->datatype); + if (lerror != lwc_error_ok) + return NSERROR_NOMEM; + } + + if(rarray[AMI_MIME_FILETYPE]) + { + lerror = lwc_intern_string((char *)rarray[AMI_MIME_FILETYPE], + strlen((char *)rarray[AMI_MIME_FILETYPE]), &mimeentry->filetype); + if (lerror != lwc_error_ok) + return NSERROR_NOMEM; + } + + if(rarray[AMI_MIME_PLUGINCMD]) + { + lerror = lwc_intern_string((char *)rarray[AMI_MIME_PLUGINCMD], + strlen((char *)rarray[AMI_MIME_PLUGINCMD]), &mimeentry->plugincmd); + if (lerror != lwc_error_ok) + return NSERROR_NOMEM; + } } FreeArgs(rargs); } @@ -256,15 +267,6 @@ void ami_mime_free(void) FreeObjList(ami_mime_list); } -void ami_mime_entry_free(struct ami_mime_entry *mimeentry) -{ - if(mimeentry->mimetype) lwc_string_unref(mimeentry->mimetype); - if(mimeentry->datatype) lwc_string_unref(mimeentry->datatype); - if(mimeentry->filetype) lwc_string_unref(mimeentry->filetype); - if(mimeentry->plugincmd) lwc_string_unref(mimeentry->plugincmd); -} - - /** * Return next matching MIME entry * @@ -356,8 +358,13 @@ static APTR ami_mime_guess_add_datatype(struct DataType *dt, lwc_string **lwc_mi char *p; node = AddObject(ami_mime_list, AMINS_MIME); + if(node == NULL) return NULL; + mimeentry = ami_misc_allocvec_clear(sizeof(struct ami_mime_entry), 0); + if(mimeentry == NULL) return NULL; + node->objstruct = mimeentry; + ObjectCallback(node, ami_mime_entry_free); lerror = lwc_intern_string(dth->dth_Name, strlen(dth->dth_Name), &mimeentry->datatype); if (lerror != lwc_error_ok) diff --git a/amiga/filetype.h b/amiga/filetype.h index e99f5950c..fc27b1df2 100644 --- a/amiga/filetype.h +++ b/amiga/filetype.h @@ -31,7 +31,6 @@ const char *fetch_filetype(const char *unix_path); nserror ami_mime_init(const char *mimefile); void ami_mime_free(void); -void ami_mime_entry_free(struct ami_mime_entry *mimeentry); void ami_mime_dump(void); struct Node *ami_mime_from_datatype(struct DataType *dt, diff --git a/amiga/font.c b/amiga/font.c index 57017582f..ac5fd129f 100644 --- a/amiga/font.c +++ b/amiga/font.c @@ -18,31 +18,19 @@ #include "amiga/os3support.h" -#include - -#ifndef __amigaos4__ -#include -#endif #include #include - -#include - -#ifdef __amigaos4__ -#include -#endif +#include #include "utils/log.h" -#include "utils/utils.h" #include "utils/nsoption.h" #include "desktop/browser.h" #include "desktop/font.h" -#include "desktop/gui_window.h" #include "amiga/font.h" +#include "amiga/font_bullet.h" +#include "amiga/font_diskfont.h" #include "amiga/font_scan.h" -#include "amiga/gui.h" -#include "amiga/utf8.h" void ami_font_setdevicedpi(int id) { @@ -51,7 +39,7 @@ void ami_font_setdevicedpi(int id) ULONG ydpi = nsoption_int(screen_ydpi); ULONG xdpi = nsoption_int(screen_ydpi); - if(nsoption_bool(use_diskfont) == true) { + if(nsoption_bool(bitmap_fonts) == true) { LOG("WARNING: Using diskfont.library for text. Forcing DPI to 72."); nsoption_int(screen_ydpi) = 72; } @@ -103,7 +91,7 @@ void ami_font_close_disk_font(struct TextFont *tfont) /* Font initialisation */ void ami_font_init(void) { - if(nsoption_bool(use_diskfont) == false) { + if(nsoption_bool(bitmap_fonts) == false) { ami_font_bullet_init(); } else { ami_font_diskfont_init(); @@ -112,7 +100,7 @@ void ami_font_init(void) void ami_font_fini(void) { - if(nsoption_bool(use_diskfont) == false) { + if(nsoption_bool(bitmap_fonts) == false) { ami_font_bullet_fini(); } } diff --git a/amiga/font.h b/amiga/font.h index 404a36e79..416609a8d 100755 --- a/amiga/font.h +++ b/amiga/font.h @@ -29,19 +29,6 @@ void ami_font_setdevicedpi(int id); void ami_font_init(void); void ami_font_fini(void); -/* In font_bitmap.c */ -void ami_font_diskfont_init(void); - -/* In font_bullet.c */ -void ami_font_bullet_init(void); -void ami_font_bullet_fini(void); -void ami_font_close(struct ami_font_cache_node *node); - -/* Alternate entry points into font_scan */ -void ami_font_initscanner(bool force, bool save); -void ami_font_finiscanner(void); -void ami_font_savescanner(void); - /* Simple diskfont functions for graphics.library use (not page rendering) */ struct TextFont *ami_font_open_disk_font(struct TextAttr *tattr); void ami_font_close_disk_font(struct TextFont *tfont); diff --git a/amiga/font_bitmap.c b/amiga/font_bitmap.c deleted file mode 100644 index e1a135744..000000000 --- a/amiga/font_bitmap.c +++ /dev/null @@ -1,293 +0,0 @@ -/* - * Copyright 2008 - 2016 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 -#include -#include -#include - -#include - -#include "utils/log.h" -#include "utils/utf8.h" -#include "utils/utils.h" -#include "utils/nsoption.h" -#include "desktop/browser.h" -#include "desktop/font.h" -#include "desktop/gui_window.h" - -#include "amiga/font.h" -#include "amiga/font_cache.h" -#include "amiga/gui.h" -#include "amiga/utf8.h" - -static struct TextFont *ami_font_bm_open(struct RastPort *rp, const plot_font_style_t *fstyle) -{ - struct TextFont *bmfont = NULL; - struct TextAttr tattr; - char *fontname, *font; - - if(rp == NULL) return NULL; - - switch(fstyle->family) - { - case PLOT_FONT_FAMILY_SANS_SERIF: - fontname = nsoption_charp(font_sans); - break; - case PLOT_FONT_FAMILY_SERIF: - fontname = nsoption_charp(font_serif); - break; - case PLOT_FONT_FAMILY_MONOSPACE: - fontname = nsoption_charp(font_mono); - break; - case PLOT_FONT_FAMILY_CURSIVE: - fontname = nsoption_charp(font_cursive); - break; - case PLOT_FONT_FAMILY_FANTASY: - fontname = nsoption_charp(font_fantasy); - break; - default: - return NULL; - break; - } - - tattr.ta_Style = FS_NORMAL; - - if (fstyle->flags & FONTF_OBLIQUE) - tattr.ta_Style = FSF_ITALIC; - - if (fstyle->flags & FONTF_ITALIC) - tattr.ta_Style = FSF_ITALIC; - - if (fstyle->weight >= 700) - tattr.ta_Style |= FSF_BOLD; - - if((font = ASPrintf("%s.font", fontname))) { - tattr.ta_Name = font; - tattr.ta_YSize = fstyle->size / FONT_SIZE_SCALE; - LOG("font: %s/%d", tattr.ta_Name, tattr.ta_YSize); - if((bmfont = OpenDiskFont(&tattr))) { - SetRPAttrs(rp, RPTAG_Font, bmfont, TAG_DONE); - } - FreeVec(font); - } - - return bmfont; -} - -static void ami_font_bm_close(struct TextFont *bmfont) -{ - CloseFont(bmfont); -} - -static size_t ami_font_bm_convert_local_to_utf8_offset(const char *utf8string, int length, size_t offset) -{ - size_t chr = 0; - - for(size_t i = 0; i < offset; i++) { - chr = utf8_next(utf8string, length, chr); - } - - return chr; -} - - -static bool amiga_bm_nsfont_width(const plot_font_style_t *fstyle, - const char *string, size_t length, - int *width) -{ - char *localtext = NULL; - - if((glob == NULL) || (glob->rp == NULL)) return false; - *width = length; - - struct TextFont *bmfont = ami_font_bm_open(glob->rp, fstyle); - if(bmfont == NULL) return false; - - if(utf8_to_local_encoding(string, length, &localtext) != NSERROR_OK) { - ami_font_bm_close(bmfont); - return false; - } - - *width = TextLength(glob->rp, localtext, strlen(localtext)); - free(localtext); - - ami_font_bm_close(bmfont); - - return true; -} - -/** - * Find the position in a string where an x coordinate falls. - * - * \param fstyle style for this text - * \param string UTF-8 string to measure - * \param length length of string - * \param x x coordinate to search for - * \param char_offset updated to offset in string of actual_x, [0..length] - * \param actual_x updated to x coordinate of character closest to x - * \return true on success, false on error and error reported - */ - -static bool amiga_bm_nsfont_position_in_string(const plot_font_style_t *fstyle, - const char *string, size_t length, - int x, size_t *char_offset, int *actual_x) -{ - struct TextExtent extent; - struct TextFont *bmfont; - char *localtext = NULL; - size_t co = 0; - - if((glob == NULL) || (glob->rp == NULL)) return false; - - bmfont = ami_font_bm_open(glob->rp, fstyle); - if(bmfont == NULL) return false; - - if(utf8_to_local_encoding(string, length, &localtext) != NSERROR_OK) { - ami_font_bm_close(bmfont); - return false; - } - - co = TextFit(glob->rp, localtext, strlen(localtext), - &extent, NULL, 1, x, 32767); - *char_offset = ami_font_bm_convert_local_to_utf8_offset(string, length, co); - *actual_x = extent.te_Extent.MaxX; - - free(localtext); - ami_font_bm_close(bmfont); - - return true; -} - - -/** - * Find where to split a string to make it fit a width. - * - * \param fstyle style for this text - * \param string UTF-8 string to measure - * \param length length of string - * \param x width available - * \param char_offset updated to offset in string of actual_x, [1..length] - * \param actual_x updated to x coordinate of character closest to x - * \return true on success, false on error and error reported - * - * On exit, char_offset indicates first character after split point. - * - * Note: char_offset of 0 should never be returned. - * - * Returns: - * char_offset giving split point closest to x, where actual_x <= x - * else - * char_offset giving split point closest to x, where actual_x > x - * - * Returning char_offset == length means no split possible - */ - -static bool amiga_bm_nsfont_split(const plot_font_style_t *fstyle, - const char *string, size_t length, - int x, size_t *char_offset, int *actual_x) -{ - struct TextExtent extent; - size_t co, offset; - char *charp; - char *localtext; - - if((glob == NULL) || (glob->rp == NULL)) return false; - - struct TextFont *bmfont = ami_font_bm_open(glob->rp, fstyle); - if(bmfont == NULL) return false; - - if(utf8_to_local_encoding(string, length, &localtext) != NSERROR_OK) { - ami_font_bm_close(bmfont); - return false; - } - - offset = TextFit(glob->rp, localtext, strlen(localtext), - &extent, NULL, 1, x, 32767); - - co = offset; - charp = localtext + co; - - - while((*charp != ' ') && (co > 0)) { - charp--; - co--; - } - - if(co == 0) { - co = offset; - charp = localtext + co; - while((*charp != ' ') && (co < strlen(localtext))) { - charp++; - co++; - } - } - - if((co > 0) && (co <= strlen(localtext))) { - *actual_x = TextLength(glob->rp, localtext, co); - *char_offset = ami_font_bm_convert_local_to_utf8_offset(string, length, co); - } else { - *actual_x = x; - *char_offset = length; - } - - free(localtext); - ami_font_bm_close(bmfont); - - return true; -} - -static ULONG amiga_bm_nsfont_text(struct RastPort *rp, const char *string, ULONG length, - const plot_font_style_t *fstyle, ULONG dx, ULONG dy, bool aa) -{ - if(!string || string[0]=='\0') return 0; - if(!length) return 0; - if(rp == NULL) return 0; - - struct TextFont *bmfont = ami_font_bm_open(rp, fstyle); - char *localtext = NULL; - if(bmfont == NULL) return 0; - if(utf8_to_local_encoding(string, length, &localtext) == NSERROR_OK) { - Move(rp, dx, dy); - Text(rp, localtext, strlen(localtext)); - free(localtext); - } - - ami_font_bm_close(bmfont); - - return 0; -} - -const struct ami_font_functions ami_font_diskfont_table = { - amiga_bm_nsfont_width, - amiga_bm_nsfont_position_in_string, - amiga_bm_nsfont_split, - amiga_bm_nsfont_text -}; - -void ami_font_diskfont_init(void) -{ - /* Set up table */ - ami_nsfont = &ami_font_diskfont_table; -} - diff --git a/amiga/font_bullet.c b/amiga/font_bullet.c index 72a2d90b2..2800533a0 100644 --- a/amiga/font_bullet.c +++ b/amiga/font_bullet.c @@ -32,6 +32,7 @@ #include #include "amiga/font.h" +#include "amiga/font_bullet.h" #include "amiga/font_cache.h" #include "amiga/font_scan.h" @@ -842,24 +843,9 @@ static inline ULONG ami_font_unicode_width(const char *string, ULONG length, return x; } -void ami_font_initscanner(bool force, bool save) -{ - ami_font_scan_init(nsoption_charp(font_unicode_file), force, save, glypharray); -} - -void ami_font_finiscanner(void) -{ - ami_font_scan_fini(glypharray); -} - -void ami_font_savescanner(void) -{ - ami_font_scan_save(nsoption_charp(font_unicode_file), glypharray); -} - -void ami_font_close(struct ami_font_cache_node *node) +void ami_font_bullet_close(void *nso) { - /* Called from FreeObjList if node type is AMINS_FONT */ + struct ami_font_cache_node *node = (struct ami_font_cache_node *)nso; CloseOutlineFont(node->font, &ami_diskfontlib_list); } @@ -891,3 +877,19 @@ void ami_font_bullet_fini(void) ami_font_finiscanner(); } +/* Font scanner */ +void ami_font_initscanner(bool force, bool save) +{ + ami_font_scan_init(nsoption_charp(font_unicode_file), force, save, glypharray); +} + +void ami_font_finiscanner(void) +{ + ami_font_scan_fini(glypharray); +} + +void ami_font_savescanner(void) +{ + ami_font_scan_save(nsoption_charp(font_unicode_file), glypharray); +} + diff --git a/amiga/font_cache.c b/amiga/font_cache.c index c94afb124..b036f6334 100644 --- a/amiga/font_cache.c +++ b/amiga/font_cache.c @@ -25,6 +25,7 @@ #include "utils/log.h" #include "amiga/font.h" +#include "amiga/font_bullet.h" #include "amiga/font_cache.h" #include "amiga/schedule.h" @@ -69,7 +70,7 @@ static void ami_font_cache_cleanup(struct SkipList *skiplist) if(curtime.Seconds > 300) { LOG("Freeing font %lx not used for %ld seconds", node->skip_node.sn_Key, curtime.Seconds); - ami_font_close(node); + ami_font_bullet_close(node); RemoveSkipNode(skiplist, node->skip_node.sn_Key); } } while((node = nnode)); @@ -113,12 +114,12 @@ static void ami_font_cache_del_skiplist(struct SkipList *skiplist) struct SkipNode *node; struct SkipNode *nnode; - node = (struct ami_font_cache_node *)GetFirstSkipNode(skiplist); + node = GetFirstSkipNode(skiplist); if(node == NULL) return; do { - nnode = GetNextSkipNode(skiplist, (struct SkipNode *)node); - ami_font_close(node); + nnode = GetNextSkipNode(skiplist, node); + ami_font_bullet_close((struct ami_font_cache_node *)node); } while((node = nnode)); @@ -170,6 +171,7 @@ void ami_font_cache_insert(struct ami_font_cache_node *nodedata, const char *fon #ifndef __amigaos4__ struct nsObject *node = AddObject(ami_font_cache_list, AMINS_FONT); if(node) { + ObjectCallback(ami_font_bullet_close); node->objstruct = nodedata; node->dtz_Node.ln_Name = strdup(font); } diff --git a/amiga/font_diskfont.c b/amiga/font_diskfont.c new file mode 100644 index 000000000..f48f0f465 --- /dev/null +++ b/amiga/font_diskfont.c @@ -0,0 +1,287 @@ +/* + * Copyright 2008 - 2016 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 +#include + +#include + +#include "utils/log.h" +#include "utils/utf8.h" +#include "utils/nsoption.h" +#include "desktop/font.h" + +#include "amiga/font.h" +#include "amiga/font_diskfont.h" +#include "amiga/gui.h" +#include "amiga/utf8.h" + +static struct TextFont *ami_font_bm_open(struct RastPort *rp, const plot_font_style_t *fstyle) +{ + struct TextFont *bmfont = NULL; + struct TextAttr tattr; + char *fontname, *font; + + if(rp == NULL) return NULL; + + switch(fstyle->family) + { + case PLOT_FONT_FAMILY_SANS_SERIF: + fontname = nsoption_charp(font_sans); + break; + case PLOT_FONT_FAMILY_SERIF: + fontname = nsoption_charp(font_serif); + break; + case PLOT_FONT_FAMILY_MONOSPACE: + fontname = nsoption_charp(font_mono); + break; + case PLOT_FONT_FAMILY_CURSIVE: + fontname = nsoption_charp(font_cursive); + break; + case PLOT_FONT_FAMILY_FANTASY: + fontname = nsoption_charp(font_fantasy); + break; + default: + return NULL; + break; + } + + tattr.ta_Style = FS_NORMAL; + + if (fstyle->flags & FONTF_OBLIQUE) + tattr.ta_Style = FSF_ITALIC; + + if (fstyle->flags & FONTF_ITALIC) + tattr.ta_Style = FSF_ITALIC; + + if (fstyle->weight >= 700) + tattr.ta_Style |= FSF_BOLD; + + if((font = ASPrintf("%s.font", fontname))) { + tattr.ta_Name = font; + tattr.ta_YSize = fstyle->size / FONT_SIZE_SCALE; + LOG("font: %s/%d", tattr.ta_Name, tattr.ta_YSize); + if((bmfont = OpenDiskFont(&tattr))) { + SetRPAttrs(rp, RPTAG_Font, bmfont, TAG_DONE); + } + FreeVec(font); + } + + return bmfont; +} + +static void ami_font_bm_close(struct TextFont *bmfont) +{ + CloseFont(bmfont); +} + +static size_t ami_font_bm_convert_local_to_utf8_offset(const char *utf8string, int length, size_t offset) +{ + size_t chr = 0; + + for(size_t i = 0; i < offset; i++) { + chr = utf8_next(utf8string, length, chr); + } + + return chr; +} + + +static bool amiga_bm_nsfont_width(const plot_font_style_t *fstyle, + const char *string, size_t length, + int *width) +{ + char *localtext = NULL; + + if((glob == NULL) || (glob->rp == NULL)) return false; + *width = length; + + struct TextFont *bmfont = ami_font_bm_open(glob->rp, fstyle); + if(bmfont == NULL) return false; + + if(utf8_to_local_encoding(string, length, &localtext) != NSERROR_OK) { + ami_font_bm_close(bmfont); + return false; + } + + *width = TextLength(glob->rp, localtext, strlen(localtext)); + free(localtext); + + ami_font_bm_close(bmfont); + + return true; +} + +/** + * Find the position in a string where an x coordinate falls. + * + * \param fstyle style for this text + * \param string UTF-8 string to measure + * \param length length of string + * \param x x coordinate to search for + * \param char_offset updated to offset in string of actual_x, [0..length] + * \param actual_x updated to x coordinate of character closest to x + * \return true on success, false on error and error reported + */ + +static bool amiga_bm_nsfont_position_in_string(const plot_font_style_t *fstyle, + const char *string, size_t length, + int x, size_t *char_offset, int *actual_x) +{ + struct TextExtent extent; + struct TextFont *bmfont; + char *localtext = NULL; + size_t co = 0; + + if((glob == NULL) || (glob->rp == NULL)) return false; + + bmfont = ami_font_bm_open(glob->rp, fstyle); + if(bmfont == NULL) return false; + + if(utf8_to_local_encoding(string, length, &localtext) != NSERROR_OK) { + ami_font_bm_close(bmfont); + return false; + } + + co = TextFit(glob->rp, localtext, strlen(localtext), + &extent, NULL, 1, x, 32767); + *char_offset = ami_font_bm_convert_local_to_utf8_offset(string, length, co); + *actual_x = extent.te_Extent.MaxX; + + free(localtext); + ami_font_bm_close(bmfont); + + return true; +} + + +/** + * Find where to split a string to make it fit a width. + * + * \param fstyle style for this text + * \param string UTF-8 string to measure + * \param length length of string + * \param x width available + * \param char_offset updated to offset in string of actual_x, [1..length] + * \param actual_x updated to x coordinate of character closest to x + * \return true on success, false on error and error reported + * + * On exit, char_offset indicates first character after split point. + * + * Note: char_offset of 0 should never be returned. + * + * Returns: + * char_offset giving split point closest to x, where actual_x <= x + * else + * char_offset giving split point closest to x, where actual_x > x + * + * Returning char_offset == length means no split possible + */ + +static bool amiga_bm_nsfont_split(const plot_font_style_t *fstyle, + const char *string, size_t length, + int x, size_t *char_offset, int *actual_x) +{ + struct TextExtent extent; + size_t co, offset; + char *charp; + char *localtext; + + if((glob == NULL) || (glob->rp == NULL)) return false; + + struct TextFont *bmfont = ami_font_bm_open(glob->rp, fstyle); + if(bmfont == NULL) return false; + + if(utf8_to_local_encoding(string, length, &localtext) != NSERROR_OK) { + ami_font_bm_close(bmfont); + return false; + } + + offset = TextFit(glob->rp, localtext, strlen(localtext), + &extent, NULL, 1, x, 32767); + + co = offset; + charp = localtext + co; + + + while((*charp != ' ') && (co > 0)) { + charp--; + co--; + } + + if(co == 0) { + co = offset; + charp = localtext + co; + while((*charp != ' ') && (co < strlen(localtext))) { + charp++; + co++; + } + } + + if((co > 0) && (co <= strlen(localtext))) { + *actual_x = TextLength(glob->rp, localtext, co); + *char_offset = ami_font_bm_convert_local_to_utf8_offset(string, length, co); + } else { + *actual_x = x; + *char_offset = length; + } + + free(localtext); + ami_font_bm_close(bmfont); + + return true; +} + +static ULONG amiga_bm_nsfont_text(struct RastPort *rp, const char *string, ULONG length, + const plot_font_style_t *fstyle, ULONG dx, ULONG dy, bool aa) +{ + if(!string || string[0]=='\0') return 0; + if(!length) return 0; + if(rp == NULL) return 0; + + struct TextFont *bmfont = ami_font_bm_open(rp, fstyle); + char *localtext = NULL; + if(bmfont == NULL) return 0; + if(utf8_to_local_encoding(string, length, &localtext) == NSERROR_OK) { + Move(rp, dx, dy); + Text(rp, localtext, strlen(localtext)); + free(localtext); + } + + ami_font_bm_close(bmfont); + + return 0; +} + +const struct ami_font_functions ami_font_diskfont_table = { + amiga_bm_nsfont_width, + amiga_bm_nsfont_position_in_string, + amiga_bm_nsfont_split, + amiga_bm_nsfont_text +}; + +void ami_font_diskfont_init(void) +{ + /* Set up table */ + ami_nsfont = &ami_font_diskfont_table; +} + diff --git a/amiga/gui_options.c b/amiga/gui_options.c index cfa78e8ca..7e800d298 100755 --- a/amiga/gui_options.c +++ b/amiga/gui_options.c @@ -65,6 +65,7 @@ #include "amiga/file.h" #include "amiga/font.h" +#include "amiga/font_bullet.h" #include "amiga/gui.h" #include "amiga/gui_options.h" #include "amiga/help.h" diff --git a/amiga/object.c b/amiga/object.c index 64c8e72db..7d935943e 100755 --- a/amiga/object.c +++ b/amiga/object.c @@ -24,8 +24,6 @@ #include #include -#include "amiga/filetype.h" -#include "amiga/font.h" #include "amiga/misc.h" #include "amiga/object.h" @@ -72,11 +70,15 @@ struct nsObject *AddObject(struct MinList *objlist, ULONG otype) return(dtzo); } +void ObjectCallback(struct nsObject *dtzo, void (*callback)(void *nso)) +{ + dtzo->callback = callback; +} + static void DelObjectInternal(struct nsObject *dtzo, BOOL free_obj) { Remove((struct Node *)dtzo); - if(dtzo->Type == AMINS_FONT) ami_font_close(dtzo->objstruct); - if(dtzo->Type == AMINS_MIME) ami_mime_entry_free(dtzo->objstruct); + if(dtzo->callback != NULL) dtzo->callback(dtzo->objstruct); if(dtzo->objstruct && free_obj) FreeVec(dtzo->objstruct); if(dtzo->dtz_Node.ln_Name) free(dtzo->dtz_Node.ln_Name); FreeVec(dtzo); diff --git a/amiga/object.h b/amiga/object.h index 27f60fc9a..85cbb6d52 100755 --- a/amiga/object.h +++ b/amiga/object.h @@ -44,11 +44,13 @@ struct nsObject ULONG Type; void *objstruct; ULONG objstruct_size; + void (*callback)(void *nso); }; struct MinList *NewObjList(void); struct nsObject *AddObject(struct MinList *objlist, ULONG otype); +void ObjectCallback(struct nsObject *dtzo, void (*callback)(void *nso)); void DelObject(struct nsObject *dtzo); void DelObjectNoFree(struct nsObject *dtzo); void FreeObjList(struct MinList *objlist); diff --git a/amiga/options.h b/amiga/options.h index 728f6d4d1..6214c702d 100644 --- a/amiga/options.h +++ b/amiga/options.h @@ -63,7 +63,7 @@ NSOPTION_STRING(font_surrogate, NULL) NSOPTION_STRING(font_unicode_file, NULL) NSOPTION_BOOL(font_unicode_only, false) NSOPTION_BOOL(font_antialiasing, true) -NSOPTION_BOOL(use_diskfont, false) +NSOPTION_BOOL(bitmap_fonts, false) NSOPTION_BOOL(drag_save_icons, true) NSOPTION_INTEGER(hotlist_window_xpos, 0) NSOPTION_INTEGER(hotlist_window_ypos, 0) diff --git a/amiga/plotters.c b/amiga/plotters.c index ea13285d7..b459dcc7e 100644 --- a/amiga/plotters.c +++ b/amiga/plotters.c @@ -45,6 +45,7 @@ #include "amiga/bitmap.h" #include "amiga/font.h" #include "amiga/gui.h" +#include "amiga/misc.h" #include "amiga/rtg.h" #include "amiga/utf8.h" -- cgit v1.2.3