From ed6ceaa49c92e20aa87eca90ec16db21ff6bbed8 Mon Sep 17 00:00:00 2001 From: Vincent Wei Date: Tue, 26 Mar 2019 12:22:26 +0800 Subject: [PATCH] fixbug of layout implementation --- include/window.h | 2 +- src/font/logfont.c | 3 + src/newgdi/layout-utils.c | 15 ++- src/newgdi/layoutinfo.c | 12 ++- src/sysres/resmgr.c | 201 +++++++++++++++++++------------------- 5 files changed, 128 insertions(+), 105 deletions(-) diff --git a/include/window.h b/include/window.h index d23da441..b9b5ed19 100644 --- a/include/window.h +++ b/include/window.h @@ -4865,7 +4865,7 @@ MG_EXPORT void* GetResource (RES_KEY key); * * When you get a resource, you should call this function to ensure that * the resource can not be unloaded when you still use it. - * This function must be called after LoadResource. + * This function must be called after GetResource. * * \param key The key of resource (use Str2Key(res_name) to get the key). * diff --git a/src/font/logfont.c b/src/font/logfont.c index 488d5d6a..a9a23c4e 100644 --- a/src/font/logfont.c +++ b/src/font/logfont.c @@ -41,6 +41,8 @@ #include #include +#define DEBUG + #include "common.h" #include "minigui.h" #include "gdi.h" @@ -123,6 +125,7 @@ static PLOGFONT gdiCreateLogFont (const char* type, const char* family, if ((newlf = (PLOGFONT)calloc(sizeof (FONT_RES), 1)) == NULL) return INV_LOGFONT; + ((FONT_RES *)newlf)->key = -1; newlf->style = style; diff --git a/src/newgdi/layout-utils.c b/src/newgdi/layout-utils.c index e9438d3a..3f073d92 100644 --- a/src/newgdi/layout-utils.c +++ b/src/newgdi/layout-utils.c @@ -101,6 +101,9 @@ LOGFONT* __mg_create_logfont_for_layout(const LAYOUTINFO* layout, return NULL; } + _DBG_PRINTF("%s: calling LoadResource for LOGFONT: %s\n", + __FUNCTION__, my_fontname); + lf = (LOGFONT*)LoadResource(my_fontname, RES_TYPE_FONT, 0); if (lf == NULL) { _ERR_PRINTF("%s: failed to create LOGFONT for layout: %p\n", @@ -218,9 +221,14 @@ LayoutRun* __mg_layout_run_new_from_offset(const LAYOUTINFO* layout, void __mg_layout_run_free(LayoutRun* lrun) { + _DBG_PRINTF("%s: called for %p\n", + __FUNCTION__, lrun); + if (lrun->lf) { FONT_RES* font_res = (FONT_RES*)lrun->lf; - ReleaseRes(font_res->key); + // FIXME + if (font_res->key) + ReleaseRes(font_res->key); } free(lrun); @@ -236,6 +244,11 @@ LayoutRun* __mg_layout_run_copy(const LayoutRun* lrun) result = malloc(sizeof(LayoutRun)); memcpy(result, lrun, sizeof(LayoutRun)); + // must increase the reference count of LOGFONT + if (result->lf) { + FONT_RES* font_res = (FONT_RES*)result->lf; + AddResRef(font_res->key); + } return result; } diff --git a/src/newgdi/layoutinfo.c b/src/newgdi/layoutinfo.c index 783f20a6..610baec6 100644 --- a/src/newgdi/layoutinfo.c +++ b/src/newgdi/layoutinfo.c @@ -1625,6 +1625,11 @@ LAYOUTLINE* GUIAPI LayoutNextLine( } } + if (prev_line) { + release_line(prev_line); + prev_line = NULL; + } + state.line_width = max_extent; state.remaining_width = max_extent; @@ -1634,15 +1639,16 @@ LAYOUTLINE* GUIAPI LayoutNextLine( if (layout->persist) { list_add_tail(&next_line->list, &layout->lines); } - else if (prev_line) { - release_line(prev_line); - } layout->nr_lines++; layout->nr_left_ucs -= next_line->len; } out: + if (prev_line) { + release_line(prev_line); + } + if (next_line && cb_laid_out) { traverse_line_glyphs(next_line, x, y, cb_laid_out, ctxt); } diff --git a/src/sysres/resmgr.c b/src/sysres/resmgr.c index 5675c8b7..0788596b 100644 --- a/src/sysres/resmgr.c +++ b/src/sysres/resmgr.c @@ -54,6 +54,7 @@ #include #endif +#define DEBUG #include "common.h" #include "minigui.h" @@ -768,7 +769,9 @@ void* LoadResource(const char* res_name, int type, DWORD usr_param) SetUsed(entry); } - entry->refcnt ++ ; + entry->refcnt++; + _DBG_PRINTF("%s: reference count for %p: %d\n", + __FUNCTION__, entry, entry->refcnt); data = get_res_data(entry, ti->ops, usr_param); if(GetSourceType(entry) == REF_SRC_FILE) @@ -818,7 +821,7 @@ int AddResRef(RES_KEY key) return -1; #endif } - return ++entry->refcnt ; + return ++entry->refcnt; } static void delete_entry(HASH_TABLE *table, RES_ENTRY* entry) @@ -826,10 +829,10 @@ static void delete_entry(HASH_TABLE *table, RES_ENTRY* entry) if(entry == NULL) return; - if(IsUsed(entry) && entry->data != NULL) - { + if(IsUsed(entry) && entry->data != NULL) { delete_entry_data(entry); } + if(!(GetSourceType(entry) == REF_SRC_INNER && !IsInnerResCopyed(entry))) remove_entry(table, entry->key); @@ -841,12 +844,17 @@ int ReleaseRes(RES_KEY key) RES_ENTRY *entry = NULL; RES_LOCK(); entry = get_entry(&hash_table, key, FALSE); - if(entry == NULL){ + if (entry == NULL){ RES_UNLOCK(); return -1; } + ref = --entry->refcnt; - if(ref <= 0) + + _DBG_PRINTF("%s: reference count for %p: %d\n", + __FUNCTION__, entry, entry->refcnt); + + if (ref <= 0) delete_entry(&hash_table, entry); RES_UNLOCK(); return ref; @@ -900,47 +908,46 @@ static void res_error(int type, const char* funcname, const char* strinfo, ... ) //ops static void* img_get_res_data(RESOURCE* res, int src_type, DWORD usr_param) { - if(res == NULL) + if (res == NULL) return NULL; - if(res->data == NULL) - { + if (res->data == NULL) { //source is null - if(res->source.src == NULL) + if (res->source.src == NULL) return NULL; - switch(src_type) - { - case REF_SRC_FILE: - { - BITMAP *pbmp; - pbmp = NEW(BITMAP); - if(LoadBitmapFromFile((HDC)usr_param, pbmp, res->source.file) != 0) - { + switch(src_type) { + case REF_SRC_FILE: { + BITMAP *pbmp; + pbmp = NEW(BITMAP); + if (LoadBitmapFromFile((HDC)usr_param, pbmp, + res->source.file) != 0) { + DELETE(pbmp); + return NULL; + } + res->data = pbmp; + break; + } + + case REF_SRC_INNER: { + INNER_RES* inner = res->source.inner; + if(inner->additional == NULL) { + // raw bitmap + res->data = inner->data; + } + else { + BITMAP *pbmp = NEW(BITMAP); + if (LoadBitmapFromMem((HDC)usr_param, pbmp, + inner->data, inner->data_len, + (const char*)inner->additional) != 0) { DELETE(pbmp); return NULL; } res->data = pbmp; - break; - } - case REF_SRC_INNER: - { - INNER_RES* inner = res->source.inner; - if(inner->additional == NULL) //raw bitmap - { - res->data = inner->data; - } - else { - BITMAP *pbmp = NEW(BITMAP); - if(LoadBitmapFromMem((HDC)usr_param, pbmp, inner->data, inner->data_len, (const char*)inner->additional) != 0) - { - DELETE(pbmp); - return NULL; - } - res->data = pbmp; - } - break; } + break; + } + default: return NULL; } @@ -949,15 +956,17 @@ static void* img_get_res_data(RESOURCE* res, int src_type, DWORD usr_param) return res->data; } -static void img_unload(RESOURCE* res, int src_type) +static void img_unload (RESOURCE* res, int src_type) { - if(res && res->data){ - if((src_type == REF_SRC_FILE) - || (src_type == REF_SRC_INNER - && (res->source.inner && res->source.inner->additional != NULL))){ + if (res && res->data) { + if ((src_type == REF_SRC_FILE) || + (src_type == REF_SRC_INNER + && (res->source.inner && + res->source.inner->additional != NULL))) { UnloadBitmap(res->data); DELETE(res->data); } + res->data = NULL; } } @@ -1082,24 +1091,20 @@ static void icon_unload(RESOURCE* res, int src_type) static void* icon_get_res_data(RESOURCE* res, int src_type, DWORD usr_param) { - if(res == NULL) + if (res == NULL) return NULL; - if(res->data==NULL) - { + if (res->data==NULL) { HICON hIcon = 0; - if(res->source.src == NULL) + if (res->source.src == NULL) return NULL; - switch(src_type) - { - case REF_SRC_FILE: - { + switch(src_type) { + case REF_SRC_FILE: { hIcon = LoadIconFromFile((HDC)usr_param, res->source.file, 0); break; } - case REF_SRC_INNER: - { + case REF_SRC_INNER: { hIcon = LoadIconFromMem((HDC)usr_param, res->source.inner->data, 0); break; } @@ -1114,34 +1119,31 @@ static void* icon_get_res_data(RESOURCE* res, int src_type, DWORD usr_param) static void icon_unload(RESOURCE* res, int src_type) { - if(res && res->data) + if (res && res->data) DestroyIcon((HICON)res->data); } - #ifdef _MGHAVE_CURSOR static void* cursor_get_res_data(RESOURCE* res, int src_type, DWORD usr_param) { - if(res == NULL) + if (res == NULL) return NULL; - if(res->data == NULL) - { + if (res->data == NULL) { if(res->source.src == NULL) return NULL; - switch(src_type) - { - case REF_SRC_FILE: - { + switch(src_type) { + case REF_SRC_FILE: { res->data =(void*) LoadCursorFromFile(res->source.file); break; } - case REF_SRC_INNER: - { + + case REF_SRC_INNER: { res->data = (void*)LoadCursorFromMem(res->source.inner->data); break; } + default: return NULL; } @@ -1152,7 +1154,7 @@ static void* cursor_get_res_data(RESOURCE* res, int src_type, DWORD usr_param) static void cursor_unload(RESOURCE* res, int src_type) { - if(res && res->data){ + if (res && res->data) { DestroyCursor((HCURSOR)res->data); } } @@ -1161,18 +1163,15 @@ static void cursor_unload(RESOURCE* res, int src_type) static void* etc_get_res_data(RESOURCE* res, int src_type, DWORD usr_param) { - if(res == NULL) + if (res == NULL) return NULL; - if(res->data == NULL) - { - if(res->source.src == NULL) + if (res->data == NULL) { + if (res->source.src == NULL) return NULL; - switch(src_type) - { - case REF_SRC_FILE: - { + switch(src_type) { + case REF_SRC_FILE: { res->data = (void*)LoadEtcFile(res->source.file); break; } @@ -1189,7 +1188,7 @@ static void* etc_get_res_data(RESOURCE* res, int src_type, DWORD usr_param) static void etc_unload(RESOURCE* res, int src_type) { - if(res->data && src_type == REF_SRC_FILE) + if (res->data && src_type == REF_SRC_FILE) UnloadEtcFile((GHANDLE)res->data); } @@ -1197,53 +1196,52 @@ static void etc_unload(RESOURCE* res, int src_type) //binery static void* mem_get_res_data(RESOURCE* res, int src_type, DWORD usr_param) { - if(res == NULL) + if (res == NULL) return NULL; - if(res->data == NULL) - { - if(res->source.src == NULL) + if (res->data == NULL) { + if (res->source.src == NULL) return NULL; - switch(src_type) - { - case REF_SRC_INNER: - { - res->data = (MEM_RES*)&(res->source.inner->data); - break; - } + switch (src_type) { + case REF_SRC_INNER: { + res->data = (MEM_RES*)&(res->source.inner->data); + break; + } default: return NULL; } } + return res->data; } static void mem_unload(RESOURCE* res, int src_type) { - if(res) + if (res) res->data = NULL; } static void* font_get_res_data(RESOURCE* res, int src_type, DWORD usr_param) { - if(res == NULL) + if (res == NULL) return NULL; - if(res->data == NULL) - { - if(res->source.src == NULL) + if (res->data == NULL) { + if (res->source.src == NULL) return NULL; - if (src_type == REF_SRC_LOGIC) - { + if (src_type == REF_SRC_LOGIC) { char *font_name = (char *)res->source.file; PLOGFONT p = CreateLogFontByName(font_name); - FONT_RES *data = (FONT_RES *)malloc(sizeof(FONT_RES)); - memcpy(&data->logfont, p, sizeof(LOGFONT)); - data->key = ((RES_ENTRY *)res)->key; - free(p); - res->data = data; + if (p) { + FONT_RES* data = (FONT_RES*)p; + data->key = ((RES_ENTRY *)res)->key; + res->data = data; + } + else { + res->data = NULL; + } } } @@ -1252,9 +1250,12 @@ static void* font_get_res_data(RESOURCE* res, int src_type, DWORD usr_param) static void font_unload(RESOURCE* res, int src_type) { - FONT_RES *data = (FONT_RES *)res->data; - //FIXME, .... how to destroy the log font ??? - DestroyLogFont (&data->logfont); - //free(data); + if (res && res->data) { + FONT_RES *data = (FONT_RES *)res->data; + _DBG_PRINTF("%s: LOGFONT %p will be destroyed\n", + __FUNCTION__, &data->logfont); + DestroyLogFont(&data->logfont); + res->data = NULL; + } }