diff --git a/src/font/fontcache.c b/src/font/fontcache.c index 0804bade..cedc41b8 100644 --- a/src/font/fontcache.c +++ b/src/font/fontcache.c @@ -1,60 +1,60 @@ /* - * This file is part of MiniGUI, a mature cross-platform windowing + * This file is part of MiniGUI, a mature cross-platform windowing * and Graphics User Interface (GUI) support system for embedded systems * and smart IoT devices. - * + * * Copyright (C) 2002~2018, Beijing FMSoft Technologies Co., Ltd. * Copyright (C) 1998~2002, WEI Yongming - * + * * This program 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, either version 3 of the License, or * (at your option) any later version. - * + * * This program 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 . - * + * * Or, - * + * * As this program is a library, any link to this program must follow * GNU General Public License version 3 (GPLv3). If you cannot accept * GPLv3, you need to be licensed from FMSoft. - * + * * If you have got a commercial license of this program, please use it * under the terms and conditions of the commercial license. - * + * * For more information about the commercial license, please refer to * . */ /* ** fontcache.c: Font cache for TrueType fonts. -** +** ** Create date: 2006/02/01 */ #include #include #include - + #include "common.h" #ifdef _MGFONT_TTF_CACHE #include "minigui.h" #include "gdi.h" -#ifdef _MGFONT_TTF +#ifdef _MGFONT_TTF #include #include #include #include #include #include "freetype.h" -#else +#else #include "freetype2.h" #endif @@ -62,14 +62,14 @@ typedef struct _MemBlk { void *data; - int len; - struct _MemBlk *hashPrev; + int len; + struct _MemBlk *hashPrev; struct _MemBlk *hashNext; - struct _MemBlk *lruPrev; + struct _MemBlk *lruPrev; struct _MemBlk *lruNext; }MemBlk; -typedef MemBlk LruQueueDummyHead; +typedef MemBlk LruQueueDummyHead; typedef MemBlk HashQueueDummyHead; /* hash directory array in every cache */ @@ -82,20 +82,20 @@ typedef struct _HashDirectory blkSize : the size of each block in cache(in byte) nBlk : how many blocks in cache nDir : how many directory entries in cache - *memPool : the memory pool(data use it) pointer. - *lruQueueNodes : point all nodes by malloc. just - release function use it + *memPool : the memory pool(data use it) pointer. + *lruQueueNodes : point all nodes by malloc. just + release function use it *hashDir : the hash directory pointer - lruQueueDummyHead : head node of lru queue + lruQueueDummyHead : head node of lru queue makeHashKeyFunc : the function which make hash key */ typedef struct cache -{ +{ /* Information about font */ - char family[LEN_FONT_NAME + 1]; - char charset[LEN_FONT_NAME + 1]; - DWORD style; + char df_name[LEN_UNIDEVFONT_NAME + 1]; + int style; int fontsize; - + int rotation; + int refers; int blkSize; int nBlk; @@ -111,7 +111,7 @@ typedef struct cache global cache LRU queue */ typedef struct _CacheQueueNode { - /* hold global cache queue + /* hold global cache queue max cache node maybe 10 */ cache_t cache; struct _CacheQueueNode *prevCache; @@ -121,15 +121,15 @@ typedef struct _CacheQueueNode /* cache system. global cache descriptor, but user don't touch it, we use it! queueDummyHead : the head node of cache queue. - + maxCache : the max count of cache in programm - cacheSize : each cache's size(in BYTE and - everyone has the same size!) + cacheSize : each cache's size(in BYTE and + everyone has the same size!) nCache : how many cache Now!! */ struct _CacheSystem { CacheQueueNode queueDummyHead; - + int maxCache; int cacheSize; int nCache; @@ -141,7 +141,7 @@ struct _CacheSystem __mg_globalCache; /* functions */ -static void +static void AppendCache(CacheQueueNode *new) { new->nextCache = &(__mg_globalCache.queueDummyHead); @@ -151,18 +151,18 @@ AppendCache(CacheQueueNode *new) } /* create a new LRU-Queue. */ -static int +static int CreateCacheLruQueue(cache_t *cache, int nblk) { int i; MemBlk *blk; - + blk = malloc(nblk * sizeof(MemBlk)); DP(("Allocate cache %p LRU == %p\n", cache, blk)); if (blk == NULL) { return -1; } - + memset(blk, 0, nblk * sizeof(MemBlk)); cache->lruQueueNodes = blk; /* link the node as a double-linked-loop-list */ @@ -174,17 +174,17 @@ CreateCacheLruQueue(cache_t *cache, int nblk) } (blk + nblk - 1)->lruPrev = blk + nblk - 2; (blk + nblk - 1)->lruNext = &cache->lruQueueDummyHead; - + cache->lruQueueDummyHead.lruPrev = blk + nblk - 1; cache->lruQueueDummyHead.lruNext = blk; return 0; } -static int +static int InitCache(CacheQueueNode *new, int ndir, int nblock) { int i; - /* allocate Hash directory array and LRU queue nodes + /* allocate Hash directory array and LRU queue nodes follow code is bad, but no way to fix it. */ if (new->cache.hashDir) { free(new->cache.hashDir); @@ -195,18 +195,18 @@ InitCache(CacheQueueNode *new, int ndir, int nblock) if (new->cache.hashDir == NULL) { return -1; } - + memset(new->cache.hashDir, 0, ndir * sizeof(HashDirectory)); for (i = 0; i < ndir; i++) { - new->cache.hashDir[i].hashHead.hashPrev = + new->cache.hashDir[i].hashHead.hashPrev = &(new->cache.hashDir[i].hashHead); - new->cache.hashDir[i].hashHead.hashNext = + new->cache.hashDir[i].hashHead.hashNext = &(new->cache.hashDir[i].hashHead); } - if (new->cache.lruQueueDummyHead.lruNext != + if (new->cache.lruQueueDummyHead.lruNext != &(new->cache.lruQueueDummyHead)) { - /* It's a old node, not malloced, + /* It's a old node, not malloced, so we must release the old LRU-queue */ free(new->cache.lruQueueNodes); DP(("free a old lru. %p\n", new->cache.lruQueueNodes)); @@ -216,7 +216,7 @@ InitCache(CacheQueueNode *new, int ndir, int nblock) free(new->cache.lruQueueNodes); DP(("free a old lru. %p\n", new->cache.lruQueueNodes)); } - return -1; + return -1; } return 0; @@ -235,10 +235,10 @@ LruQueueBufferSplit(cache_t *cache, int bufsize) blk->data = buff; blk = blk->lruNext; buff = buff + bufsize; - } + } } -static void +static void DestroyCache(cache_t *cache) { if (cache->hashDir != NULL) { @@ -257,7 +257,7 @@ DestroyCache(cache_t *cache) /* release a cache node from the global LRU cache queue. Free the memory and unlink the pointers. */ -static void +static void ReleaseCache(CacheQueueNode *cache) { /* Re-Link the double link queue */ @@ -273,26 +273,26 @@ ReleaseCache(CacheQueueNode *cache) /* allocate a new cache and append at the end of the global cache queue. * If global cache queue is full, we should kill the first node of the queue, * and we call this : Least-Recently-Used-Order - * If global cache is not full, just allocate a new one. + * If global cache is not full, just allocate a new one. * the func return pointer to the cache if succeed, return NULL means failed. */ static CacheQueueNode * GetCache(int nblock, int ndir) { CacheQueueNode *temp; - + if (__mg_globalCache.nCache == __mg_globalCache.maxCache) { - /* The Queue is Full!! in this case, we don't + /* The Queue is Full!! in this case, we don't release any node, just return NULL */ return NULL; } - /* there is empty space in the queue - we should allocate a new CacheQueueNode and + /* there is empty space in the queue + we should allocate a new CacheQueueNode and allocate Memory-Pool for it */ if ((temp = malloc(sizeof(CacheQueueNode))) == NULL) { return NULL; } DP(("New a cache node %p\n", temp)); - /* Set zero the new CacheQueueNode + /* Set zero the new CacheQueueNode and link the head to itself */ memset(temp, 0, sizeof(CacheQueueNode)); temp->cache.lruQueueDummyHead.lruPrev = &(temp->cache.lruQueueDummyHead); @@ -305,8 +305,8 @@ GetCache(int nblock, int ndir) return NULL; } __mg_globalCache.nCache++; - - /* init hash directory, lru-queue + + /* init hash directory, lru-queue the function should release the old hash directory and lru-queue and allocate new one. */ if (InitCache(temp, ndir, nblock) == -1) { @@ -324,47 +324,47 @@ GetCache(int nblock, int ndir) } -/* Pick-off a block from the head of cache's +/* Pick-off a block from the head of cache's lru-queue and also Hash queue(anywhere in hash q). Relink the lru queue and hash queue */ static MemBlk * PickOffBlk(cache_t *cache) { MemBlk *blk; - - if (cache->lruQueueDummyHead.lruNext == + + if (cache->lruQueueDummyHead.lruNext == &cache->lruQueueDummyHead) { return NULL; } - /* get the head of the lru-queue - it is a Least-Recently-Used-Order Node + /* get the head of the lru-queue + it is a Least-Recently-Used-Order Node and we should re-link the queue */ blk = cache->lruQueueDummyHead.lruNext; - - cache->lruQueueDummyHead.lruNext= + + cache->lruQueueDummyHead.lruNext= (cache->lruQueueDummyHead.lruNext)->lruNext; - (cache->lruQueueDummyHead.lruNext)->lruPrev = + (cache->lruQueueDummyHead.lruNext)->lruPrev = &cache->lruQueueDummyHead; - /* we pick the block, and if the block already + /* we pick the block, and if the block already in a hash q, so we must re-link the hash q */ if (blk->hashNext && blk->hashPrev) { blk->hashNext->hashPrev = blk->hashPrev; - blk->hashPrev->hashNext = blk->hashNext; + blk->hashPrev->hashNext = blk->hashNext; } return blk; } -static void +static void AppendBlk(cache_t *cache, MemBlk *blk, int key) { - /* first, append the blcok at the end of the + /* first, append the blcok at the end of the lru-queue. */ blk->lruNext = &(cache->lruQueueDummyHead); blk->lruPrev = cache->lruQueueDummyHead.lruPrev; (cache->lruQueueDummyHead.lruPrev)->lruNext = blk; cache->lruQueueDummyHead.lruPrev = blk; - - /* Then, insert the block at the head of + + /* Then, insert the block at the head of the hash queue which KEY==key */ blk->hashNext = cache->hashDir[key].hashHead.hashNext; (cache->hashDir[key].hashHead.hashNext)->hashPrev = blk; @@ -378,13 +378,13 @@ AppendBlk(cache_t *cache, MemBlk *blk, int key) /********************************************************** * extern functions * **********************************************************/ -/* search a data in cache, +/* search a data in cache, hCache : which cache *cmpdata : your data pointer point to data for compare *size : if found the data, how long is the data(return val) - reutrn = pointer to the data */ + reutrn = pointer to the data */ TTFCACHEINFO * -__mg_ttc_search(HCACHE hCache, unsigned short unicode, int *size) +__mg_ttc_search(HCACHE hCache, UChar32 unicode, int *size) { int key; CacheQueueNode *ca; @@ -400,9 +400,10 @@ __mg_ttc_search(HCACHE hCache, unsigned short unicode, int *size) } blk = ca->cache.hashDir[key].hashHead.hashNext; - for ( ; blk != &(ca->cache.hashDir[key].hashHead); + for ( ; blk != &(ca->cache.hashDir[key].hashHead); blk = blk->hashNext) { - if (*(unsigned short *)(blk->data) == unicode) { + TTFCACHEINFO * tci = (TTFCACHEINFO *)blk->data; + if (tci->unicode == unicode) { /* If found the blk, we should pick off it and link it at the end of LRU-q */ *size = blk->len; @@ -412,23 +413,24 @@ __mg_ttc_search(HCACHE hCache, unsigned short unicode, int *size) blk->lruPrev = ca->cache.lruQueueDummyHead.lruPrev; (ca->cache.lruQueueDummyHead.lruPrev)->lruNext = blk; ca->cache.lruQueueDummyHead.lruPrev = blk; - return blk->data; + return tci; } } + return NULL; } -/* add data into a speicial cache - hCache : which cache , +/* add data into a speicial cache + hCache : which cache , *data : your data pointer size : your data's bytes key : hash key of your data */ -int +int __mg_ttc_write(HCACHE hCache, TTFCACHEINFO *data, int size) { CacheQueueNode *ca; MemBlk *blk; - int key; + int key; if (hCache == 0 || data == NULL) { return -1; @@ -437,19 +439,19 @@ __mg_ttc_write(HCACHE hCache, TTFCACHEINFO *data, int size) if (ca->cache.blkSize < size) { return -1; } - key = ca->cache.makeHashKeyFunc(*(unsigned short *)data); - + key = ca->cache.makeHashKeyFunc(data->unicode); + /* pick off a block from lru queue */ if ((blk = PickOffBlk(&ca->cache)) == NULL) { return -1; } /* 1. copy the TTFCACHEINFO structure - 2. copy the BITMAP data by data->bitmap + 2. copy the BITMAP data by data->bitmap 3. change the bitmap pointer */ memcpy(blk->data, data, sizeof(TTFCACHEINFO)); if (data->bitmap) - memcpy((blk->data + sizeof(TTFCACHEINFO)), - data->bitmap, + memcpy((blk->data + sizeof(TTFCACHEINFO)), + data->bitmap, (size - sizeof(TTFCACHEINFO))); blk->len = size; ((TTFCACHEINFO *)(blk->data))->bitmap = blk->data + sizeof(TTFCACHEINFO); @@ -458,17 +460,17 @@ __mg_ttc_write(HCACHE hCache, TTFCACHEINFO *data, int size) return 0; } -/* create a cache for a font instance. +/* create a cache for a font instance. nblk : how many block in the cache. blks ize : each block's size ndir : how many hash entries in the cache makeHashKey : the function which make the hash key */ -HCACHE -__mg_ttc_create(char *family, char *charset, DWORD style, int size, +HCACHE +__mg_ttc_create(const char *df_name, int style, int size, int rotation, int nblk, int blksize, int ndir, MakeHashKeyFunc makeHashKey) { CacheQueueNode *temp; - if (family == NULL || charset == NULL || makeHashKey == NULL) { + if (df_name == NULL || makeHashKey == NULL) { return (HCACHE)(0); } if (nblk <= 0 || blksize <= 0 || size <= 0 || ndir <= 0) { @@ -482,10 +484,11 @@ __mg_ttc_create(char *family, char *charset, DWORD style, int size, return (HCACHE)(0); } - strncpy(temp->cache.family, family, LEN_FONT_NAME); - strncpy(temp->cache.charset, charset, LEN_FONT_NAME); + memset(temp->cache.df_name, 0, LEN_UNIDEVFONT_NAME + 1); + strncpy(temp->cache.df_name, df_name, LEN_UNIDEVFONT_NAME); temp->cache.style = style; temp->cache.fontsize = size; + temp->cache.rotation = rotation; temp->cache.blkSize = blksize; temp->cache.nBlk = nblk; temp->cache.nDir = ndir; @@ -496,7 +499,7 @@ __mg_ttc_create(char *family, char *charset, DWORD style, int size, return (HCACHE)(temp); } -void +void __mg_ttc_refer(HCACHE hCache) { CacheQueueNode *ca; @@ -504,10 +507,10 @@ __mg_ttc_refer(HCACHE hCache) return; } ca = (CacheQueueNode *)(hCache); - ca->cache.refers++; + ca->cache.refers++; } -void +void __mg_ttc_release(HCACHE hCache) { CacheQueueNode *ca; @@ -522,13 +525,13 @@ __mg_ttc_release(HCACHE hCache) ReleaseCache(ca); free(ca); DP(("Free cache==%p\n", ca)); - __mg_globalCache.nCache--; + __mg_globalCache.nCache--; } } /* init cache system, create cache queue, and clear cache counter, if need use cache, should call this function first */ -int +int __mg_ttc_sys_init(int maxCache, int cacheSize) { if (maxCache <= 0 || cacheSize <= 0) { @@ -543,27 +546,27 @@ __mg_ttc_sys_init(int maxCache, int cacheSize) } -void +void __mg_ttc_sys_deinit(void) { CacheQueueNode *q, *pfree; - + if (__mg_globalCache.nCache == 0) { - /* it means just no cache in our system, - no malloc at all, just set zero global val + /* it means just no cache in our system, + no malloc at all, just set zero global val and return safe :) */ memset(&__mg_globalCache, 0, sizeof(__mg_globalCache)); return; } - /* In this case, it means more than ONE cache in - our system. we should release follow structures: + /* In this case, it means more than ONE cache in + our system. we should release follow structures: a. every CacheQueueNode(s) in global cache queue - b. every Memory-Pool in every cache + b. every Memory-Pool in every cache c. every Hash-Directory in every cache - d. every LRU queue nodes in every cache + d. every LRU queue nodes in every cache that's all, may be~~ :( */ q = __mg_globalCache.queueDummyHead.nextCache; - + while (q != &__mg_globalCache.queueDummyHead) { pfree = q; q = q->nextCache; @@ -575,34 +578,23 @@ __mg_ttc_sys_deinit(void) -HCACHE -__mg_ttc_is_exist(char *family, char *charset, DWORD style, int size) +HCACHE +__mg_ttc_is_exist(const char *df_name, int style, int size, int rotation) { CacheQueueNode *p; if (__mg_globalCache.nCache == 0) { return (HCACHE)0; } - + /* If can not match font name*/ p = __mg_globalCache.queueDummyHead.nextCache; while (p != &__mg_globalCache.queueDummyHead) { - if (strncmp(p->cache.family, family, LEN_FONT_NAME) == 0) { - if (strncmp(p->cache.charset, charset, LEN_FONT_NAME) == 0) { - if (p->cache.fontsize == size) { - int s = style & 0x000000FF; - if ((s == FS_WEIGHT_BOOK || s == FS_WEIGHT_DEMIBOLD || s == FS_WEIGHT_SUBPIXEL) && - (p->cache.style == FS_WEIGHT_BOOK || p->cache.style == FS_WEIGHT_DEMIBOLD || - p->cache.style == FS_WEIGHT_SUBPIXEL)) { - return (HCACHE) p; - } - if ((s != FS_WEIGHT_BOOK && s != FS_WEIGHT_DEMIBOLD && s != FS_WEIGHT_SUBPIXEL) && - (p->cache.style != FS_WEIGHT_BOOK && p->cache.style != FS_WEIGHT_DEMIBOLD && - p->cache.style != FS_WEIGHT_SUBPIXEL)) { - return (HCACHE) p; - } - } - } + if (strncmp(p->cache.df_name, df_name, LEN_UNIDEVFONT_NAME) == 0 && + p->cache.style == style && + p->cache.fontsize == size && + p->cache.rotation == rotation) { + return (HCACHE) p; } p = p->nextCache; } @@ -611,7 +603,7 @@ __mg_ttc_is_exist(char *family, char *charset, DWORD style, int size) #if 0 -static void +static void queue_traversal(LruQueueDummyHead *pQ) { MemBlk *ptr; @@ -619,12 +611,12 @@ queue_traversal(LruQueueDummyHead *pQ) ptr = pQ->lruNext; for (; ptr != pQ; ptr = ptr->lruNext) { DP(("MemBlk = %p, MemBlk->prev = %p, " - "MemBlk->next = %p, MemBlk->data : %d\n", + "MemBlk->next = %p, MemBlk->data : %d\n", ptr, ptr->lruPrev, ptr->lruNext, *(int *)(ptr->data))); - } + } } -static void +static void queue_traversal_reverse(LruQueueDummyHead *pQ) { MemBlk *ptr; @@ -632,9 +624,9 @@ queue_traversal_reverse(LruQueueDummyHead *pQ) ptr = pQ->lruPrev; for ( ; ptr != pQ; ptr = ptr->lruPrev) { DP(("MemBlk = %p, MemBlk->prev = %p, " - "MemBlk->next = %p, MemBlk->data : %d\n", + "MemBlk->next = %p, MemBlk->data : %d\n", ptr, ptr->lruPrev, ptr->lruNext, *(int *)(ptr->data))); - } + } } @@ -645,12 +637,12 @@ void __mg_ttc_dump_all(void) DP(("__mg_globalCache.maxCache = %d\n", __mg_globalCache.maxCache)); DP(("__mg_globalCache.cacheSize = %d\n", __mg_globalCache.cacheSize)); DP(("__mg_globalCache.nCache = %d\n", __mg_globalCache.nCache)); - - DP(("__mg_globalCache.queueDummyHead.prevCache = %p\n", + + DP(("__mg_globalCache.queueDummyHead.prevCache = %p\n", __mg_globalCache.queueDummyHead.prevCache)); DP(("__mg_globalCache.queueDummyHead.nextCache = %p\n", __mg_globalCache.queueDummyHead.nextCache)); -#endif +#endif pc = __mg_globalCache.queueDummyHead.nextCache; for ( ; pc != &__mg_globalCache.queueDummyHead; pc = pc->nextCache) { __mg_ttc_dump(&pc->cache); @@ -662,21 +654,21 @@ void __mg_ttc_dump(cache_t *cache) { int i, j, k; MemBlk *ptr; -#if 0 +#if 0 DP(("&cache = %p\n", cache)); - DP(("cache.family = %s\n", cache->family)); - DP(("cache.charset = %s\n", cache->charset)); + DP(("cache.df_name = %s\n", cache->df_name)); DP(("cache.style = %d\n", cache->style)); DP(("cache.fontsize = %d\n", cache->fontsize)); + DP(("cache.rotation = %d\n", cache->rotation)); DP(("cache.blkSize = %d\n", cache->blkSize)); DP(("cache.refers = %d\n", cache->refers)); DP(("cache.nBlk = %d\n", cache->nBlk)); DP(("cache.nDir = %d\n", cache->nDir)); - DP(("cache.memPool = %d, (HEX) = %p\n", + DP(("cache.memPool = %d, (HEX) = %p\n", cache->memPool, cache->memPool)); DP(("cache.lruQueueNodes=%p\n", cache->lruQueueNodes)); DP(("cache.hashDir = %p\n", cache->hashDir)); -#endif +#endif DP(("&cache.lruQueueDummyHead=%p\n", &cache->lruQueueDummyHead)); DP(("cache.lruQueueDummyHead.lruPrev=%p\n", @@ -686,48 +678,48 @@ void __mg_ttc_dump(cache_t *cache) //queue_traversal(&cache->lruQueueDummyHead); //DP(("----\n")); //queue_traversal_reverse(&cache->lruQueueDummyHead); -#if 0 +#if 0 for (i=0; inDir; i++) { MemBlk *p; printf("hash[%d]:", i); p = (cache->hashDir)[i].hashHead.hashNext; while(p != &(cache->hashDir[i].hashHead)) { - printf("-->%d(%d)", *(unsigned short *)(p->data), p->len); + printf("-->%d(%d)", *(UChar32 *)(p->data), p->len); p = p->hashNext; } printf("\n"); } #endif - //printf("LRU: "); - + //printf("LRU: "); + ptr = cache->lruQueueDummyHead.lruNext; for ( ; ptr != &cache->lruQueueDummyHead; ptr = ptr->lruNext) { - DP(("-->%p(len:%d, data:%d)", - ptr, ptr->len, *(unsigned short *)(ptr->data))); + DP(("-->%p(len:%d, data:%d)", + ptr, ptr->len, *(UCha32 *)(ptr->data))); } - //printf("\n"); + //printf("\n"); } -void +void __mg_ttc_dump_cacheinfo(TTFCACHEINFO *ca) { DP(("Dump TTFCACHEINFO %p...\n", ca)); DP(("cacheInfo->unicode = %d\n", ca->unicode)); DP(("cacheInfo->glyph_code = %d\n", ca->glyph_code)); - + DP(("cacheInfo->cur_xmin = %d, cacheInfo->cur_ymin = %d\n", ca->cur_xmin, ca->cur_ymin)); DP(("cacheInfo->width = %d, cacheInfo->height = %d\n", ca->width, ca->height)); DP(("cacheInfo->advance = %d\n", ca->advance)); DP(("cacheInfo->cur_bbox = %d, %d, %d, %d\n", - ca->bbox.xMin, ca->bbox.yMin, + ca->bbox.xMin, ca->bbox.yMin, ca->bbox.xMax, ca->bbox.yMax)); DP(("\n")); } -void +void __mg_ttc_dump_instance(TTFINSTANCEINFO *in) { DP(("Dump TTFINSTANCEINFO %p...\n", in)); @@ -740,9 +732,9 @@ __mg_ttc_dump_instance(TTFINSTANCEINFO *in) in->cur_width, in->cur_height)); DP(("Instance->advance = %d\n", in->cur_advance)); DP(("Instance->cur_bbox = %d, %d, %d, %d\n", - in->cur_bbox.xMin, in->cur_bbox.yMin, + in->cur_bbox.xMin, in->cur_bbox.yMin, in->cur_bbox.xMax, in->cur_bbox.yMax)); - + DP(("\n")); } diff --git a/src/font/freetype1.c b/src/font/freetype1.c index 04092eb9..7e3e1ae0 100644 --- a/src/font/freetype1.c +++ b/src/font/freetype1.c @@ -440,7 +440,7 @@ static int get_glyph_bbox (LOGFONT* logfont, DEVFONT* devfont, /* call this function to get the bitmap/pixmap of the char */ static const void* char_bitmap_pixmap (LOGFONT* logfont, DEVFONT* devfont, - const Glyph32 glyph_value, int* pitch, BOOL is_grey) + const Glyph32 glyph_value, SIZE* sz, int* pitch, BOOL is_grey) { TT_Raster_Map Raster; TT_Error error; @@ -538,17 +538,17 @@ char_bitmap_pixmap (LOGFONT* logfont, DEVFONT* devfont, } static const void* get_glyph_monobitmap (LOGFONT* logfont, DEVFONT* devfont, - const Glyph32 glyph_value, int* pitch, unsigned short* scale) + const Glyph32 glyph_value, SIZE* sz, int* pitch, unsigned short* scale) { if (scale) *scale = 1; - return char_bitmap_pixmap (logfont, devfont, glyph_value, pitch, FALSE); + return char_bitmap_pixmap (logfont, devfont, glyph_value, sz, pitch, FALSE); } static const void* get_glyph_greybitmap (LOGFONT* logfont, DEVFONT* devfont, - const Glyph32 glyph_value, int* pitch, unsigned short* scale) + const Glyph32 glyph_value, SIZE* sz, int* pitch, unsigned short* scale) { if (scale) *scale = 1; - return char_bitmap_pixmap (logfont, devfont, glyph_value, pitch, TRUE); + return char_bitmap_pixmap (logfont, devfont, glyph_value, sz, pitch, TRUE); } /* call this function after getting the bitmap/pixmap of the char diff --git a/src/font/freetype2.c b/src/font/freetype2.c index 2bad2a5b..daa03dd3 100644 --- a/src/font/freetype2.c +++ b/src/font/freetype2.c @@ -1,39 +1,39 @@ /* - * This file is part of MiniGUI, a mature cross-platform windowing + * This file is part of MiniGUI, a mature cross-platform windowing * and Graphics User Interface (GUI) support system for embedded systems * and smart IoT devices. - * + * * Copyright (C) 2002~2018, Beijing FMSoft Technologies Co., Ltd. * Copyright (C) 1998~2002, WEI Yongming - * + * * This program 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, either version 3 of the License, or * (at your option) any later version. - * + * * This program 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 . - * + * * Or, - * + * * As this program is a library, any link to this program must follow * GNU General Public License version 3 (GPLv3). If you cannot accept * GPLv3, you need to be licensed from FMSoft. - * + * * If you have got a commercial license of this program, please use it * under the terms and conditions of the commercial license. - * + * * For more information about the commercial license, please refer to * . */ /* ** freetype2.c: TrueType font support based on FreeType 2. -** +** ** Create date: 2002/01/18 */ @@ -56,7 +56,7 @@ #include "freetype2.h" #define IS_SUBPIXEL(logfont) \ - (((logfont)->style & FS_WEIGHT_MASK) == FS_WEIGHT_SUBPIXEL) + (((logfont)->style & FS_WEIGHT_MASK) == FS_WEIGHT_SUBPIXEL) #ifdef TTF_DBG static int bbox_nohit = 0; @@ -156,14 +156,14 @@ static void free_raster_bitmap_buffer (void) /*************** TrueType on FreeType font operations ************************/ #ifdef DEBUG_GLYPH_DATA -static void +static void print_bitmap(char* bits, int width, int height, int pitch) { int y = 0; int x = 0; char* p_line_head; char* p_cur_char; - + for (y = 0, p_line_head = bits; y < height; y++) { for (x = 0; x < width; x++) @@ -175,12 +175,12 @@ print_bitmap(char* bits, int width, int height, int pitch) printf(". "); } printf("\n"); - + p_line_head += pitch; } } -static void +static void print_bitmap_grey (void* buffer, int width, int rows, int pitch) { int i; @@ -208,28 +208,28 @@ static DWORD get_glyph_type (LOGFONT* logfont, DEVFONT* devfont) return DEVFONTGLYPHTYPE_MONOBMP; } -static int +static int get_ave_width (LOGFONT* logfont, DEVFONT* devfont) { FTINSTANCEINFO* ft_inst_info = FT_INST_INFO_P (devfont); return ft_inst_info->ave_width; } -static int +static int get_max_width (LOGFONT* logfont, DEVFONT* devfont) { FTINSTANCEINFO* ft_inst_info = FT_INST_INFO_P (devfont); return ft_inst_info->max_width; } -static int +static int get_font_height (LOGFONT* logfont, DEVFONT* devfont) { FTINSTANCEINFO* ft_inst_info = FT_INST_INFO_P (devfont); return ft_inst_info->height; } -static int +static int get_font_size (LOGFONT* logfont, DEVFONT* devfont, int expect) { unsigned short scale = 1; @@ -237,22 +237,22 @@ get_font_size (LOGFONT* logfont, DEVFONT* devfont, int expect) return expect; } -static int +static int get_font_ascent (LOGFONT* logfont, DEVFONT* devfont) { FTINSTANCEINFO* ft_inst_info = FT_INST_INFO_P (devfont); return ft_inst_info->ascent; } -static int +static int get_font_descent (LOGFONT* logfont, DEVFONT* devfont) { FTINSTANCEINFO* ft_inst_info = FT_INST_INFO_P (devfont); return ft_inst_info->descent; } -static int -load_or_search_glyph (FTINSTANCEINFO* ft_inst_info, FT_Face* face, +static int +load_or_search_glyph (FTINSTANCEINFO* ft_inst_info, FT_Face* face, FT_ULong uni_char, int glyph_type) { #ifndef _MGFONT_TTF_CACHE @@ -270,7 +270,6 @@ load_or_search_glyph (FTINSTANCEINFO* ft_inst_info, FT_Face* face, ft_load_flags |= FT_LOAD_TARGET_NORMAL | FT_LOAD_FORCE_AUTOHINT; } - FT_Activate_Size (ft_inst_info->size); *face = ft_face_info->face; @@ -323,12 +322,12 @@ load_or_search_glyph (FTINSTANCEINFO* ft_inst_info, FT_Face* face, /* call this function before getting the bitmap/pixmap of the char * to get the bbox of the char */ -static int -get_glyph_bbox (LOGFONT* logfont, DEVFONT* devfont, - const Glyph32 glyph_value, +static int +get_glyph_bbox (LOGFONT* logfont, DEVFONT* devfont, + const Glyph32 glyph_value, int* px, int* py, int* pwidth, int* pheight) { - + FT_BBox bbox; FT_Face face; FT_UInt uni_char; @@ -344,7 +343,7 @@ get_glyph_bbox (LOGFONT* logfont, DEVFONT* devfont, /* Search cache by unicode !*/ #ifdef _MGFONT_TTF_CACHE - if (ft_inst_info->cache && (ft_inst_info->rotation == 0)) { + if (ft_inst_info->cache) { TTFCACHEINFO *cache_info; int datasize; cache_info = __mg_ttc_search(ft_inst_info->cache, @@ -357,7 +356,7 @@ get_glyph_bbox (LOGFONT* logfont, DEVFONT* devfont, if (pwidth) *pwidth = cache_info->bbox.xMax - cache_info->bbox.xMin; if (pheight) *pheight = cache_info->bbox.yMax - cache_info->bbox.yMin; - if (px) *px += cache_info->bbox.xMin; + if (px) *px += cache_info->bbox.xMin; if (py) *py -= cache_info->bbox.yMax; if (px) @@ -368,9 +367,9 @@ get_glyph_bbox (LOGFONT* logfont, DEVFONT* devfont, DP(("\nBBOX Non - Hit! %d, %d\n", bbox_nohit++, uni_char)); } -#endif +#endif - if (load_or_search_glyph (ft_inst_info, &face, uni_char, + if (load_or_search_glyph (ft_inst_info, &face, uni_char, get_glyph_type(logfont, devfont))) { _MG_PRINTF ("FONT>FT2: load_or_search_glyph error in freetype2\n"); return 0; @@ -379,7 +378,7 @@ get_glyph_bbox (LOGFONT* logfont, DEVFONT* devfont, if (ft_inst_info->use_kerning) { /* get kerning. */ if (ft_inst_info->prev_index && ft_inst_info->cur_index) { - int error = FT_Get_Kerning (face, + int error = FT_Get_Kerning (face, ft_inst_info->prev_index, ft_inst_info->cur_index, FT_KERNING_DEFAULT, &(ft_inst_info->delta)); @@ -405,7 +404,7 @@ get_glyph_bbox (LOGFONT* logfont, DEVFONT* devfont, /* We just save the BBOX :). */ memcpy (&ft_inst_info->bbox, &bbox, sizeof(FT_BBox)); - memcpy (&ft_inst_info->advance, &ft_inst_info->glyph->advance, + memcpy (&ft_inst_info->advance, &ft_inst_info->glyph->advance, sizeof(FT_Vector)); FT_Done_Glyph (ft_inst_info->glyph); @@ -415,7 +414,7 @@ get_glyph_bbox (LOGFONT* logfont, DEVFONT* devfont, } #ifdef _MGFONT_TTF_CACHE - if (ft_inst_info->cache && (ft_inst_info->rotation == 0)) { + if (ft_inst_info->cache) { TTFCACHEINFO * pcache; TTFCACHEINFO cache_info = {0}; int datasize; @@ -432,12 +431,14 @@ get_glyph_bbox (LOGFONT* logfont, DEVFONT* devfont, cache_info.delta = ft_inst_info->delta; cache_info.bitmap = NULL; cache_info.pitch = 0; + cache_info.width = 0; + cache_info.height = 0; cache_info.flag = FALSE; - DP(("Should Write %d to cache length = %d, bitmap size = %d, cache = %p\n", - cache_info.unicode, sizeof(TTFCACHEINFO) + size, size, + DP(("Should Write %d to cache length = %d, bitmap size = %d, cache = %p\n", + cache_info.unicode, sizeof(TTFCACHEINFO) + size, size, ft_inst_info->cache)); - __mg_ttc_write(ft_inst_info->cache, + __mg_ttc_write(ft_inst_info->cache, &cache_info, sizeof(TTFCACHEINFO) + size); } } @@ -445,7 +446,7 @@ get_glyph_bbox (LOGFONT* logfont, DEVFONT* devfont, if (pwidth) *pwidth = bbox.xMax - bbox.xMin; if (pheight) *pheight = bbox.yMax - bbox.yMin; - if (px) *px += bbox.xMin; + if (px) *px += bbox.xMin; if (py) *py -= bbox.yMax; return (int)(bbox.xMax - bbox.xMin); @@ -453,7 +454,7 @@ get_glyph_bbox (LOGFONT* logfont, DEVFONT* devfont, #if 0 // VincentWei: bad implementation /* press double-byte align to byte align.*/ -static void +static void press_bitmap (void* buffer, int width, int rows, int pitch) { unsigned char* src_pos; @@ -475,10 +476,10 @@ press_bitmap (void* buffer, int width, int rows, int pitch) } #endif -/* call this function to get the bitmap/pixmap of the char */ -static const void* -char_bitmap_pixmap (LOGFONT* logfont, DEVFONT* devfont, - const Glyph32 glyph_value, int* pitch, BOOL is_grey) +/* call this function to get the bitmap/pixmap of the char */ +static const void* +char_bitmap_pixmap (LOGFONT* logfont, DEVFONT* devfont, + const Glyph32 glyph_value, SIZE* sz, int* pitch, BOOL is_grey) { FT_BitmapGlyph glyph_bitmap; FT_Bitmap* source; @@ -490,32 +491,38 @@ char_bitmap_pixmap (LOGFONT* logfont, DEVFONT* devfont, /*because: lock in draw_one_glyph*/ if (IS_SUBPIXEL(logfont)) FT_Library_SetLcdFilter(ft_library, ft_inst_info->ft_lcdfilter); - + if(devfont->charset_ops->conv_to_uc32) uni_char = (*devfont->charset_ops->conv_to_uc32) (glyph_value); else uni_char = glyph_value; #ifdef _MGFONT_TTF_CACHE - if (ft_inst_info->cache && (ft_inst_info->rotation == 0)) { + if (ft_inst_info->cache) { TTFCACHEINFO *cacheinfo; int datasize; - + cacheinfo = __mg_ttc_search(ft_inst_info->cache, uni_char, &datasize); - + if (cacheinfo != NULL && cacheinfo->flag == TRUE) { DP(("Bitmap Hit!! %d\n", bitmap_hit++)); + if (pitch) *pitch = cacheinfo->pitch; + if (sz) { + sz->cx = cacheinfo->width; + sz->cy = cacheinfo->height; + } + return cacheinfo->bitmap; } DP(("Bitmap Non hit %d, %d\n", bitmap_nohit++, uni_char)); } -#endif - - if (load_or_search_glyph (ft_inst_info, &face, uni_char, +#endif + + if (load_or_search_glyph (ft_inst_info, &face, uni_char, get_glyph_type(logfont, devfont))) { _MG_PRINTF ("FONT>FT2: load_or_search_glyph failed in freetype2\n"); return NULL; @@ -525,14 +532,14 @@ char_bitmap_pixmap (LOGFONT* logfont, DEVFONT* devfont, if (ft_inst_info->glyph->format != ft_glyph_format_bitmap) { if (ft_inst_info->ft_lcdfilter != FT_LCD_FILTER_NONE && IS_SUBPIXEL(logfont) && is_grey) { - if (FT_Glyph_To_Bitmap (&(ft_inst_info->glyph), + if (FT_Glyph_To_Bitmap (&(ft_inst_info->glyph), FT_RENDER_MODE_LCD, NULL, 1)) { _MG_PRINTF ("FONT>FT2: FT_Glyph_To_Bitmap failed\n"); return NULL; } } else { - if (FT_Glyph_To_Bitmap (&(ft_inst_info->glyph), + if (FT_Glyph_To_Bitmap (&(ft_inst_info->glyph), is_grey? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO, NULL, 1)) { _MG_PRINTF ("FONT>FT2: FT_Glyph_To_Bitmap failed\n"); @@ -540,29 +547,19 @@ char_bitmap_pixmap (LOGFONT* logfont, DEVFONT* devfont, } } } - + /* access bitmap content by typecasting */ glyph_bitmap = (FT_BitmapGlyph) ft_inst_info->glyph; source = &glyph_bitmap->bitmap; - + if (pitch) *pitch = source->pitch; -#if 0 // VincentWei: bad implementation - if (!is_grey) { - press_bitmap(source->buffer, - source->width, source->rows, source->pitch); - *pitch = (source->width + 7) >> 3; - } -#else - *pitch = source->pitch; -#endif - #ifdef _MGFONT_TTF_CACHE - if (ft_inst_info->cache && (ft_inst_info->rotation == 0)) { + if (ft_inst_info->cache) { TTFCACHEINFO * pcache; int datasize; - int size = source->rows * (*pitch); + int size = source->rows * source->pitch; pcache = __mg_ttc_search(ft_inst_info->cache, uni_char, &datasize); @@ -575,22 +572,30 @@ char_bitmap_pixmap (LOGFONT* logfont, DEVFONT* devfont, cache_info.advance = ft_inst_info->advance; cache_info.delta = ft_inst_info->delta; cache_info.bitmap = source->buffer; - cache_info.pitch = *pitch; + cache_info.pitch = source->pitch; + cache_info.width = source->width; + cache_info.height = source->rows; cache_info.flag = TRUE; - DP(("Should Write %d to cache length = %d, bitmap size = %d, cache = %p\n", - cache_info.unicode, sizeof(TTFCACHEINFO) + size, size, + DP(("Should Write %d to cache length = %d, bitmap size = %d, cache = %p\n", + cache_info.unicode, sizeof(TTFCACHEINFO) + size, size, ft_inst_info->cache)); - __mg_ttc_write(ft_inst_info->cache, + __mg_ttc_write(ft_inst_info->cache, &cache_info, sizeof(TTFCACHEINFO) + size); - } else { if (pcache->flag == FALSE) { - pcache->pitch = *pitch; + pcache->pitch = source->pitch; + pcache->width = source->width; + pcache->height = source->rows; memcpy(pcache->bitmap, source->buffer, size); pcache->flag = TRUE; } + + if (sz) { + sz->cx = pcache->width; + sz->cy = pcache->height; + } FT_Done_Glyph (ft_inst_info->glyph); return pcache->bitmap; } @@ -599,30 +604,34 @@ char_bitmap_pixmap (LOGFONT* logfont, DEVFONT* devfont, buffer = get_raster_bitmap_buffer (source->rows * source->pitch); memcpy(buffer, source->buffer, source->rows * source->pitch); + if (sz) { + sz->cx = source->width; + sz->cy = source->rows; + } FT_Done_Glyph (ft_inst_info->glyph); - + return buffer; } -static const void* +static const void* get_glyph_monobitmap (LOGFONT* logfont, DEVFONT* devfont, - const Glyph32 glyph_value, int* pitch, unsigned short* scale) + const Glyph32 glyph_value, SIZE* sz, int* pitch, unsigned short* scale) { if (scale) *scale = 1; - return char_bitmap_pixmap (logfont, devfont, glyph_value, pitch, FALSE); + return char_bitmap_pixmap (logfont, devfont, glyph_value, sz, pitch, FALSE); } -static const void* -get_glyph_greybitmap (LOGFONT* logfont, DEVFONT* devfont, - const Glyph32 glyph_value, int* pitch, +static const void* +get_glyph_greybitmap (LOGFONT* logfont, DEVFONT* devfont, + const Glyph32 glyph_value, SIZE* sz, int* pitch, unsigned short* scale) { if (scale) *scale = 1; - return char_bitmap_pixmap (logfont, devfont, glyph_value, pitch, TRUE); + return char_bitmap_pixmap (logfont, devfont, glyph_value, sz, pitch, TRUE); } /* call this function before output a string */ -static void +static void start_str_output (LOGFONT* logfont, DEVFONT* devfont) { FTINSTANCEINFO* ft_inst_info = FT_INST_INFO_P (devfont); @@ -638,14 +647,14 @@ start_str_output (LOGFONT* logfont, DEVFONT* devfont) /* call this function after getting the bitmap/pixmap of the char * to get the advance of the char */ static int -get_glyph_advance (LOGFONT* logfont, DEVFONT* devfont, +get_glyph_advance (LOGFONT* logfont, DEVFONT* devfont, const Glyph32 glyph_value, int* px, int* py) { FT_Fixed advance; FTINSTANCEINFO* ft_inst_info = FT_INST_INFO_P (devfont); - if (ft_inst_info->use_kerning + if (ft_inst_info->use_kerning && ft_inst_info->prev_index && ft_inst_info->cur_index) { if (ft_inst_info->is_index_old) { if (px) @@ -665,13 +674,13 @@ get_glyph_advance (LOGFONT* logfont, DEVFONT* devfont, } #ifdef _MGFONT_TTF_CACHE -static int make_hash_key(unsigned short data) +static int make_hash_key(UChar32 data) { return ((int)data % 37); } #endif -static DEVFONT* +static DEVFONT* new_instance (LOGFONT* logfont, DEVFONT* devfont, BOOL need_sbc_font) { float angle; @@ -737,7 +746,7 @@ new_instance (LOGFONT* logfont, DEVFONT* devfont, BOOL need_sbc_font) if (FT_Set_Pixel_Sizes (face, logfont->size, 0)) goto out_size; - + ft_inst_info->rotation = logfont->rotation; /* in tenthdegrees */ angle = ft_inst_info->rotation * M_PI / 1800; @@ -753,10 +762,10 @@ new_instance (LOGFONT* logfont, DEVFONT* devfont, BOOL need_sbc_font) ft_inst_info->matrix.xx = ft_inst_info->matrix.yy; ft_inst_info->matrix.xy = -ft_inst_info->matrix.yx; } - + ft_inst_info->use_kerning = 0; - ft_inst_info->use_kerning = FT_HAS_KERNING(face); - + ft_inst_info->use_kerning = FT_HAS_KERNING(face); + ft_inst_info->max_width = size->metrics.x_ppem; ft_inst_info->ave_width = ft_inst_info->max_width; @@ -771,55 +780,54 @@ new_instance (LOGFONT* logfont, DEVFONT* devfont, BOOL need_sbc_font) ft_inst_info->image_type.height = logfont->size; ft_inst_info->image_type.face_id = (FTC_FaceID)ft_inst_info->ft_face_info; - /* houhh 20110304, AUTOHINT will be get more clear + /* houhh 20110304, AUTOHINT will be get more clear * and thin glyph. */ - ft_inst_info->image_type.flags = - FT_LOAD_DEFAULT | FT_LOAD_NO_BITMAP | + ft_inst_info->image_type.flags = + FT_LOAD_DEFAULT | FT_LOAD_NO_BITMAP | FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH | FT_LOAD_TARGET_NORMAL |FT_LOAD_FORCE_AUTOHINT; //FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH | FT_LOAD_TARGET_NORMAL; /* if unmask non-cache and no rotation */ - if (!(logfont->style & FS_OTHER_TTFNOCACHE) && - (ft_inst_info->rotation == 0)) { - - HCACHE hCache = __mg_ttc_is_exist(logfont->family, logfont->charset, - logfont->style, logfont->size); + if (!(logfont->style & FS_OTHER_TTFNOCACHE)) { + + HCACHE hCache = __mg_ttc_is_exist(logfont->family, + logfont->style, logfont->size, logfont->rotation); DP(("__mg_ttc_is_exist() return %p\n", hCache)); /* No this style's cache */ if (hCache == 0) { int pitch = 0, nblk, col, blksize, rows = ft_inst_info->height; - - if (((logfont->style & 0x0000000F) == FS_WEIGHT_BOOK) + + if (((logfont->style & 0x0000000F) == FS_WEIGHT_BOOK) || ((logfont->style & 0x0000000F) == FS_WEIGHT_DEMIBOLD) || ((logfont->style & 0x0000000FF) == FS_WEIGHT_SUBPIXEL)) { pitch = 1; } - + if (!pitch) { col = (ft_inst_info->max_width + 7) >> 3; } else { col = (ft_inst_info->max_width + 3) & -4; } - + blksize = col * rows; if ((logfont->style & 0x0000000FF) == FS_WEIGHT_SUBPIXEL) blksize *= 3; blksize += sizeof(TTFCACHEINFO); - - DP(("BITMAP Space = %d, Whole Space = %d\n", + + DP(("BITMAP Space = %d, Whole Space = %d\n", blksize - sizeof(TTFCACHEINFO), blksize)); - + blksize = (blksize + 3) & -4; nblk = ( _MGTTF_CACHE_SIZE * 1024 )/ blksize; DP(("[Before New a Cache], col = %d, row = %d, blksize = %d, " - "blksize(bitmap) = %d, nblk = %d\n", + "blksize(bitmap) = %d, nblk = %d\n", rows, col, blksize, blksize-sizeof(TTFCACHEINFO), nblk)); - - ft_inst_info->cache = __mg_ttc_create(logfont->family, logfont->charset, - logfont->style, logfont->size, nblk , blksize , - _TTF_HASH_NDIR, make_hash_key); + + ft_inst_info->cache = __mg_ttc_create(devfont->name, + logfont->style, logfont->size, logfont->rotation, + nblk , blksize , _TTF_HASH_NDIR, make_hash_key); DP(("__mg_ttc_create() return %p\n", ft_inst_info->cache)); } else { ft_inst_info->cache = hCache; @@ -847,12 +855,13 @@ out_size: FT_Done_Size (size); out: - free (ft_inst_info); - free (new_devfont); + if (ft_data) free (ft_data); + if (ft_inst_info) free (ft_inst_info); + if (new_devfont) free (new_devfont); return NULL; } -static void +static void delete_instance (DEVFONT* devfont) { FTINSTANCEINFO* ft_inst_info = FT_INST_INFO_P (devfont); @@ -861,7 +870,7 @@ delete_instance (DEVFONT* devfont) if (ft_inst_info->cache) { __mg_ttc_release(ft_inst_info->cache); } -#endif +#endif free (ft_inst_info); free (devfont->data); @@ -873,12 +882,12 @@ static BOOL is_glyph_existed (LOGFONT* logfont, DEVFONT* devfont, Glyph32 glyph_ FT_Face face; FT_UInt uni_char; FTINSTANCEINFO* ft_inst_info = FT_INST_INFO_P (devfont); - + if(devfont->charset_ops->conv_to_uc32) uni_char = (*devfont->charset_ops->conv_to_uc32) (glyph_value); else uni_char = glyph_value; - + #ifndef _MGFONT_TTF_CACHE face = ft_inst_info->ft_face_info->face; if(0 == FT_Get_Char_Index (face, uni_char)) @@ -916,10 +925,16 @@ static void* load_font_data (const char* font_name, const char *file_name) FTFACEINFO* ft_face_info = (FTFACEINFO*) calloc (1, sizeof(FTFACEINFO)); FT2_DATA* ft_data = (FT2_DATA*) calloc(1, sizeof(FTFACEINFO)); -#ifdef _MGFONT_TTF_CACHE - strcpy (ft_face_info->filepathname, file_name); - ft_face_info->face_index = 0; + if (ft_face_info == NULL || ft_data == NULL) { + goto error; + } +#ifdef _MGFONT_TTF_CACHE + ft_face_info->filepathname = strdup(file_name); + if (ft_face_info->filepathname == NULL) + goto error; + + ft_face_info->face_index = 0; error = FT_New_Face (ft_library, file_name, ft_face_info->face_index, &face); #else error = FT_New_Face (ft_library, file_name, 0, &ft_face_info->face); @@ -942,7 +957,7 @@ static void* load_font_data (const char* font_name, const char *file_name) for (i = 0; i < face->num_charmaps; i++) { charmap = face->charmaps [i]; - if (((charmap->platform_id == TT_PLATFORM_MICROSOFT) + if (((charmap->platform_id == TT_PLATFORM_MICROSOFT) && (charmap->encoding_id == TT_MS_ID_UNICODE_CS)) || ((charmap->platform_id == TT_PLATFORM_APPLE_UNICODE) && (charmap->encoding_id == TT_APPLE_ID_DEFAULT))) { @@ -969,15 +984,24 @@ static void* load_font_data (const char* font_name, const char *file_name) return ft_data; error: - free (ft_data); - free (ft_face_info); + if (ft_data) + free (ft_data); + + if (ft_face_info) { + if (ft_face_info->filepathname) + free(ft_face_info->filepathname); + free(ft_face_info); + } + return NULL; } static void unload_font_data (void* data) { FT2_DATA* ft_data = (FT2_DATA*)data; -#ifndef _MGFONT_TTF_CACHE +#ifdef _MGFONT_TTF_CACHE + free(ft_data->ft_face_info->filepathname); +#else FT_Done_Face ((ft_data->ft_face_info)->face); #endif free (ft_data->ft_face_info); @@ -985,7 +1009,7 @@ static void unload_font_data (void* data) free (ft_data); } -static void +static void ShowErr (const char* message , int error) { _MG_PRINTF ("FONT>FT2: %s\n error = 0x%04x\n", message, error ); @@ -1048,7 +1072,7 @@ BOOL font_InitFreetypeLibrary (void) return TRUE; error_ftc_manager: - FTC_Manager_Done (ft_cache_manager); + FTC_Manager_Done (ft_cache_manager); #endif return TRUE; @@ -1078,29 +1102,29 @@ void font_TermFreetypeLibrary (void) FONTOPS __mg_ttf_ops = { get_glyph_type, get_ave_width, - get_max_width, + get_max_width, get_font_height, - get_font_size, + get_font_size, get_font_ascent, get_font_descent, is_glyph_existed, get_glyph_advance, - get_glyph_bbox, + get_glyph_bbox, - get_glyph_monobitmap, - get_glyph_greybitmap, + get_glyph_monobitmap, + get_glyph_greybitmap, NULL, start_str_output, - new_instance, + new_instance, delete_instance, is_rotatable, load_font_data, unload_font_data }; -BOOL +BOOL ft2SetLcdFilter (LOGFONT* logfont, mg_FT_LcdFilter filter) { BOOL rv = FALSE; @@ -1108,7 +1132,7 @@ ft2SetLcdFilter (LOGFONT* logfont, mg_FT_LcdFilter filter) if (IS_SUBPIXEL(logfont)) { if (filter >= MG_SMOOTH_MAX) - filter = MG_SMOOTH_DEFAULT; + filter = MG_SMOOTH_DEFAULT; devfont = logfont->sbc_devfont; if (devfont && devfont->font_ops == &__mg_ttf_ops) { FTINSTANCEINFO* ft_inst_info = FT_INST_INFO_P (devfont); @@ -1132,14 +1156,14 @@ ft2SetLcdFilter (LOGFONT* logfont, mg_FT_LcdFilter filter) return rv; } -int +int ft2GetLcdFilter (DEVFONT* devfont) { FTINSTANCEINFO* ft_inst_info = FT_INST_INFO_P (devfont); return ft_inst_info->ft_lcdfilter; } -int +int ft2IsFreeTypeDevfont (DEVFONT* devfont) { if (devfont && devfont->font_ops == &__mg_ttf_ops) diff --git a/src/font/freetype2.h b/src/font/freetype2.h index 87839fcd..19c9fcd5 100644 --- a/src/font/freetype2.h +++ b/src/font/freetype2.h @@ -63,13 +63,12 @@ extern "C" { #ifdef _MGFONT_TTF_CACHE typedef unsigned long HCACHE; -typedef int (* MakeHashKeyFunc)(unsigned short unicode); +typedef int (* MakeHashKeyFunc)(UChar32 unicode); #endif typedef struct tagFTFACEINFO { #ifdef _MGFONT_TTF_CACHE - /*should be MAX_PATH*/ - char filepathname[256]; + char* filepathname; int face_index; int cmap_index; #else @@ -114,26 +113,28 @@ typedef struct tagFTINSTANCEINFO { #define _TTF_HASH_NDIR 37 typedef struct tagTTFCACHEINFO { - unsigned short unicode; - short glyph_code; + UChar32 unicode; + FT_UInt glyph_code; FT_Vector advance; FT_BBox bbox; FT_Vector delta; int flag; int pitch; + int width; + int height; void *bitmap; } TTFCACHEINFO, *PTTFCACHEINFO; -extern HCACHE __mg_ttc_create(char *family, char *charset, DWORD style, int size, - int nblk, int blksize, int ndir, MakeHashKeyFunc makeHashKey); +extern HCACHE __mg_ttc_create(const char *df_name, + int style, int size, int rotation, + int nblk, int blksize, int ndir, MakeHashKeyFunc makeHashKey); +extern HCACHE __mg_ttc_is_exist(const char *df_name, + int style, int size, int rotation); extern int __mg_ttc_write(HCACHE hCache, TTFCACHEINFO *data, int size); extern void __mg_ttc_release(HCACHE hCache); extern int __mg_ttc_sys_init(int maxCache, int cacheSize); extern void __mg_ttc_sys_deinit(void); -extern TTFCACHEINFO *__mg_ttc_search(HCACHE hCache, - unsigned short unicode, int *size); -extern HCACHE __mg_ttc_is_exist(char *family, char *charset, - DWORD style, int size); +extern TTFCACHEINFO *__mg_ttc_search(HCACHE hCache, UChar32 unicode, int *size); extern void __mg_ttc_refer(HCACHE hCache); #endif diff --git a/src/font/qpf.c b/src/font/qpf.c index 4a8be7a8..7da0c09d 100644 --- a/src/font/qpf.c +++ b/src/font/qpf.c @@ -329,7 +329,7 @@ static int get_font_descent (LOGFONT* logfont, DEVFONT* devfont) } static const void* get_glyph_monobitmap (LOGFONT* logfont, DEVFONT* devfont, - const Glyph32 glyph_value, int* pitch, unsigned short* scale) + const Glyph32 glyph_value, SIZE* sz, int* pitch, unsigned short* scale) { unsigned int uc16; QPF_GLYPH* glyph; @@ -345,7 +345,7 @@ static const void* get_glyph_monobitmap (LOGFONT* logfont, DEVFONT* devfont, if (uc16 < 0x80 && logfont->sbc_devfont != devfont) { /* ASCII */ unsigned char ascii_ch = uc16; return logfont->sbc_devfont->font_ops->get_glyph_monobitmap (logfont, - logfont->sbc_devfont, ascii_ch, pitch, scale); + logfont->sbc_devfont, ascii_ch, sz, pitch, scale); } else glyph = &def_glyph; @@ -365,7 +365,7 @@ static const void* get_glyph_monobitmap (LOGFONT* logfont, DEVFONT* devfont, } static const void* get_glyph_greybitmap (LOGFONT* logfont, DEVFONT* devfont, - Glyph32 glyph_value, int* pitch, unsigned short* scale) + Glyph32 glyph_value, SIZE* sz, int* pitch, unsigned short* scale) { unsigned int uc16; QPF_GLYPH* glyph; diff --git a/src/font/rawbitmap.c b/src/font/rawbitmap.c index 3dc2cc11..1394df0a 100644 --- a/src/font/rawbitmap.c +++ b/src/font/rawbitmap.c @@ -208,7 +208,7 @@ static int get_font_descent (LOGFONT* logfont, DEVFONT* devfont) } static const void* get_glyph_monobitmap (LOGFONT* logfont, DEVFONT* devfont, - const Glyph32 glyph_value, int* pitch, unsigned short* scale) + const Glyph32 glyph_value, SIZE* sz, int* pitch, unsigned short* scale) { int bitmap_size; Glyph32 glyph_tmp = glyph_value; diff --git a/src/font/upf.c b/src/font/upf.c index cdb68ae4..9ab83409 100644 --- a/src/font/upf.c +++ b/src/font/upf.c @@ -279,7 +279,7 @@ print_bitmap(char* bits, int width, int height, int pitch) #endif static const void* get_glyph_monobitmap (LOGFONT* logfont, DEVFONT* devfont, - const Glyph32 glyph_value, int* pitch, unsigned short* scale) + const Glyph32 glyph_value, SIZE* sz, int* pitch, unsigned short* scale) { unsigned int uc16; UPFGLYPH* glyph; @@ -300,7 +300,7 @@ static const void* get_glyph_monobitmap (LOGFONT* logfont, DEVFONT* devfont, if (uc16 < 0x80 && logfont->sbc_devfont != devfont) { /* ASCII */ unsigned char ascii_ch = uc16; return logfont->sbc_devfont->font_ops->get_glyph_monobitmap (logfont, - logfont->sbc_devfont, ascii_ch, pitch, scale); + logfont->sbc_devfont, ascii_ch, sz, pitch, scale); } else glyph = &def_glyph; @@ -326,7 +326,7 @@ static const void* get_glyph_monobitmap (LOGFONT* logfont, DEVFONT* devfont, } static const void* get_glyph_greybitmap (LOGFONT* logfont, DEVFONT* devfont, - Glyph32 glyph_value, int* pitch, unsigned short* scale) + Glyph32 glyph_value, SIZE* sz, int* pitch, unsigned short* scale) { unsigned int uc16; UPFGLYPH* glyph; diff --git a/src/font/varbitmap.c b/src/font/varbitmap.c index a17216a5..b2440e11 100644 --- a/src/font/varbitmap.c +++ b/src/font/varbitmap.c @@ -111,6 +111,9 @@ static int get_ch_width (LOGFONT* logfont, DEVFONT* devfont, if (vbf_info->bits_offset == NULL) return vbf_info->max_width * scale; + if (glyph_value < vbf_info->first_glyph || glyph_value > vbf_info->last_glyph) + glyph_value = vbf_info->def_glyph; + return vbf_info->advance_x [glyph_value - vbf_info->first_glyph] * scale; } @@ -234,7 +237,7 @@ static int get_glyph_advance (LOGFONT* logfont, DEVFONT* devfont, } static const void* get_glyph_monobitmap (LOGFONT* logfont, DEVFONT* devfont, - const Glyph32 glyph_value, int* pitch, unsigned short* scale) + const Glyph32 glyph_value, SIZE* sz, int* pitch, unsigned short* scale) { int offset; Glyph32 eff_value = glyph_value; diff --git a/src/include/devfont.h b/src/include/devfont.h index 74cbb8a7..44cd8ba8 100644 --- a/src/include/devfont.h +++ b/src/include/devfont.h @@ -225,11 +225,11 @@ struct _FONTOPS /** The method to get mono-bitmap function. */ const void* (*get_glyph_monobitmap) (LOGFONT* logfont, DEVFONT* devfont, - const Glyph32 glyph_value, int* pitch, unsigned short* scale); + const Glyph32 glyph_value, SIZE* sz, int* pitch, unsigned short* scale); /** The method to get grey bitmap, pitch and scale function */ const void* (*get_glyph_greybitmap) (LOGFONT* logfont, DEVFONT* devfont, - const Glyph32 galph_value, int* pitch, unsigned short* scale); + const Glyph32 galph_value, SIZE* sz, int* pitch, unsigned short* scale); /** The method to get the pre-rendered bitmap of one glyph. */ int (*get_glyph_prbitmap) (LOGFONT* logfont, DEVFONT* devfont, diff --git a/src/newgdi/glyph.c b/src/newgdi/glyph.c index 382ecc12..36009f6f 100644 --- a/src/newgdi/glyph.c +++ b/src/newgdi/glyph.c @@ -203,6 +203,7 @@ int GUIAPI GetGlyphInfo (LOGFONT* logfont, Glyph32 glyph_value, { int advance = 0; int pitch = 0; + SIZE sz; /* get the relative device font*/ DEVFONT* devfont = SELECT_DEVFONT(logfont, glyph_value); @@ -240,6 +241,9 @@ int GUIAPI GetGlyphInfo (LOGFONT* logfont, Glyph32 glyph_value, glyph_info->advance_x++; } + sz.cx = glyph_info->bbox_w; + sz.cy = glyph_info->bbox_h; + /*get height and descent of devfont*/ if (glyph_info->mask & GLYPH_INFO_METRICS) { @@ -256,7 +260,9 @@ int GUIAPI GetGlyphInfo (LOGFONT* logfont, Glyph32 glyph_value, switch (glyph_info->bmp_type) { case GLYPHBMP_TYPE_MONO: glyph_info->bits = devfont->font_ops->get_glyph_monobitmap ( - logfont, devfont, glyph_value, &pitch, NULL); + logfont, devfont, glyph_value, &sz, &pitch, NULL); + glyph_info->bbox_w = sz.cx; + glyph_info->bbox_h = sz.cy; glyph_info->bmp_pitch = pitch; glyph_info->bmp_size = pitch * glyph_info->bbox_h; break; @@ -264,7 +270,9 @@ int GUIAPI GetGlyphInfo (LOGFONT* logfont, Glyph32 glyph_value, case GLYPHBMP_TYPE_GREY: glyph_info->bits = devfont->font_ops->get_glyph_greybitmap ( logfont, devfont, glyph_value, - &glyph_info->bmp_pitch, NULL); + &sz, &glyph_info->bmp_pitch, NULL); + glyph_info->bbox_w = sz.cx; + glyph_info->bbox_h = sz.cy; glyph_info->bmp_size = glyph_info->bmp_pitch * glyph_info->bbox_h; break; @@ -272,7 +280,9 @@ int GUIAPI GetGlyphInfo (LOGFONT* logfont, Glyph32 glyph_value, case GLYPHBMP_TYPE_SUBPIXEL: glyph_info->bits = devfont->font_ops->get_glyph_greybitmap ( logfont, devfont, glyph_value, - &glyph_info->bmp_pitch, NULL); + &sz, &glyph_info->bmp_pitch, NULL); + glyph_info->bbox_w = sz.cx; + glyph_info->bbox_h = sz.cy; glyph_info->bmp_size = glyph_info->bmp_pitch * glyph_info->bbox_h; break; @@ -1838,14 +1848,14 @@ static BOOL get_subpixel_bmp (PDC pdc, Glyph32 glyph_value, SIZE* bbx_size, *devfont->font_ops->get_glyph_greybitmap) { /* the returned bits will be the subpixled pixmap */ data = (*devfont->font_ops->get_glyph_greybitmap) (logfont, devfont, - REAL_GLYPH(glyph_value), &data_pitch, &scale); + REAL_GLYPH(glyph_value), bbx_size, &data_pitch, &scale); } #endif if (data == NULL) { data = (*devfont->font_ops->get_glyph_monobitmap) (logfont, devfont, - REAL_GLYPH(glyph_value), &data_pitch, &scale); + REAL_GLYPH(glyph_value), bbx_size, &data_pitch, &scale); } if (data == NULL) @@ -1891,7 +1901,7 @@ static BOOL get_book_bmp (PDC pdc, Glyph32 glyph_value, SIZE* bbx_size, /*get preybitmap and expand*/ if (devfont->font_ops->get_glyph_greybitmap) { data = (*devfont->font_ops->get_glyph_greybitmap) (logfont, devfont, - REAL_GLYPH(glyph_value), &data_pitch, &scale); + REAL_GLYPH(glyph_value), bbx_size, &data_pitch, &scale); } if (data) @@ -1928,7 +1938,7 @@ static BOOL get_book_bmp (PDC pdc, Glyph32 glyph_value, SIZE* bbx_size, } data = (*devfont->font_ops->get_glyph_monobitmap) (logfont, devfont, - REAL_GLYPH(glyph_value), &data_pitch, &scale); + REAL_GLYPH(glyph_value), bbx_size, &data_pitch, &scale); if (data == NULL) return FALSE; @@ -1991,7 +2001,7 @@ static BOOL get_light_bmp (PDC pdc, Glyph32 glyph_value, SIZE* bbx_size, data = NULL; data = (*devfont->font_ops->get_glyph_monobitmap) (logfont, devfont, - REAL_GLYPH(glyph_value), &pitch, &scale); + REAL_GLYPH(glyph_value), bbx_size, &pitch, &scale); if (data == NULL) return FALSE; @@ -2079,7 +2089,7 @@ static BOOL get_regular_bmp (PDC pdc, Glyph32 glyph_value, SIZE* bbx_size, data = NULL; data = (*devfont->font_ops->get_glyph_monobitmap) (logfont, devfont, - REAL_GLYPH(glyph_value), &pitch, &scale); + REAL_GLYPH(glyph_value), bbx_size, &pitch, &scale); if (!data) return FALSE; @@ -3726,7 +3736,7 @@ static BOOL _gdi_get_glyph_data (PDC pdc, Glyph32 glyph_value, } data = (BYTE*)(*devfont->font_ops->get_glyph_monobitmap) (logfont, devfont, - REAL_GLYPH(glyph_value), &pitch, &scale); + REAL_GLYPH(glyph_value), bbox, &pitch, &scale); if (data == NULL) break; @@ -3760,7 +3770,7 @@ static BOOL _gdi_get_glyph_data (PDC pdc, Glyph32 glyph_value, /* get preybitmap */ if (devfont->font_ops->get_glyph_greybitmap) { data = (BYTE*)(*devfont->font_ops->get_glyph_greybitmap) (logfont, devfont, - REAL_GLYPH (glyph_value), &pitch, &scale); + REAL_GLYPH (glyph_value), bbox, &pitch, &scale); ctxt->cb = _dc_bookgrey_scan_line; if (data && scale > 1) { bbox->cx = bbox->cx / scale; @@ -3782,7 +3792,7 @@ static BOOL _gdi_get_glyph_data (PDC pdc, Glyph32 glyph_value, *devfont->font_ops->get_glyph_greybitmap) { /* the returned bits will be the subpixled pixmap */ data = (BYTE*)(*devfont->font_ops->get_glyph_greybitmap) (logfont, devfont, - REAL_GLYPH(glyph_value), &pitch, &scale); + REAL_GLYPH(glyph_value), bbox, &pitch, &scale); ctxt->cb = _dc_ft2subpixel_scan_line; } #endif