source: svn/trunk/zasc/app_c/DST_FontEngine.c @ 40

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

first commit

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