source: svn/trunk/zasc/app/DST_FontEngine.cpp @ 2

Last change on this file since 2 was 2, checked in by phkim, 11 years ago

1.phkim

  1. revision copy newcon3sk r27
File size: 24.5 KB
Line 
1/********************************************************************
2*  DST_NewFontEngine.c
3*       -Font Engine
4*
5*  Copyright (c)2008 Digital STREAM Tech, Inc.
6*  All Rights Reserved
7*
8*  $Id: DST_FontEngine.cpp,v 1.5 2012/04/12 05:39:08 megakiss Exp $
9*********************************************************************/
10#include "DST_Common.h"
11#include "DST_FontEngine.h"
12
13#include "freetype/ftoutln.h"
14#include FT_FREETYPE_H
15
16static int DST_GetFontBaseLine(int nSize);
17static int DST_GetFontEdgeWidth(int nFontSize);
18
19#define DYNAMIC_MEMORY 0
20// ÆùÆ®¿ë ij½¬ ±¸Á¶
21#define CACHE_MAX 1000
22typedef struct _FontCache
23{
24        DS_U32 nCode;
25        DS_U8 nSize;
26        DS_U8 nStyle;
27        DS_U8 nOffset; // Áö¿ø ÇÊ¿ä
28        bool bItalic;
29        DS_S16 x;
30        DS_S16 y;
31        DS_S16 w;
32        DS_S16 h;
33        DS_S16 width; // ´ÙÀ½ ±ÛÀÚÀÇ À§Ä¡
34#if DYNAMIC_MEMORY
35        DS_U8 *buff;
36#else
37        DS_U8 buff[4096];
38#endif
39} FontCache;
40
41static FontCache fontCache[CACHE_MAX];
42
43static DS_U32 DST_U8ToU32(DS_U8* buff)
44{
45        return buff[0]*256*256*256+buff[1]*256*256+buff[2]*256+buff[3];
46}
47
48// ´ÜÀÏ Å½ºÅ©·Î CC ¹× OSD¸¦ ±×¸±¿¹Á¤À̹ǷΠ¼¼¸¶Æ÷¾î¸¦ ¾²Áö ¾ÊÀ½
49static int DST_GetFont(DS_U32 nCode, DS_U8 nSize, DS_U8 nStyle, DS_U8 nOffset, bool bItalic)
50{
51        static int nCacheCount = 0;
52        static int nCachePosition = -1;
53        static FT_Library DST_g_FT_library;
54        static FT_Face DST_g_FT_Face[2];
55        int x = 0; // Àӽà º¯¼ö
56
57        static bool bFirst = true;
58        if (bFirst == true)
59        {
60                bFirst = false;
61                FT_Init_FreeType( &DST_g_FT_library );
62                extern DS_U8 UnDotumBold[];
63                extern DS_U8 Special[];
64                FT_New_Memory_Face(DST_g_FT_library, &UnDotumBold[5], DST_U8ToU32((DS_U8*)&UnDotumBold[1]), 0, &DST_g_FT_Face[0]);
65                FT_New_Memory_Face(DST_g_FT_library, &Special[5], DST_U8ToU32((DS_U8*)&Special[1]), 0, &DST_g_FT_Face[1]);
66                memset(fontCache, 0, CACHE_MAX * sizeof(FontCache)); // ij½¬ Á¤º¸ ÃʱâÈ­
67                DST_Printf("DST_g_FT_Face[0]=%d\n", (int)DST_g_FT_Face[0]);
68                DST_Printf("DST_g_FT_Face[1]=%d\n", (int)DST_g_FT_Face[1]);
69                DST_Printf("Font Engine Initialized\n");
70                FT_Int major = 0, minor = 0, patch = 0;
71                FT_Library_Version( DST_g_FT_library, &major, &minor, &patch);
72                DST_Printf("FreeType Library Version %d.%d.%d\n", major, minor, patch);
73        }
74        // ÄÚµå °ü·Ã º¸Á¤
75        if (nCode == 0x2013) nCode = '-'; // hack.trpÀÇ ETT
76        if (nCode == 0x00A0) nCode = 0x20;
77        if (nCode == 0x3000) nCode = 0x20; // UniCode ÀÇ ÆøÀÌ ³ÐÀº °ø¹é ¹®ÀÚ¸¦ ÆøÀÌ Á¼Àº °ø¹é ¹®ÀÚ·Î ´ëüÇÑ´Ù. (SBS)
78        if (nCode == 0xF90A) nCode = 0x91D1; // ÐÝÀÇ µ¿ÀÚ
79        // ½ºÅ¸ÀÏ °ü·Ã º¸Á¤
80        nStyle = 0;
81        if (nCode == 0x26A0) nStyle = 1; // Ư¼ö¹®ÀÚ Warning
82        if (nCode <  0x0020) nStyle = 1; // Ư¼ö¹®ÀÚ
83        if (nCode >=  0xE000 && nCode <= 0xEFFF) nStyle = 1; // »ç¿ëÀÚ Á¤ÀÇ ¿µ¿ª
84        // ij½¬¿¡¼­ ÀÏÄ¡ÇÏ´Â Á¤º¸¸¦ ã´Â´Ù
85        for (x = 0; x < nCacheCount; x++)
86        {
87                if (fontCache[x].nCode != nCode) continue;
88                if (fontCache[x].nSize != nSize) continue;
89                if (fontCache[x].nStyle != nStyle) continue;
90                if (fontCache[x].nOffset != nOffset) continue;
91                if (fontCache[x].bItalic != bItalic) continue;
92                return x;
93        }
94  if (FT_Set_Pixel_Sizes( DST_g_FT_Face[nStyle], 0, nSize )) return DST_GetFont(0x0020, nSize, nStyle, nOffset, bItalic);
95  FT_Matrix matrix = { 0x10000, 0x0, 0x0, 0x10000};
96  FT_Vector pen = {0, 0};
97  matrix.xy = bItalic ? 0x34fd : 0; // ÀÌÅŸ¯ ¼³Á¤
98
99  if (nOffset != 0) // ÷ÀÚ Ã³¸®
100  {
101      matrix.xx = (matrix.xx * 70) / 100; // 70%»çÀÌÁî
102      matrix.xy = (matrix.xy * 70) / 100;
103      matrix.yx = (matrix.yx * 70) / 100;
104      matrix.yy = (matrix.yy * 70) / 100;
105  }
106  if (nOffset == 2) // À§Ã·ÀÚ
107  {
108      pen.x = 0;
109      pen.y = (nSize * 64 * 37) / 100; // 30% À§·Î ¿Ã¸°´Ù.(37%À϶§ º¸±â ÁÁ´Ù.)
110  }
111  FT_Set_Transform( DST_g_FT_Face[nStyle], &matrix, &pen );
112  FT_UInt  glyph_index = FT_Get_Char_Index( DST_g_FT_Face[nStyle], nCode );
113  if (FT_Load_Glyph( DST_g_FT_Face[nStyle],glyph_index, FT_LOAD_DEFAULT )) return DST_GetFont(0x0020, nSize, nStyle, nOffset, bItalic);
114  if (FT_Render_Glyph(DST_g_FT_Face[nStyle]->glyph, FT_RENDER_MODE_NORMAL)) return DST_GetFont(0x0020, nSize, nStyle, nOffset, bItalic);
115
116        if (nCacheCount < CACHE_MAX) nCacheCount++;// ij½¬¿¡ Áý¾î³ÖÀÚ.
117        nCachePosition++;
118        if (nCachePosition == CACHE_MAX) nCachePosition = 0;
119  fontCache[nCachePosition].nCode = nCode;
120  fontCache[nCachePosition].nSize = nSize;
121  fontCache[nCachePosition].nStyle = nStyle;
122  fontCache[nCachePosition].bItalic = bItalic;
123  fontCache[nCachePosition].nOffset = nOffset;
124
125  fontCache[nCachePosition].x = DST_g_FT_Face[nStyle]->glyph->bitmap_left;
126  fontCache[nCachePosition].y = DST_g_FT_Face[nStyle]->glyph->bitmap_top;
127  fontCache[nCachePosition].w = DST_g_FT_Face[nStyle]->glyph->bitmap.width;
128  fontCache[nCachePosition].h = DST_g_FT_Face[nStyle]->glyph->bitmap.rows;
129  fontCache[nCachePosition].width = (DST_g_FT_Face[nStyle]->glyph->advance.x) >> 6;
130#if DYNAMIC_MEMORY
131  if (fontCache[nCachePosition].buff != 0) DST_OS_Free(&fontCache[nCachePosition].buff);
132  fontCache[nCachePosition].buff = (DS_U8 *)DST_OS_Malloc(fontCache[nCachePosition].w * fontCache[nCachePosition].h);
133#endif
134  memcpy(fontCache[nCachePosition].buff, DST_g_FT_Face[nStyle]->glyph->bitmap.buffer,
135        fontCache[nCachePosition].w * fontCache[nCachePosition].h);
136
137        return nCachePosition;
138}
139
140static int DST_GetFontEdgeWidth(int nFontSize)
141{
142        int nSize = nFontSize/5;
143        if (nSize < 1) nSize = 1;
144        return nSize;
145}
146
147// ÆùÆ®ÀÇ ³ôÀ̸¦ ±¸ÇÑ´Ù.
148static int DST_g_FontHeight[256] = {0};
149static int DST_g_FontBaseLine[256] = {0};
150
151// ¿©·¯ ÆùÆ®¸¦ ¼¯¾î ¾²±â À§Çؼ­ ÇÊ¿äÇÑ ÀÛ¾÷
152static void DST_GetFontHeightSub(int nSize)
153{
154        int nEdgeWidth = DST_GetFontEdgeWidth(nSize);
155        int pos1 = DST_GetFont(0x6A, nSize, 0,0,false); // j
156        int pos2 = DST_GetFont(0x203E, nSize, 0,0,false); // À§ÂÊ ¹Ù   
157        DST_g_FontHeight[nSize] = fontCache[pos1].h - fontCache[pos1].y + fontCache[pos2].y + nEdgeWidth + nEdgeWidth;
158        DST_g_FontBaseLine[nSize] = fontCache[pos2].y + nEdgeWidth+nEdgeWidth/3; // ³ª´®ÆùÆ®´Â nEdgeWidth/3 ¸¸Å­ ³»¸°´Ù.
159}
160
161// ÆùÆ®ÀÇ ³ôÀ̸¦ ¹ÝȯÇÑ´Ù.
162int DST_GetFontHeight(int nSize)
163{
164        if (DST_g_FontHeight[nSize] == 0) DST_GetFontHeightSub(nSize);
165        return DST_g_FontHeight[nSize];
166}
167
168// ÆùÆ®ÀÇ º£À̽º¶óÀαîÁöÀÇ °Å¸®¸¦ ¹ÝȯÇÑ´Ù.
169static int DST_GetFontBaseLine(int nSize)
170{
171        if (DST_g_FontBaseLine[nSize] == 0) DST_GetFontHeightSub(nSize);
172        return DST_g_FontBaseLine[nSize];
173}
174
175// ÀÔ·ÂµÈ ¹®ÀÚÁß °¡Àå Å« ÆùÆ® »çÀÌÁ ÃßÃâÇÑ´Ù.
176static int DST_GetMaxFontSize(FONT_CC data[], int nCount)
177{
178        int i = 0;
179        if (nCount == 0) return 0;
180        int nMax = data[0].nSize;
181        for (i = 0; i < nCount; i++)
182        {
183                if (nMax < data[i].nSize) nMax = data[i].nSize;
184        }
185        return nMax;
186}
187
188int DST_GetFontHeightCC(FONT_CC data[], int nCount)
189{
190  if (nCount == 0) return 0;
191  return DST_GetFontHeight(DST_GetMaxFontSize(data, nCount));
192}
193
194// ÆùÆ®ÀÇ ³ÐÀ̸¦ ±¸ÇÑ´Ù.
195int DST_GetFontWidthCC(FONT_CC data[], int nCount)
196{
197        int i = 0;
198        if (nCount == 0) return 0;
199        int nTotalWidth = 0;
200        int nMaxWidth = 0;
201        for (i = 0; i < nCount; i++)
202        {
203    // int nPos = DST_GetFontArib(data[i].nCode, data[i].nSize, data[i].nStyle, data[i].nOffset, data[i].bItalic);
204    int nPos = DST_GetFont(data[i].nCode, data[i].nSize, data[i].nStyle,data[i].nOffset,data[i].bItalic);
205            if (i==0) // ù¹øÂ° ±ÛÀÚÀÇ ¿ÞÂÊ »ßÁ®³²¿È Á¤µµ + Edge + margin
206            {
207              if (fontCache[nPos].x < 0) nTotalWidth -= fontCache[nPos].x;
208              nTotalWidth += (DST_GetFontEdgeWidth(data[i].nSize) * 2); 
209            }
210            nTotalWidth = nTotalWidth + fontCache[nPos].width;
211            // µ¥ÀÌÅÍÀÇ widthº¸´Ù ±×·ÁÁ®¾ßÇÏ´Â ÆùÆ®°¡ ¿À¸¥ÂÊÀ¸·Î ´õ »ßÁ®³ª¿Â´Ù¸é
212            // À̰ÍÀ» ¸Æ½º·Î ÇØ¾ßÇÑ´Ù. [hand.] µîÀÇ ¹®ÀÚ´Â
213            // Çʱâü ÀÌÅŸ¯ÀÎ °æ¿ì dÀÇ ¿À¸¥ÂÊ ³¡ÀÌ '.' º¸´Ù ¹Û¿¡ ÀÖ´Â °æ¿ì¸¦ °í·ÁÇØ¾ß ÇÑ´Ù.
214            int nDelta = fontCache[nPos].x + fontCache[nPos].w - fontCache[nPos].width;
215            if (nDelta < 0) nDelta = 0;
216            if (nTotalWidth + nDelta > nMaxWidth) nMaxWidth = nTotalWidth + nDelta;
217            // ¸¶Áö¸· ±ÛÀÚÀÇ ¿§Áö Å©±â¸¸Å­ ¸¶Áø Àû¿ë
218                if (i == nCount -1)  nMaxWidth += (DST_GetFontEdgeWidth(data[i].nSize) * 2);
219        }
220        return nMaxWidth;
221}
222
223static void DST_DrawBox(int des_w, int des_h, OSD_PIXEL_T* des, int x, int y, int w, int h, OSD_PIXEL_T color)
224{
225        if (des == 0 || w < 1 || h < 1 || des_w < 1 || des_h < 1) return;
226        if (x < 0) x = 0;
227        if (y < 0) y = 0;
228        if (x + w > des_w) w = des_w - x;
229        if (y + h > des_h) h = des_h - y;
230        des += (des_w*y+x);
231        int delta = des_w - w;
232        while (h--)
233        {
234                int ww = w;
235                while (ww--) *des++ = color;
236                des += delta;
237        }
238}
239
240
241OSD_PIXEL_T DST_SetColor(OSD_PIXEL_T a, OSD_PIXEL_T r, OSD_PIXEL_T g, OSD_PIXEL_T b)
242{
243        if (sizeof(OSD_PIXEL_T) == 2) // 16ºñÆ®ÀÎ °æ¿ì
244        {
245                OSD_PIXEL_T max = 0x0F;
246                if (a > max) a = max;
247                if (r > max) r = max;
248                if (g > max) g = max;
249                if (b > max) b = max;
250                return (a<<12) | (r<<8) | (g<<4) | b;
251        }
252        // 32ºñÆ®ÀÎ °æ¿ì
253        OSD_PIXEL_T max = 0xFF;
254        if (a > max) a = max;
255        if (r > max) r = max;
256        if (g > max) g = max;
257        if (b > max) b = max;
258        return (a<<24) | (r<<16) | (g<<8) | b;
259}
260
261void DST_GetColor(OSD_PIXEL_T color, OSD_PIXEL_T *a, OSD_PIXEL_T *r, OSD_PIXEL_T *g, OSD_PIXEL_T *b)
262{
263        if (sizeof(OSD_PIXEL_T) == 1) // 8ºñÆ®ÀÎ °æ¿ì
264        {
265                return;
266        }
267        if (sizeof(OSD_PIXEL_T) == 2) // 16ºñÆ®ÀÎ °æ¿ì
268        {
269                OSD_PIXEL_T mask = 0x0F;
270                *a = (color >> 12) & mask;
271                *r = (color >>  8) & mask;
272                *g = (color >>  4) & mask;
273                *b = color & mask;
274                return;
275        }
276        // 32ºñÆ®ÀÎ °æ¿ì
277        OSD_PIXEL_T mask = 0xFF;
278        *a = (color >> 24) & mask;
279        *r = (color >> 16) & mask;
280        *g = (color >>  8) & mask;
281        *b = color & mask;
282}
283
284static OSD_PIXEL_T DST_ColorCalcuration(OSD_PIXEL_T foreColor, DS_U8 nWeight, OSD_PIXEL_T backColor)
285{
286        if (nWeight == 0xFF) return foreColor;
287        if (nWeight == 0) return backColor;
288        if (sizeof(OSD_PIXEL_T) == 1) // 8ºñÆ®ÀÎ °æ¿ì
289        {
290                if (foreColor == 0) return backColor;
291                if (backColor == 0) return foreColor;
292                return (nWeight > 128) ? foreColor : backColor;
293        }
294        if (sizeof(OSD_PIXEL_T) == 2) // 16ºñÆ®ÀÎ °æ¿ì
295        {
296                if (foreColor == 0)
297                {
298                        // Àü°æ»öÀÌ Åõ¸íÀÎ °æ¿ì
299                        if (backColor == 0) return 0;
300                        OSD_PIXEL_T a,r,g,b;
301                        DST_GetColor(backColor, &a, &r, &g, &b);
302                        a = nWeight * a / 255;
303                        return DST_SetColor(a, r, g, b);
304                }
305                if (backColor == 0)
306                {
307                        OSD_PIXEL_T a,r,g,b;
308                        DST_GetColor(foreColor, &a, &r, &g, &b);
309                        a = nWeight/16;
310                        return DST_SetColor(a, r, g, b);
311                }
312                if (foreColor == 0xFFFF && backColor == 0xF000) // °ËÀº¹ÙÅÁ¿¡ Èò±Û¾¾
313                {
314                        OSD_PIXEL_T nWeight4 = nWeight / 16;
315                        return DST_SetColor(0xF, nWeight4, nWeight4, nWeight4);
316                }
317                OSD_PIXEL_T fa,fr,fg,fb;
318                DST_GetColor(foreColor, &fa, &fr, &fg, &fb);
319                OSD_PIXEL_T ba,br,bg,bb;
320                DST_GetColor(backColor, &ba, &br, &bg, &bb);
321
322                OSD_PIXEL_T max = 0xFF;
323                //OSD_PIXEL_T a = ba + (fa*(max-(ba*nWeight)/max))/max;
324                OSD_PIXEL_T a = ((nWeight*fa) + (max-nWeight)*ba)/max;
325                OSD_PIXEL_T r = ((nWeight*fr) + (max-nWeight)*br)/max;
326                OSD_PIXEL_T g = ((nWeight*fg) + (max-nWeight)*bg)/max;
327                OSD_PIXEL_T b = ((nWeight*fb) + (max-nWeight)*bb)/max;
328                return DST_SetColor(a,r,g,b);
329        }
330        // 32ºñÆ®ÀÎ °æ¿ì
331        if (foreColor == 0)
332        {
333                // Àü°æ»öÀÌ Åõ¸íÀÎ °æ¿ì
334                if (backColor == 0) return 0;
335                OSD_PIXEL_T a,r,g,b;
336                DST_GetColor(backColor, &a, &r, &g, &b);
337                a = nWeight * a / 255;
338                return DST_SetColor(a, r, g, b);
339        }
340        if (backColor == 0)
341        {
342                OSD_PIXEL_T a,r,g,b;
343                DST_GetColor(foreColor, &a, &r, &g, &b);
344                a = nWeight;
345                return DST_SetColor(a, r, g, b);
346        }
347        if (foreColor == CONV32_16(0xFFFFFFFF) && backColor == CONV32_16(0xFF000000)) // °ËÀº¹ÙÅÁ¿¡ Èò±Û¾¾
348        {
349                return DST_SetColor(0xFF, nWeight, nWeight, nWeight);
350        }
351        OSD_PIXEL_T fa,fr,fg,fb;
352        DST_GetColor(foreColor, &fa, &fr, &fg, &fb);
353        OSD_PIXEL_T ba,br,bg,bb;
354        DST_GetColor(backColor, &ba, &br, &bg, &bb);
355
356        OSD_PIXEL_T max = 0xFF;
357        //OSD_PIXEL_T a = ba + (fa*(max-(ba*nWeight)/max))/max;
358        OSD_PIXEL_T a = ((nWeight*fa) + (max-nWeight)*ba)/max;
359        OSD_PIXEL_T r = ((nWeight*fr) + (max-nWeight)*br)/max;
360        OSD_PIXEL_T g = ((nWeight*fg) + (max-nWeight)*bg)/max;
361        OSD_PIXEL_T b = ((nWeight*fb) + (max-nWeight)*bb)/max;
362        return DST_SetColor(a,r,g,b);
363}
364
365//°¡ÁßÄ¡ °ª°ú »öÀ» ÀúÁ¤Çϱâ À§ÇÑ ¹öÆÛ °è»êÀ» À§ÇÑ ÇÔ¼ö
366// Edge µîÀÇ ¿¬»ê¿¡¼­´Â °¡ÁßÄ¡ °ªÀ» ´õÇϱ⠿¬»êÇÏ¿©¾ß ÇÑ´Ù.
367// ±ÛÀÚ¸¦ ±×¸®´Â ¼ø¼­´Â ´ÙÀ½°ú °°´Ù.
368// ¹è°æ ±×¸®±â
369// ¿¡Áö¹öÆÛ ±¸Çϱâ (°¡ÁßÄ¡+»ö)
370// ±ÛÀÚ¹öÆÛ ±¸Çϱâ (°¡ÁßÄ¡+»ö)
371// ¹è°æ¿¡ ¿¡Áö¹öÆÛ ´õÇϱâ
372// ¹è°æ¿¡ ¿¡Áö¹öÆÛ ´õÇÑ ¹öÆÛ¿¡ ±ÛÀÚ¹öÆÛ ´õÇϱâ
373static void DST_PrintBuff(int des_w,  int des_h, DS_U8* desWeight, OSD_PIXEL_T* desColor,
374                int src_w, int src_h, DS_U8* src, int x_pos, int y_pos, OSD_PIXEL_T color)
375{
376        if (des_w < 1 || des_h < 1)
377        {
378                return;
379        }
380        if (src_w < 1 || src_h < 1)
381        {
382                return;
383        }
384        if (src_w > des_w)
385        {
386                return;
387        }
388        if (src_h > des_h)
389        {
390                return;
391        }
392        if (x_pos < 0)
393        {
394                x_pos = 0;
395        }
396        if (y_pos < 0)
397        {
398                y_pos = 0;
399        }
400        if (x_pos + src_w > des_w)
401        {
402                x_pos = des_w - src_w;
403        }
404        if (y_pos + src_h > des_h)
405        {
406                y_pos = des_h - src_h;
407        }
408               
409        int x = 0, y = 0;
410        DS_U8 *src1 = src;
411        for (y = 0; y < src_h; y++)
412        {
413                DS_U8 *desWeight1 = desWeight + des_w * (y_pos+y) + x_pos;
414                OSD_PIXEL_T *desColor1 = desColor + des_w * (y_pos+y) + x_pos;
415                for (x = 0; x < src_w; x++)
416                {
417                        if (*desWeight1)
418                        {
419                                *desWeight1 = (*desWeight1 > *src1) ? *desWeight1 : *src1;
420                        }
421                        else
422                        {
423                                *desWeight1 = *src1;
424                        }
425                        if (*src1 > 0) *desColor1 = color;
426                        src1++;
427                        desWeight1++;
428                        desColor1++;
429                }
430        }
431}
432
433struct FontImageCache
434{
435        FONT_CC *data;
436        int nCount;
437        OSD_PIXEL_T *buff;
438};
439
440#define MAX_FONT_IMAGE_CACHE 100
441static FontImageCache fontimagecache[MAX_FONT_IMAGE_CACHE];
442static int g_FontImageCacheWritePosition = 0;
443
444static bool DST_GetFontImageCache(FONT_CC data[], int nCount, OSD_PIXEL_T *buff, int width, int height)
445{
446        for (int i = 0; i < MAX_FONT_IMAGE_CACHE; i++)
447        {
448                if (nCount != fontimagecache[i].nCount) continue;
449                if (memcmp(data, fontimagecache[i].data, nCount * sizeof(FONT_CC)) != 0) continue;
450                memcpy(buff, fontimagecache[i].buff, width * height * sizeof(OSD_PIXEL_T));
451                return true;
452        }
453        return false;
454}
455
456static void DST_SetFontImageCache(FONT_CC data[], int nCount, OSD_PIXEL_T *buff, int width, int height)
457{
458        if (fontimagecache[g_FontImageCacheWritePosition].data) DST_OS_Free(&fontimagecache[g_FontImageCacheWritePosition].data);
459        if (fontimagecache[g_FontImageCacheWritePosition].buff) DST_OS_Free(&fontimagecache[g_FontImageCacheWritePosition].buff);
460               
461        fontimagecache[g_FontImageCacheWritePosition].data = (FONT_CC *)DST_OS_Malloc(nCount * sizeof(FONT_CC));
462        memcpy(fontimagecache[g_FontImageCacheWritePosition].data, data, nCount * sizeof(FONT_CC));
463        fontimagecache[g_FontImageCacheWritePosition].nCount = nCount;
464        fontimagecache[g_FontImageCacheWritePosition].buff = (OSD_PIXEL_T *)DST_OS_Malloc(width * height * sizeof(OSD_PIXEL_T));
465        memcpy(fontimagecache[g_FontImageCacheWritePosition].buff, buff, width * height * sizeof(OSD_PIXEL_T));
466       
467        g_FontImageCacheWritePosition++;
468        if (g_FontImageCacheWritePosition >= MAX_FONT_IMAGE_CACHE) g_FontImageCacheWritePosition = 0;
469}
470
471// ÆùÆ®ÀÇ À̹ÌÁö¸¦ ±¸ÇÑ´Ù.
472void DST_GetFontImageCC(FONT_CC data[], int nCount, OSD_PIXEL_T *buff)
473{
474        int x = 0, y = 0, i = 0, j = 0, x_pos = 0;
475        if (nCount == 0) return;
476        int width = DST_GetFontWidthCC(data, nCount);
477        int height = DST_GetFontHeightCC(data, nCount);
478        if (width < 1 || height < 1) return;
479       
480        if (DST_GetFontImageCache(data, nCount, buff, width, height) == true) return;
481        // mallocÀ» ¸¹ÀÌ ÇÏ´Â ¹æ½ÄÀº ºÒ¾ÈÁ¤ÇϹǷÎ
482        // ÀÌÀü Å©±âº¸´Ù Ä¿Áø °æ¿ì¿¡¸¸ mallocÀ» Çϵµ·Ï ÇÑ´Ù.
483        static int nBuffSize = 0;
484        static DS_U8 *buff_char = 0; // °¡ÁßÄ¡ °ª ¹öÆÛ
485        static DS_U8 *buff_edge = 0;
486        static OSD_PIXEL_T *buff_char_color = 0; // »ö ¹öÆÛ
487        static OSD_PIXEL_T *buff_edge_color = 0;
488        if (width * height > nBuffSize)
489        {
490                nBuffSize = width * height;
491                DST_OS_Free(&buff_char);
492                DST_OS_Free(&buff_edge);
493                DST_OS_Free(&buff_char_color);
494                DST_OS_Free(&buff_edge_color);
495                buff_char = (DS_U8*)DST_OS_Malloc(nBuffSize);
496                buff_edge = (DS_U8*)DST_OS_Malloc(nBuffSize);
497                buff_char_color = (OSD_PIXEL_T*)DST_OS_Malloc(sizeof(OSD_PIXEL_T) * nBuffSize);
498                buff_edge_color = (OSD_PIXEL_T*)DST_OS_Malloc(sizeof(OSD_PIXEL_T) * nBuffSize);
499        }
500       
501        memset(buff_char, 0, nBuffSize);
502        memset(buff_edge, 0, nBuffSize);
503        memset(buff_char_color, 0, nBuffSize*sizeof(OSD_PIXEL_T));
504        memset(buff_edge_color, 0, nBuffSize*sizeof(OSD_PIXEL_T));
505       
506        // ±âÁؼ±ÀÇ À§Ä¡¸¦ Àâ´Â´Ù.
507        int nMaxBaseLine = DST_GetFontBaseLine(DST_GetMaxFontSize(data, nCount));
508       
509        for (i = 0; i < nCount; i++)
510        {
511                //int nPos = DST_GetFontArib(data[i].nCode, data[i].nSize, data[i].nStyle,data[i].nOffset,data[i].bItalic);
512                int nPos = DST_GetFont(data[i].nCode, data[i].nSize, data[i].nStyle,data[i].nOffset,data[i].bItalic);
513                int nEdgeWidth = DST_GetFontEdgeWidth(data[i].nSize);
514                if (i==0)
515                {
516                        // ù¹øÂ° ±ÛÀÚÀÇ ¿ÞÂÊ »ßÁ®³²¿È Á¤µµ + Edge + margin
517                        if (fontCache[nPos].x < 0) x_pos -= fontCache[nPos].x;
518                        x_pos += (nEdgeWidth*2);
519                        DST_DrawBox(width, height, buff, 0, 0, x_pos + fontCache[nPos].width, height, data[i].BackColor);
520                }
521//              else // ±ÛÀÚ°¡ 1°³ÀÎ °æ¿ì µÞºÎºÐ¿¡ ¾²·¹±â °ªÀÌ ³²´Â ¹®Á¦·Î Á¦°Å
522                {
523                        if (i== nCount -1)
524                        {
525                                DST_DrawBox(width, height, buff, x_pos, 0, width - x_pos, height, data[i].BackColor);
526                        }
527                        else
528                        {
529                                DST_DrawBox(width, height, buff, x_pos, 0, fontCache[nPos].width, height, data[i].BackColor);
530                        }
531                }
532                int nBaseX = x_pos + fontCache[nPos].x;
533                int nBaseY = nMaxBaseLine - fontCache[nPos].y;
534                if (nBaseX + fontCache[nPos].w > width)
535                {
536                        nBaseX = width -  fontCache[nPos].w;
537                }
538                if (nBaseY + fontCache[nPos].h > height)
539                {
540                        nBaseY = height -  fontCache[nPos].h;
541                        if (nBaseY < 0)
542                        {
543                                 fontCache[nPos].h = height;
544                                 nBaseY = 0;
545                        }
546                }
547                // ÆùÆ® ±×¸®±â   
548                DST_PrintBuff(width, height, buff_char, buff_char_color,
549                fontCache[nPos].w, fontCache[nPos].h, fontCache[nPos].buff,
550                nBaseX, nBaseY, data[i].Color);
551                // UnderLine Drawing
552                if (data[i].bUnderLine)
553                {
554                        int nUnderLineHeight = (nEdgeWidth * 70) / 100;
555                        if (nUnderLineHeight < 1) nUnderLineHeight =1;
556                        for (y = 0; y < nUnderLineHeight; y++)
557                        {
558                                for (x = 0; x < fontCache[nPos].width; x++)
559                                {
560                                        buff_edge[x_pos + width * (nMaxBaseLine + y+1)+x] = 200;
561                                        buff_edge_color[x_pos + width * (nMaxBaseLine + y+1)+x] = data[i].Color;
562                                }
563                        }
564                }
565                // Edge ±×¸®±â
566                switch (data[i].nEdgeType)
567                {
568                        case 1:
569                                for (j = 1; j <= nEdgeWidth; j++)
570                                {
571                                    DST_PrintBuff(width, height,buff_edge, buff_edge_color,
572                                        fontCache[nPos].w, fontCache[nPos].h, fontCache[nPos].buff,
573                                        nBaseX - j, nBaseY - j, data[i].EdgeColor);
574                                }
575                                break;
576                       
577                        case 2:
578                                for (j = 1; j <= nEdgeWidth; j++)
579                                {
580                                    DST_PrintBuff(width, height, buff_edge,  buff_edge_color,
581                                        fontCache[nPos].w, fontCache[nPos].h, fontCache[nPos].buff,
582                                        nBaseX + j, nBaseY + j , data[i].EdgeColor);
583                                }
584                                break;
585                       
586                        case 3:
587                                for (y = nEdgeWidth * -1; y <= nEdgeWidth; y++)
588                                {
589                                    for (x = nEdgeWidth * -1 ; x <= nEdgeWidth; x++)
590                                    {
591                                        DST_PrintBuff(width, height, buff_edge,  buff_edge_color,
592                                            fontCache[nPos].w, fontCache[nPos].h, fontCache[nPos].buff,
593                                            nBaseX + x, nBaseY + y , data[i].EdgeColor);
594                                    }
595                                }
596                                break;
597                       
598                        case 4:
599                                DST_PrintBuff(width, height, buff_edge,  buff_edge_color,
600                                      fontCache[nPos].w, fontCache[nPos].h, fontCache[nPos].buff,
601                                      nBaseX - nEdgeWidth, nBaseY + nEdgeWidth, data[i].EdgeColor);
602                                break;
603                       
604                        case 5:
605                                DST_PrintBuff(width, height, buff_edge,  buff_edge_color,
606                                      fontCache[nPos].w, fontCache[nPos].h, fontCache[nPos].buff,
607                                      nBaseX + nEdgeWidth, nBaseY + nEdgeWidth , data[i].EdgeColor);
608                                break;
609                }
610                x_pos += fontCache[nPos].width;
611        }
612        // Edge ¹öÆÛ¿Í char ¹öÆÛ¸¦ º¹»çÇÑ´Ù.
613        for (i=0; i < nBuffSize; i++)
614        {
615                // Edge ¹öÆÛ Àû¿ë
616                if (buff_edge[i] > 0)
617                {
618                        buff[i] = DST_ColorCalcuration(buff_edge_color[i], buff_edge[i], buff[i]);
619                }
620                // Char ¹öÆÛ Àû¿ë
621                if (buff_char[i] > 0)
622                {
623                        DS_U16 emphasis = (buff_char[i] * 150) / 100;
624                        if (emphasis > 255) emphasis = 255;
625                        buff[i] = DST_ColorCalcuration(buff_char_color[i], emphasis, buff[i]);
626                }
627        }
628        DST_SetFontImageCache(data, nCount, buff, width, height);
629}
630
631// OSD¿ë ÆùÆ®¿£Áø
632
633// ÅØ½ºÆ®ÀÇ ³ôÀ̸¦ ±¸ÇÑ´Ù.
634int DST_GetTextHeight(DS_U8 nSize)
635{
636        return DST_GetFontHeight(nSize);
637}
638
639// ÁöÁ¤ÇÑ ¹öÆÛ¿¡ ÆùÆ®¸¦ Ãâ·ÂÇÑ´Ù.
640bool DST_PrintText(
641        OSD_PIXEL_T *buffDes, int buffer_width, int /*buffer_height*/,
642        int x_pos, int y_pos,
643        DS_U32* strText, int nStrLen,  DS_U8 nSize, OSD_PIXEL_T Color)
644{
645        if (nStrLen < 1) return false;
646        int width = DST_GetTextWidth32(strText, nStrLen, nSize);
647  int height = DST_GetTextHeight(nSize);
648  if (width < 1 || height < 1) return false;
649  // 8ºñÆ® Gray ¹öÆÛ
650  static int nBuffSize = 0;
651  static DS_U8 *buff = 0;
652  if (width * height > nBuffSize) // ÀÔ·ÂµÈ ÃÖ´ë »çÀÌÁî·Î ¸Þ¸ð¸® ¹öÆÛ¸¦ °»½ÅÇØ¼­ ¸¸µç´Ù.
653  {
654        nBuffSize = width * height;
655        DST_OS_Free(&buff);
656        buff = (DS_U8 *)DST_OS_Malloc(nBuffSize);
657        }
658        memset(buff, 0, width * height);
659
660  int nMaxBaseLine = DST_GetFontBaseLine(nSize); // ±âÁؼ±ÀÇ À§Ä¡¸¦ Àâ´Â´Ù.
661  int nEdgeWidth = DST_GetFontEdgeWidth(nSize);
662
663        int x_posi = 0;
664  for (int i = 0; i < nStrLen; i++)
665  {
666    int nPos = DST_GetFont(strText[i], nSize, 0, 0, false);
667    if (i==0)
668    {
669            // ù¹øÂ° ±ÛÀÚÀÇ ¿ÞÂÊ »ßÁ®³²¿È Á¤µµ + Edge + margin
670            if (fontCache[nPos].x < 0) x_posi -= fontCache[nPos].x;
671            x_posi += (nEdgeWidth*2);
672    }
673    int nBaseX = x_posi + fontCache[nPos].x;
674                int nBaseY = nMaxBaseLine - fontCache[nPos].y;
675                DS_U8 *src1 = fontCache[nPos].buff;
676                for (int y = 0; y < fontCache[nPos].h; y++)
677                {
678                        DS_U8 *des1 = buff + width * (nBaseY+y) + nBaseX;
679                        for (int x = 0; x < fontCache[nPos].w; x++)
680                        {
681                                if (*src1) *des1 = *src1;
682                                src1++;
683                                des1++;
684                        }
685                }
686    x_posi += fontCache[nPos].width;
687  }
688  DS_U8 *p = buff;
689  for (int y=0; y < height; y++)
690  {
691        OSD_PIXEL_T *des1 = buffDes + (y_pos+y)*buffer_width + x_pos;
692        for (int x=0; x < width; x++)
693        {
694                if (*p) *des1 = DST_ColorCalcuration(Color, *p, *des1);
695                p++;
696                        des1++;
697        }
698        }
699        return true;
700}
701
702
703// À¯´ÏÄÚµå ÅØ½ºÆ® ÆøÀ» ±¸ÇÑ´Ù.
704int DST_GetTextWidth32(DS_U32* strText, DS_U16 nStrLen, DS_U8 nSize)
705{
706        if (strText == 0) return 0;
707        int i = 0;
708        int nTotalWidth = 0;
709        int nMaxWidth = 0;
710       
711        if (nStrLen < 1) return 0;
712        if (nStrLen > 4096) nStrLen = 4096;
713        for (int i = 0; i < nStrLen; i++)
714        {
715                if (strText[i] != 0) continue;
716                nStrLen = i;
717                break;
718        }
719
720        for (i = 0; i < nStrLen; i++)
721        {
722    int nPos = DST_GetFont(strText[i], nSize, 0, 0, false);
723    if (i==0) // ù¹øÂ° ±ÛÀÚÀÇ ¿ÞÂÊ »ßÁ®³²¿È Á¤µµ + Edge + margin
724    {
725      if (fontCache[nPos].x < 0) nTotalWidth -= fontCache[nPos].x;
726      nTotalWidth += (DST_GetFontEdgeWidth(nSize) * 2);
727    }
728    nTotalWidth = nTotalWidth + fontCache[nPos].width;
729    // µ¥ÀÌÅÍÀÇ widthº¸´Ù ±×·ÁÁ®¾ßÇÏ´Â ÆùÆ®°¡ ¿À¸¥ÂÊÀ¸·Î ´õ »ßÁ®³ª¿Â´Ù¸é
730    // À̰ÍÀ» ¸Æ½º·Î ÇØ¾ßÇÑ´Ù. [hand.] µîÀÇ ¹®ÀÚ´Â
731    // Çʱâü ÀÌÅŸ¯ÀÎ °æ¿ì dÀÇ ¿À¸¥ÂÊ ³¡ÀÌ '.' º¸´Ù ¹Û¿¡ ÀÖ´Â °æ¿ì¸¦ °í·ÁÇØ¾ß ÇÑ´Ù.
732    int nDelta = fontCache[nPos].x + fontCache[nPos].w - fontCache[nPos].width;
733    if (nDelta < 0) nDelta = 0;
734    if (nTotalWidth + nDelta > nMaxWidth) nMaxWidth = nTotalWidth + nDelta;
735    // ¸¶Áö¸· ±ÛÀÚÀÇ ¿§Áö Å©±â¸¸Å­ ¸¶Áø Àû¿ë
736        if (i == nStrLen -1)  nMaxWidth += (DST_GetFontEdgeWidth(nSize) * 2);
737        }
738        return nMaxWidth;
739}
740
741int DST_GetTextWidthUni(DS_U16* strText, DS_U16 nStrLen, DS_U8 nSize)
742{
743        if (nStrLen == 0) return 0; // ¹®ÀÚ¿­ÀÇ ±æÀ̰¡ 0À̸é 0ÀÌ´Ù.
744        DS_U32* strText32 = (DS_U32*)DST_OS_Malloc(nStrLen * sizeof(DS_U32));
745        for (int i = 0; i < nStrLen; i++) strText32[i] = (DS_U32)strText[i];
746        int ret = DST_GetTextWidth32(strText32, nStrLen, nSize);
747        DST_OS_Free(&strText32);
748        return ret;
749}
750
751int DST_GetTextWidthUni(DS_U16* strText, DS_U8 nSize)
752{
753        for (int i = 0; i < 4096; i++)
754        {
755                if (strText[i] == 0) return DST_GetTextWidthUni(strText, i, nSize);
756        }
757        return 0;
758}
759
760// À¯´ÏÄÚµå ¹®ÀÚ¿­ Áß ÁöÁ¤ÇÑ ºÎºÐÀÇ ÅØ½ºÆ® ÆøÀ» ±¸ÇÑ´Ù.
761int DST_GetTextWidthExtUni(int start, int width, DS_U16* strText, DS_U16 /*nStrLen*/, DS_U8 nSize)
762{
763        return DST_GetTextWidthUni(strText + start, width, nSize);
764}
765
766// ±×·ÁÁú ÅØ½ºÆ®ÀÇ ÆøÀ» ±¸ÇÑ´Ù. ÇÑ±Û ¸Þ´º¿¡¼­µµ È£ÃâÇÒ¼ö ÀÖ´Ù.
767int DST_GetTextWidth(char* strText, DS_U8 nSize)
768{
769        DS_U16 nStrLen = strlen(strText);
770        if (nStrLen == 0) return 0; // ¹®ÀÚ¿­ÀÇ ±æÀ̰¡ 0À̸é 0ÀÌ´Ù.
771        DS_U16* strText16 = (DS_U16*)DST_OS_Malloc(nStrLen * sizeof(DS_U16));
772        for (int i = 0; i < nStrLen; i++) strText16[i] = (DS_U16)(DS_U8)strText[i];
773        int ret = DST_GetTextWidthUni(strText16, nStrLen, nSize);
774        DST_OS_Free(&strText16);
775        return ret;
776}
777
778DS_U32* DST_UTF82Uni(DS_U8 *utf)
779{
780        if (utf == 0) return 0;
781        int nLen = strlen((char*)utf);
782        if (nLen == 0) return 0;
783        //printf("nLen=%d\n", nLen);
784        static DS_U32 buff[4096];
785        memset(buff, 0, 4096*4);
786        int nPos = 0;
787        for (int i = 0; i < nLen; i++)
788        {
789                if (utf[i] >= 0xF0)
790                { // 11110zzz 10zzxxxx 10xxxxxx 10xxxxxx
791                        buff[nPos] = ((utf[i] & 0x07) << 18) + ((utf[i+1] & 0x3F) << 16) + ((utf[i+2] & 0x3F) << 8) + (utf[i+3] & 0x3F);
792                        nPos++;
793                        i+=3;
794                        continue;
795                }
796                if (utf[i] >= 0xE0)
797                { // 1110xxxx 10xxxxxx 10xxxxxx
798                        buff[nPos] = ((utf[i] & 0x0F) << 12) + ((utf[i+1] & 0x3F) << 6) + (utf[i+2] & 0x3F);
799                        nPos++;
800                        i+=2;
801                        continue;
802                }
803                if (utf[i] >= 0xC0)
804                { // 110xxxxx 10xxxxxx
805                        buff[nPos] = ((utf[i] & 0x1F) << 6) + (utf[i+1] & 0x3F);
806                        nPos++;
807                        i++;
808                        continue;
809                }
810                if (utf[i] < 0x80)
811                { // 0xxxxxxx
812                        buff[nPos] = utf[i];
813                        nPos++;
814                        continue;
815                }
816        }
817        return buff;
818}
819
Note: See TracBrowser for help on using the repository browser.