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