/******************************************************************** * DST_NewFontEngine.c * -Font Engine * * Copyright (c)2008 Digital STREAM Tech, Inc. * All Rights Reserved * * $Id: DST_FontEngine.cpp,v 1.5 2012/04/12 05:39:08 megakiss Exp $ *********************************************************************/ #include "DST_Common.h" #include "DST_FontEngine.h" #include "freetype/ftoutln.h" #include FT_FREETYPE_H static int DST_GetFontBaseLine(int nSize); static int DST_GetFontEdgeWidth(int nFontSize); #define DYNAMIC_MEMORY 0 // ÆùÆ®¿ë ij½¬ ±¸Á¶ #define CACHE_MAX 100 #define FONT_BUFF_SIZE 600 typedef struct _FontCache { DS_U32 nCode; DS_U8 nSize; DS_U8 nStyle; DS_U8 nOffset; // Áö¿ø ÇÊ¿ä bool bItalic; DS_S16 x; DS_S16 y; DS_S16 w; DS_S16 h; DS_S16 width; // ´ÙÀ½ ±ÛÀÚÀÇ À§Ä¡ #if DYNAMIC_MEMORY DS_U8 *buff; #else DS_U8 buff[FONT_BUFF_SIZE]; #endif } FontCache; static FontCache fontCache[CACHE_MAX]; static DS_U32 DST_U8ToU32(DS_U8* buff) { return buff[0]*256*256*256+buff[1]*256*256+buff[2]*256+buff[3]; } // ´ÜÀÏ Å½ºÅ©·Î CC ¹× OSD¸¦ ±×¸±¿¹Á¤À̹ǷΠ¼¼¸¶Æ÷¾î¸¦ ¾²Áö ¾ÊÀ½ static int DST_GetFont(DS_U32 nCode, DS_U8 nSize, DS_U8 nStyle, DS_U8 nOffset, bool bItalic) { static int nCacheCount = 0; static int nCachePosition = -1; static FT_Library DST_g_FT_library; static FT_Face DST_g_FT_Face[2]; int x = 0; // Àӽà º¯¼ö static bool bFirst = true; if (bFirst == true) { bFirst = false; FT_Init_FreeType( &DST_g_FT_library ); extern DS_U8 UnDotumBold[]; extern DS_U8 Special[]; FT_New_Memory_Face(DST_g_FT_library, &UnDotumBold[5], DST_U8ToU32((DS_U8*)&UnDotumBold[1]), 0, &DST_g_FT_Face[0]); FT_New_Memory_Face(DST_g_FT_library, &Special[5], DST_U8ToU32((DS_U8*)&Special[1]), 0, &DST_g_FT_Face[1]); memset(fontCache, 0, CACHE_MAX * sizeof(FontCache)); // ij½¬ Á¤º¸ ÃʱâÈ­ DST_Printf("DST_g_FT_Face[0]=%d\n", (int)DST_g_FT_Face[0]); DST_Printf("DST_g_FT_Face[1]=%d\n", (int)DST_g_FT_Face[1]); DST_Printf("Font Engine Initialized\n"); FT_Int major = 0, minor = 0, patch = 0; FT_Library_Version( DST_g_FT_library, &major, &minor, &patch); DST_Printf("FreeType Library Version %d.%d.%d\n", major, minor, patch); } // ÄÚµå °ü·Ã º¸Á¤ if (nCode == 0x2013) nCode = '-'; // hack.trpÀÇ ETT if (nCode == 0x00A0) nCode = 0x20; if (nCode == 0x3000) nCode = 0x20; // UniCode ÀÇ ÆøÀÌ ³ÐÀº °ø¹é ¹®ÀÚ¸¦ ÆøÀÌ Á¼Àº °ø¹é ¹®ÀÚ·Î ´ëüÇÑ´Ù. (SBS) if (nCode == 0xF90A) nCode = 0x91D1; // ÐÝÀÇ µ¿ÀÚ // ½ºÅ¸ÀÏ °ü·Ã º¸Á¤ nStyle = 0; if (nCode == 0x26A0) nStyle = 1; // Ư¼ö¹®ÀÚ Warning if (nCode < 0x0020) nStyle = 1; // Ư¼ö¹®ÀÚ if (nCode >= 0xE000 && nCode <= 0xEFFF) nStyle = 1; // »ç¿ëÀÚ Á¤ÀÇ ¿µ¿ª // ÀºÆùÆ®¿¡ ¾ø´Â À¯´ÏÄÚµå if (nCode == 0x00AD) nCode = '-'; // Unicode Character 'SOFT HYPHEN' (U+00AD) if (nCode == 0x0160) nStyle =1; if (nCode == 0x0160) nStyle =1; // Unicode Character 'LATIN CAPITAL LETTER S WITH CARON' (U+0160) if (nCode == 0x0161) nStyle =1; //Unicode Character 'LATIN SMALL LETTER S WITH CARON' (U+0161) if (nCode == 0x2588) nCode = 0x25A0; // Unicode Character 'FULL BLOCK' (U+2588) if (nCode == 0x2022) nStyle =1; // Unicode Character 'BULLET' (U+2022) if (nCode == 0x2120) nStyle =1; // Unicode Character 'SERVICE MARK' (U+2120) if (nCode == 0x0178) nStyle =1; // LATIN CAPITAL LETTER Y WITH DIAERESIS' (U+0178) if (nCode == 0x215B) nStyle =1; // Unicode Character 'VULGAR FRACTION ONE EIGHTH' (U+215B) if (nCode == 0x215C) nStyle =1; // Unicode Character 'VULGAR FRACTION THREE EIGHTHS' (U+215C) if (nCode == 0x215D) nStyle =1; // Unicode Character 'VULGAR FRACTION FIVE EIGHTHS' (U+215D) if (nCode == 0x215E) nStyle =1; // Unicode Character 'VULGAR FRACTION SEVEN EIGHTHS' (U+215E) if (nCode == 0xE1A0) nStyle =1; // [CC] ¹®ÀÚ »ç¿ëÀÚ Á¤ÀÇ // ij½¬¿¡¼­ ÀÏÄ¡ÇÏ´Â Á¤º¸¸¦ ã´Â´Ù for (x = 0; x < nCacheCount; x++) { if (fontCache[x].nCode != nCode) continue; if (fontCache[x].nSize != nSize) continue; if (fontCache[x].nStyle != nStyle) continue; if (fontCache[x].nOffset != nOffset) continue; if (fontCache[x].bItalic != bItalic) continue; return x; } if (FT_Set_Pixel_Sizes( DST_g_FT_Face[nStyle], 0, nSize )) return DST_GetFont(0x0020, nSize, nStyle, nOffset, bItalic); FT_Matrix matrix = { 0x10000, 0x0, 0x0, 0x10000}; FT_Vector pen = {0, 0}; matrix.xy = bItalic ? 0x34fd : 0; // ÀÌÅŸ¯ ¼³Á¤ if (nOffset != 0) // ÷ÀÚ Ã³¸® { matrix.xx = (matrix.xx * 70) / 100; // 70%»çÀÌÁî matrix.xy = (matrix.xy * 70) / 100; matrix.yx = (matrix.yx * 70) / 100; matrix.yy = (matrix.yy * 70) / 100; } if (nOffset == 2) // À§Ã·ÀÚ { pen.x = 0; pen.y = (nSize * 64 * 37) / 100; // 30% À§·Î ¿Ã¸°´Ù.(37%À϶§ º¸±â ÁÁ´Ù.) } FT_Set_Transform( DST_g_FT_Face[nStyle], &matrix, &pen ); FT_UInt glyph_index = FT_Get_Char_Index( DST_g_FT_Face[nStyle], nCode ); if (FT_Load_Glyph( DST_g_FT_Face[nStyle],glyph_index, FT_LOAD_DEFAULT )) return DST_GetFont(0x0020, nSize, nStyle, nOffset, bItalic); if (FT_Render_Glyph(DST_g_FT_Face[nStyle]->glyph, FT_RENDER_MODE_NORMAL)) return DST_GetFont(0x0020, nSize, nStyle, nOffset, bItalic); if (nCacheCount < CACHE_MAX) nCacheCount++;// ij½¬¿¡ Áý¾î³ÖÀÚ. nCachePosition++; if (nCachePosition == CACHE_MAX) nCachePosition = 0; fontCache[nCachePosition].nCode = nCode; fontCache[nCachePosition].nSize = nSize; fontCache[nCachePosition].nStyle = nStyle; fontCache[nCachePosition].bItalic = bItalic; fontCache[nCachePosition].nOffset = nOffset; fontCache[nCachePosition].x = DST_g_FT_Face[nStyle]->glyph->bitmap_left; fontCache[nCachePosition].y = DST_g_FT_Face[nStyle]->glyph->bitmap_top; fontCache[nCachePosition].w = DST_g_FT_Face[nStyle]->glyph->bitmap.width; fontCache[nCachePosition].h = DST_g_FT_Face[nStyle]->glyph->bitmap.rows; fontCache[nCachePosition].width = (DST_g_FT_Face[nStyle]->glyph->advance.x) >> 6; #if DYNAMIC_MEMORY if (fontCache[nCachePosition].buff != 0) DST_OS_Free(&fontCache[nCachePosition].buff); fontCache[nCachePosition].buff = (DS_U8 *)DST_OS_Malloc(fontCache[nCachePosition].w * fontCache[nCachePosition].h); #else // ÆùÆ®°¡ ÆùÆ® ¹öÆÛº¸´Ù Å©´Ù¸é ¾Æ·¡ÂÊÀ» Àß¶ó¼­ ¹ö¸°´Ù. if (fontCache[nCachePosition].w * fontCache[nCachePosition].h > FONT_BUFF_SIZE) { fontCache[nCachePosition].h = FONT_BUFF_SIZE / fontCache[nCachePosition].w; } #endif memcpy(fontCache[nCachePosition].buff, DST_g_FT_Face[nStyle]->glyph->bitmap.buffer, fontCache[nCachePosition].w * fontCache[nCachePosition].h); return nCachePosition; } static int DST_GetFontEdgeWidth(int nFontSize) { int nSize = nFontSize/5; if (nSize < 1) nSize = 1; return nSize; } // ÆùÆ®ÀÇ ³ôÀ̸¦ ±¸ÇÑ´Ù. static int DST_g_FontHeight[256] = {0}; static int DST_g_FontBaseLine[256] = {0}; // ¿©·¯ ÆùÆ®¸¦ ¼¯¾î ¾²±â À§Çؼ­ ÇÊ¿äÇÑ ÀÛ¾÷ static void DST_GetFontHeightSub(int nSize) { int nEdgeWidth = DST_GetFontEdgeWidth(nSize); int pos1 = DST_GetFont(0x6A, nSize, 0,0,false); // j int pos2 = DST_GetFont(0x203E, nSize, 0,0,false); // À§ÂÊ ¹Ù DST_g_FontHeight[nSize] = fontCache[pos1].h - fontCache[pos1].y + fontCache[pos2].y + nEdgeWidth + nEdgeWidth; DST_g_FontBaseLine[nSize] = fontCache[pos2].y + nEdgeWidth+nEdgeWidth/3; // ³ª´®ÆùÆ®´Â nEdgeWidth/3 ¸¸Å­ ³»¸°´Ù. } // ÆùÆ®ÀÇ ³ôÀ̸¦ ¹ÝȯÇÑ´Ù. int DST_GetFontHeight(int nSize) { if (DST_g_FontHeight[nSize] == 0) DST_GetFontHeightSub(nSize); return DST_g_FontHeight[nSize]; } // ÆùÆ®ÀÇ º£À̽º¶óÀαîÁöÀÇ °Å¸®¸¦ ¹ÝȯÇÑ´Ù. static int DST_GetFontBaseLine(int nSize) { if (DST_g_FontBaseLine[nSize] == 0) DST_GetFontHeightSub(nSize); return DST_g_FontBaseLine[nSize]; } // ÀÔ·ÂµÈ ¹®ÀÚÁß °¡Àå Å« ÆùÆ® »çÀÌÁ ÃßÃâÇÑ´Ù. static int DST_GetMaxFontSize(FONT_CC data[], int nCount) { int i = 0; if (nCount == 0) return 0; int nMax = data[0].nSize; for (i = 0; i < nCount; i++) { if (nMax < data[i].nSize) nMax = data[i].nSize; } return nMax; } int DST_GetFontHeightCC(FONT_CC data[], int nCount) { if (nCount == 0) return 0; return DST_GetFontHeight(DST_GetMaxFontSize(data, nCount)); } // ÆùÆ®ÀÇ ³ÐÀ̸¦ ±¸ÇÑ´Ù. int DST_GetFontWidthCC(FONT_CC data[], int nCount) { int i = 0; if (nCount == 0) return 0; int nTotalWidth = 0; int nMaxWidth = 0; for (i = 0; i < nCount; i++) { // int nPos = DST_GetFontArib(data[i].nCode, data[i].nSize, data[i].nStyle, data[i].nOffset, data[i].bItalic); int nPos = DST_GetFont(data[i].nCode, data[i].nSize, data[i].nStyle,data[i].nOffset,data[i].bItalic); if (i==0) // ù¹øÂ° ±ÛÀÚÀÇ ¿ÞÂÊ »ßÁ®³²¿È Á¤µµ + Edge + margin { if (fontCache[nPos].x < 0) nTotalWidth -= fontCache[nPos].x; nTotalWidth += (DST_GetFontEdgeWidth(data[i].nSize) * 2); } nTotalWidth = nTotalWidth + fontCache[nPos].width; // µ¥ÀÌÅÍÀÇ widthº¸´Ù ±×·ÁÁ®¾ßÇÏ´Â ÆùÆ®°¡ ¿À¸¥ÂÊÀ¸·Î ´õ »ßÁ®³ª¿Â´Ù¸é // À̰ÍÀ» ¸Æ½º·Î ÇØ¾ßÇÑ´Ù. [hand.] µîÀÇ ¹®ÀÚ´Â // Çʱâü ÀÌÅŸ¯ÀÎ °æ¿ì dÀÇ ¿À¸¥ÂÊ ³¡ÀÌ '.' º¸´Ù ¹Û¿¡ ÀÖ´Â °æ¿ì¸¦ °í·ÁÇØ¾ß ÇÑ´Ù. int nDelta = fontCache[nPos].x + fontCache[nPos].w - fontCache[nPos].width; if (nDelta < 0) nDelta = 0; if (nTotalWidth + nDelta > nMaxWidth) nMaxWidth = nTotalWidth + nDelta; // ¸¶Áö¸· ±ÛÀÚÀÇ ¿§Áö Å©±â¸¸Å­ ¸¶Áø Àû¿ë if (i == nCount -1) nMaxWidth += (DST_GetFontEdgeWidth(data[i].nSize) * 2); } return nMaxWidth; } static 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) { if (des == 0 || w < 1 || h < 1 || des_w < 1 || des_h < 1) return; if (x < 0) x = 0; if (y < 0) y = 0; if (x + w > des_w) w = des_w - x; if (y + h > des_h) h = des_h - y; des += (des_w*y+x); int delta = des_w - w; while (h--) { int ww = w; while (ww--) *des++ = color; des += delta; } } OSD_PIXEL_T DST_SetColor(OSD_PIXEL_T a, OSD_PIXEL_T r, OSD_PIXEL_T g, OSD_PIXEL_T b) { if (sizeof(OSD_PIXEL_T) == 2) // 16ºñÆ®ÀÎ °æ¿ì { OSD_PIXEL_T max = 0x0F; if (a > max) a = max; if (r > max) r = max; if (g > max) g = max; if (b > max) b = max; return (a<<12) | (r<<8) | (g<<4) | b; } // 32ºñÆ®ÀÎ °æ¿ì OSD_PIXEL_T max = 0xFF; if (a > max) a = max; if (r > max) r = max; if (g > max) g = max; if (b > max) b = max; return (a<<24) | (r<<16) | (g<<8) | b; } void DST_GetColor(OSD_PIXEL_T color, OSD_PIXEL_T *a, OSD_PIXEL_T *r, OSD_PIXEL_T *g, OSD_PIXEL_T *b) { if (sizeof(OSD_PIXEL_T) == 1) // 8ºñÆ®ÀÎ °æ¿ì { return; } if (sizeof(OSD_PIXEL_T) == 2) // 16ºñÆ®ÀÎ °æ¿ì { OSD_PIXEL_T mask = 0x0F; *a = (color >> 12) & mask; *r = (color >> 8) & mask; *g = (color >> 4) & mask; *b = color & mask; return; } // 32ºñÆ®ÀÎ °æ¿ì OSD_PIXEL_T mask = 0xFF; *a = (color >> 24) & mask; *r = (color >> 16) & mask; *g = (color >> 8) & mask; *b = color & mask; } static OSD_PIXEL_T DST_ColorCalcuration(OSD_PIXEL_T foreColor, DS_U8 nWeight, OSD_PIXEL_T backColor) { if (nWeight == 0xFF) return foreColor; if (nWeight == 0) return backColor; if (sizeof(OSD_PIXEL_T) == 1) // 8ºñÆ®ÀÎ °æ¿ì { if (foreColor == 0) return backColor; if (backColor == 0) return foreColor; return (nWeight > 128) ? foreColor : backColor; } if (sizeof(OSD_PIXEL_T) == 2) // 16ºñÆ®ÀÎ °æ¿ì { if (foreColor == 0) { // Àü°æ»öÀÌ Åõ¸íÀÎ °æ¿ì if (backColor == 0) return 0; OSD_PIXEL_T a,r,g,b; DST_GetColor(backColor, &a, &r, &g, &b); a = nWeight * a / 255; return DST_SetColor(a, r, g, b); } if (backColor == 0) { OSD_PIXEL_T a,r,g,b; DST_GetColor(foreColor, &a, &r, &g, &b); a = nWeight/16; return DST_SetColor(a, r, g, b); } if (foreColor == 0xFFFF && backColor == 0xF000) // °ËÀº¹ÙÅÁ¿¡ Èò±Û¾¾ { OSD_PIXEL_T nWeight4 = nWeight / 16; return DST_SetColor(0xF, nWeight4, nWeight4, nWeight4); } OSD_PIXEL_T fa,fr,fg,fb; DST_GetColor(foreColor, &fa, &fr, &fg, &fb); OSD_PIXEL_T ba,br,bg,bb; DST_GetColor(backColor, &ba, &br, &bg, &bb); OSD_PIXEL_T max = 0xFF; //OSD_PIXEL_T a = ba + (fa*(max-(ba*nWeight)/max))/max; OSD_PIXEL_T a = ((nWeight*fa) + (max-nWeight)*ba)/max; OSD_PIXEL_T r = ((nWeight*fr) + (max-nWeight)*br)/max; OSD_PIXEL_T g = ((nWeight*fg) + (max-nWeight)*bg)/max; OSD_PIXEL_T b = ((nWeight*fb) + (max-nWeight)*bb)/max; return DST_SetColor(a,r,g,b); } // 32ºñÆ®ÀÎ °æ¿ì if (foreColor == 0) { // Àü°æ»öÀÌ Åõ¸íÀÎ °æ¿ì if (backColor == 0) return 0; OSD_PIXEL_T a,r,g,b; DST_GetColor(backColor, &a, &r, &g, &b); a = nWeight * a / 255; return DST_SetColor(a, r, g, b); } if (backColor == 0) { OSD_PIXEL_T a,r,g,b; DST_GetColor(foreColor, &a, &r, &g, &b); a = nWeight; return DST_SetColor(a, r, g, b); } if (foreColor == CONV32_16(0xFFFFFFFF) && backColor == CONV32_16(0xFF000000)) // °ËÀº¹ÙÅÁ¿¡ Èò±Û¾¾ { return DST_SetColor(0xFF, nWeight, nWeight, nWeight); } OSD_PIXEL_T fa,fr,fg,fb; DST_GetColor(foreColor, &fa, &fr, &fg, &fb); OSD_PIXEL_T ba,br,bg,bb; DST_GetColor(backColor, &ba, &br, &bg, &bb); OSD_PIXEL_T max = 0xFF; //OSD_PIXEL_T a = ba + (fa*(max-(ba*nWeight)/max))/max; OSD_PIXEL_T a = ((nWeight*fa) + (max-nWeight)*ba)/max; OSD_PIXEL_T r = ((nWeight*fr) + (max-nWeight)*br)/max; OSD_PIXEL_T g = ((nWeight*fg) + (max-nWeight)*bg)/max; OSD_PIXEL_T b = ((nWeight*fb) + (max-nWeight)*bb)/max; return DST_SetColor(a,r,g,b); } //°¡ÁßÄ¡ °ª°ú »öÀ» ÀúÁ¤Çϱâ À§ÇÑ ¹öÆÛ °è»êÀ» À§ÇÑ ÇÔ¼ö // Edge µîÀÇ ¿¬»ê¿¡¼­´Â °¡ÁßÄ¡ °ªÀ» ´õÇϱ⠿¬»êÇÏ¿©¾ß ÇÑ´Ù. // ±ÛÀÚ¸¦ ±×¸®´Â ¼ø¼­´Â ´ÙÀ½°ú °°´Ù. // ¹è°æ ±×¸®±â // ¿¡Áö¹öÆÛ ±¸Çϱâ (°¡ÁßÄ¡+»ö) // ±ÛÀÚ¹öÆÛ ±¸Çϱâ (°¡ÁßÄ¡+»ö) // ¹è°æ¿¡ ¿¡Áö¹öÆÛ ´õÇϱâ // ¹è°æ¿¡ ¿¡Áö¹öÆÛ ´õÇÑ ¹öÆÛ¿¡ ±ÛÀÚ¹öÆÛ ´õÇϱâ static void DST_PrintBuff(int des_w, int des_h, DS_U8* desWeight, OSD_PIXEL_T* desColor, int src_w, int src_h, DS_U8* src, int x_pos, int y_pos, OSD_PIXEL_T color) { if (des_w < 1 || des_h < 1) { return; } if (src_w < 1 || src_h < 1) { return; } if (src_w > des_w) { return; } if (src_h > des_h) { return; } if (x_pos < 0) { x_pos = 0; } if (y_pos < 0) { y_pos = 0; } if (x_pos + src_w > des_w) { x_pos = des_w - src_w; } if (y_pos + src_h > des_h) { y_pos = des_h - src_h; } int x = 0, y = 0; DS_U8 *src1 = src; for (y = 0; y < src_h; y++) { DS_U8 *desWeight1 = desWeight + des_w * (y_pos+y) + x_pos; OSD_PIXEL_T *desColor1 = desColor + des_w * (y_pos+y) + x_pos; for (x = 0; x < src_w; x++) { if (*desWeight1) { *desWeight1 = (*desWeight1 > *src1) ? *desWeight1 : *src1; } else { *desWeight1 = *src1; } if (*src1 > 0) *desColor1 = color; src1++; desWeight1++; desColor1++; } } } typedef struct { FONT_CC data[64]; int nCount; OSD_PIXEL_T buff[720*48]; } FontImageCache; #define MAX_FONT_IMAGE_CACHE 10 static FontImageCache fontimagecache[MAX_FONT_IMAGE_CACHE]; static int g_FontImageCacheWritePosition = 0; static bool DST_GetFontImageCache(FONT_CC data[], int nCount, OSD_PIXEL_T *buff, int width, int height) { int i; for ( i = 0; i < MAX_FONT_IMAGE_CACHE; i++) { if (nCount != fontimagecache[i].nCount) continue; if (memcmp(data, fontimagecache[i].data, nCount * sizeof(FONT_CC)) != 0) continue; memcpy(buff, fontimagecache[i].buff, width * height * sizeof(OSD_PIXEL_T)); return true; } return false; } static void DST_SetFontImageCache(FONT_CC data[], int nCount, OSD_PIXEL_T *buff, int width, int height) { // if (fontimagecache[g_FontImageCacheWritePosition].data) DST_OS_Free(&fontimagecache[g_FontImageCacheWritePosition].data); // if (fontimagecache[g_FontImageCacheWritePosition].buff) DST_OS_Free(&fontimagecache[g_FontImageCacheWritePosition].buff); // fontimagecache[g_FontImageCacheWritePosition].data = (FONT_CC *)DST_OS_Malloc(nCount * sizeof(FONT_CC)); memcpy(fontimagecache[g_FontImageCacheWritePosition].data, data, nCount * sizeof(FONT_CC)); fontimagecache[g_FontImageCacheWritePosition].nCount = nCount; // fontimagecache[g_FontImageCacheWritePosition].buff = (OSD_PIXEL_T *)DST_OS_Malloc(width * height * sizeof(OSD_PIXEL_T)); memcpy(fontimagecache[g_FontImageCacheWritePosition].buff, buff, width * height * sizeof(OSD_PIXEL_T)); g_FontImageCacheWritePosition++; if (g_FontImageCacheWritePosition >= MAX_FONT_IMAGE_CACHE) g_FontImageCacheWritePosition = 0; } // ÆùÆ®ÀÇ À̹ÌÁö¸¦ ±¸ÇÑ´Ù. void DST_GetFontImageCC(FONT_CC data[], int nCount, OSD_PIXEL_T *buff) { int x = 0, y = 0, i = 0, j = 0, x_pos = 0; if (nCount == 0) return; int width = DST_GetFontWidthCC(data, nCount); int height = DST_GetFontHeightCC(data, nCount); if (width < 1 || height < 1) return; if (DST_GetFontImageCache(data, nCount, buff, width, height) == true) return; // mallocÀ» ¸¹ÀÌ ÇÏ´Â ¹æ½ÄÀº ºÒ¾ÈÁ¤ÇϹǷΠ// ÀÌÀü Å©±âº¸´Ù Ä¿Áø °æ¿ì¿¡¸¸ mallocÀ» Çϵµ·Ï ÇÑ´Ù. static int nBuffSize = 0; static DS_U8 *buff_char = 0; // °¡ÁßÄ¡ °ª ¹öÆÛ static DS_U8 *buff_edge = 0; static OSD_PIXEL_T *buff_char_color = 0; // »ö ¹öÆÛ static OSD_PIXEL_T *buff_edge_color = 0; if (width * height > nBuffSize) { nBuffSize = width * height; DST_OS_Free(&buff_char); DST_OS_Free(&buff_edge); DST_OS_Free(&buff_char_color); DST_OS_Free(&buff_edge_color); buff_char = (DS_U8*)DST_OS_Malloc(nBuffSize); buff_edge = (DS_U8*)DST_OS_Malloc(nBuffSize); buff_char_color = (OSD_PIXEL_T*)DST_OS_Malloc(sizeof(OSD_PIXEL_T) * nBuffSize); buff_edge_color = (OSD_PIXEL_T*)DST_OS_Malloc(sizeof(OSD_PIXEL_T) * nBuffSize); } memset(buff_char, 0, nBuffSize); memset(buff_edge, 0, nBuffSize); memset(buff_char_color, 0, nBuffSize*sizeof(OSD_PIXEL_T)); memset(buff_edge_color, 0, nBuffSize*sizeof(OSD_PIXEL_T)); // ±âÁؼ±ÀÇ À§Ä¡¸¦ Àâ´Â´Ù. int nMaxBaseLine = DST_GetFontBaseLine(DST_GetMaxFontSize(data, nCount)); for (i = 0; i < nCount; i++) { //int nPos = DST_GetFontArib(data[i].nCode, data[i].nSize, data[i].nStyle,data[i].nOffset,data[i].bItalic); int nPos = DST_GetFont(data[i].nCode, data[i].nSize, data[i].nStyle,data[i].nOffset,data[i].bItalic); int nEdgeWidth = DST_GetFontEdgeWidth(data[i].nSize); if (i==0) { // ù¹øÂ° ±ÛÀÚÀÇ ¿ÞÂÊ »ßÁ®³²¿È Á¤µµ + Edge + margin if (fontCache[nPos].x < 0) x_pos -= fontCache[nPos].x; x_pos += (nEdgeWidth*2); DST_DrawBox(width, height, buff, 0, 0, x_pos + fontCache[nPos].width, height, data[i].BackColor); } // else // ±ÛÀÚ°¡ 1°³ÀÎ °æ¿ì µÞºÎºÐ¿¡ ¾²·¹±â °ªÀÌ ³²´Â ¹®Á¦·Î Á¦°Å { if (i== nCount -1) { DST_DrawBox(width, height, buff, x_pos, 0, width - x_pos, height, data[i].BackColor); } else { DST_DrawBox(width, height, buff, x_pos, 0, fontCache[nPos].width, height, data[i].BackColor); } } int nBaseX = x_pos + fontCache[nPos].x; int nBaseY = nMaxBaseLine - fontCache[nPos].y; if (nBaseX + fontCache[nPos].w > width) { nBaseX = width - fontCache[nPos].w; } if (nBaseY + fontCache[nPos].h > height) { nBaseY = height - fontCache[nPos].h; if (nBaseY < 0) { fontCache[nPos].h = height; nBaseY = 0; } } // ÆùÆ® ±×¸®±â DST_PrintBuff(width, height, buff_char, buff_char_color, fontCache[nPos].w, fontCache[nPos].h, fontCache[nPos].buff, nBaseX, nBaseY, data[i].Color); // UnderLine Drawing if (data[i].bUnderLine) { int nUnderLineHeight = (nEdgeWidth * 70) / 100; if (nUnderLineHeight < 1) nUnderLineHeight =1; for (y = 0; y < nUnderLineHeight; y++) { for (x = 0; x < fontCache[nPos].width; x++) { buff_edge[x_pos + width * (nMaxBaseLine + y+1)+x] = 200; buff_edge_color[x_pos + width * (nMaxBaseLine + y+1)+x] = data[i].Color; } } } // Edge ±×¸®±â switch (data[i].nEdgeType) { case 1: for (j = 1; j <= nEdgeWidth; j++) { DST_PrintBuff(width, height,buff_edge, buff_edge_color, fontCache[nPos].w, fontCache[nPos].h, fontCache[nPos].buff, nBaseX - j, nBaseY - j, data[i].EdgeColor); } break; case 2: for (j = 1; j <= nEdgeWidth; j++) { DST_PrintBuff(width, height, buff_edge, buff_edge_color, fontCache[nPos].w, fontCache[nPos].h, fontCache[nPos].buff, nBaseX + j, nBaseY + j , data[i].EdgeColor); } break; case 3: for (y = nEdgeWidth * -1; y <= nEdgeWidth; y++) { for (x = nEdgeWidth * -1 ; x <= nEdgeWidth; x++) { DST_PrintBuff(width, height, buff_edge, buff_edge_color, fontCache[nPos].w, fontCache[nPos].h, fontCache[nPos].buff, nBaseX + x, nBaseY + y , data[i].EdgeColor); } } break; case 4: DST_PrintBuff(width, height, buff_edge, buff_edge_color, fontCache[nPos].w, fontCache[nPos].h, fontCache[nPos].buff, nBaseX - nEdgeWidth, nBaseY + nEdgeWidth, data[i].EdgeColor); break; case 5: DST_PrintBuff(width, height, buff_edge, buff_edge_color, fontCache[nPos].w, fontCache[nPos].h, fontCache[nPos].buff, nBaseX + nEdgeWidth, nBaseY + nEdgeWidth , data[i].EdgeColor); break; } x_pos += fontCache[nPos].width; } // Edge ¹öÆÛ¿Í char ¹öÆÛ¸¦ º¹»çÇÑ´Ù. for (i=0; i < nBuffSize; i++) { // Edge ¹öÆÛ Àû¿ë if (buff_edge[i] > 0) { buff[i] = DST_ColorCalcuration(buff_edge_color[i], buff_edge[i], buff[i]); } // Char ¹öÆÛ Àû¿ë if (buff_char[i] > 0) { DS_U16 emphasis = (buff_char[i] * 150) / 100; if (emphasis > 255) emphasis = 255; buff[i] = DST_ColorCalcuration(buff_char_color[i], emphasis, buff[i]); } } DST_SetFontImageCache(data, nCount, buff, width, height); } // OSD¿ë ÆùÆ®¿£Áø // ÅØ½ºÆ®ÀÇ ³ôÀ̸¦ ±¸ÇÑ´Ù. int DST_GetTextHeight(DS_U8 nSize) { return DST_GetFontHeight(nSize); } // ÁöÁ¤ÇÑ ¹öÆÛ¿¡ ÆùÆ®¸¦ Ãâ·ÂÇÑ´Ù. bool DST_PrintText( OSD_PIXEL_T *buffDes, int buffer_width, int buffer_height, int x_pos, int y_pos, DS_U32* strText, int nStrLen, DS_U8 nSize, OSD_PIXEL_T Color) { if (nStrLen < 1) return false; int width = DST_GetTextWidth32(strText, nStrLen, nSize); int height = DST_GetTextHeight(nSize); if (width < 1 || height < 1) return false; // 8ºñÆ® Gray ¹öÆÛ static int nBuffSize = 0; static DS_U8 *buff = 0; if (width * height > nBuffSize) // ÀÔ·ÂµÈ ÃÖ´ë »çÀÌÁî·Î ¸Þ¸ð¸® ¹öÆÛ¸¦ °»½ÅÇØ¼­ ¸¸µç´Ù. { nBuffSize = width * height; DST_OS_Free(&buff); buff = (DS_U8 *)DST_OS_Malloc(nBuffSize); } memset(buff, 0, width * height); int nMaxBaseLine = DST_GetFontBaseLine(nSize); // ±âÁؼ±ÀÇ À§Ä¡¸¦ Àâ´Â´Ù. int nEdgeWidth = DST_GetFontEdgeWidth(nSize); int x_posi = 0; int i; for ( i = 0; i < nStrLen; i++) { int nPos = DST_GetFont(strText[i], nSize, 0, 0, false); if (i==0) { // ù¹øÂ° ±ÛÀÚÀÇ ¿ÞÂÊ »ßÁ®³²¿È Á¤µµ + Edge + margin if (fontCache[nPos].x < 0) x_posi -= fontCache[nPos].x; x_posi += (nEdgeWidth*2); } int nBaseX = x_posi + fontCache[nPos].x; int nBaseY = nMaxBaseLine - fontCache[nPos].y; DS_U8 *src1 = fontCache[nPos].buff; int y; for ( y = 0; y < fontCache[nPos].h; y++) { DS_U8 *des1 = buff + width * (nBaseY+y) + nBaseX; int x; for ( x = 0; x < fontCache[nPos].w; x++) { if (*src1) *des1 = *src1; src1++; des1++; } } x_posi += fontCache[nPos].width; } DS_U8 *p = buff; int y; for ( y=0; y < height; y++) { OSD_PIXEL_T *des1 = buffDes + (y_pos+y)*buffer_width + x_pos; int x; for ( x=0; x < width; x++) { if (*p) *des1 = DST_ColorCalcuration(Color, *p, *des1); p++; des1++; } } return true; } // À¯´ÏÄÚµå ÅØ½ºÆ® ÆøÀ» ±¸ÇÑ´Ù. int DST_GetTextWidth32(DS_U32* strText, DS_U16 nStrLen, DS_U8 nSize) { if (strText == 0) return 0; int nTotalWidth = 0; int nMaxWidth = 0; if (nStrLen < 1) return 0; if (nStrLen > 4096) nStrLen = 4096; int i; for ( i = 0; i < nStrLen; i++) { if (strText[i] != 0) continue; nStrLen = i; break; } for (i = 0; i < nStrLen; i++) { int nPos = DST_GetFont(strText[i], nSize, 0, 0, false); if (i==0) // ù¹øÂ° ±ÛÀÚÀÇ ¿ÞÂÊ »ßÁ®³²¿È Á¤µµ + Edge + margin { if (fontCache[nPos].x < 0) nTotalWidth -= fontCache[nPos].x; nTotalWidth += (DST_GetFontEdgeWidth(nSize) * 2); } nTotalWidth = nTotalWidth + fontCache[nPos].width; // µ¥ÀÌÅÍÀÇ widthº¸´Ù ±×·ÁÁ®¾ßÇÏ´Â ÆùÆ®°¡ ¿À¸¥ÂÊÀ¸·Î ´õ »ßÁ®³ª¿Â´Ù¸é // À̰ÍÀ» ¸Æ½º·Î ÇØ¾ßÇÑ´Ù. [hand.] µîÀÇ ¹®ÀÚ´Â // Çʱâü ÀÌÅŸ¯ÀÎ °æ¿ì dÀÇ ¿À¸¥ÂÊ ³¡ÀÌ '.' º¸´Ù ¹Û¿¡ ÀÖ´Â °æ¿ì¸¦ °í·ÁÇØ¾ß ÇÑ´Ù. int nDelta = fontCache[nPos].x + fontCache[nPos].w - fontCache[nPos].width; if (nDelta < 0) nDelta = 0; if (nTotalWidth + nDelta > nMaxWidth) nMaxWidth = nTotalWidth + nDelta; // ¸¶Áö¸· ±ÛÀÚÀÇ ¿§Áö Å©±â¸¸Å­ ¸¶Áø Àû¿ë if (i == nStrLen -1) nMaxWidth += (DST_GetFontEdgeWidth(nSize) * 2); } return nMaxWidth; } int DST_GetTextWidthUniwithLen(DS_U16* strText, DS_U16 nStrLen, DS_U8 nSize) { if (nStrLen == 0) return 0; // ¹®ÀÚ¿­ÀÇ ±æÀ̰¡ 0À̸é 0ÀÌ´Ù. if (nStrLen >= 4096) return 0; static DS_U32 strText32[4096]; memset(strText32 ,0, 4096 * sizeof(DS_U32)); int i; for ( i = 0; i < nStrLen; i++) strText32[i] = (DS_U32)strText[i]; int ret = DST_GetTextWidth32(strText32, nStrLen, nSize); //DST_OS_Free(&strText32); return ret; } int DST_GetTextWidthUni(DS_U16* strText, DS_U8 nSize) { int i; for ( i = 0; i < 4096; i++) { if (strText[i] == 0) return DST_GetTextWidthUniwithLen(strText, i, nSize); } return 0; } // À¯´ÏÄÚµå ¹®ÀÚ¿­ Áß ÁöÁ¤ÇÑ ºÎºÐÀÇ ÅØ½ºÆ® ÆøÀ» ±¸ÇÑ´Ù. int DST_GetTextWidthExtUni(int start, int width, DS_U16* strText, DS_U16 nStrLen, DS_U8 nSize) { return DST_GetTextWidthUniwithLen(strText + start, width, nSize); } // ±×·ÁÁú ÅØ½ºÆ®ÀÇ ÆøÀ» ±¸ÇÑ´Ù. ÇÑ±Û ¸Þ´º¿¡¼­µµ È£ÃâÇÒ¼ö ÀÖ´Ù. int DST_GetTextWidth(char* strText, DS_U8 nSize) { DS_U16 nStrLen = strlen(strText); if (nStrLen == 0) return 0; // ¹®ÀÚ¿­ÀÇ ±æÀ̰¡ 0À̸é 0ÀÌ´Ù. if (nStrLen >= 4096) return 0; // ¹®ÀÚ¿­ÀÇ ±æÀ̰¡ 0À̸é 0ÀÌ´Ù. static DS_U16 strText16[4096]; memset(strText16, 0, 4096*sizeof(DS_U16)); int i; for ( i = 0; i < nStrLen; i++) strText16[i] = (DS_U16)(DS_U8)strText[i]; int ret = DST_GetTextWidthUniwithLen(strText16, nStrLen, nSize); return ret; } DS_U32* DST_UTF82Uni(DS_U8 *utf) { if (utf == 0) return 0; int nLen = strlen((char*)utf); if (nLen == 0) return 0; //printf("nLen=%d\n", nLen); static DS_U32 buff[4096]; memset(buff, 0, 4096*sizeof(DS_U32)); int nPos = 0; int i; for ( i = 0; i < nLen; i++) { if (utf[i] >= 0xF0) { // 11110zzz 10zzxxxx 10xxxxxx 10xxxxxx buff[nPos] = ((utf[i] & 0x07) << 18) + ((utf[i+1] & 0x3F) << 16) + ((utf[i+2] & 0x3F) << 8) + (utf[i+3] & 0x3F); nPos++; i+=3; continue; } if (utf[i] >= 0xE0) { // 1110xxxx 10xxxxxx 10xxxxxx buff[nPos] = ((utf[i] & 0x0F) << 12) + ((utf[i+1] & 0x3F) << 6) + (utf[i+2] & 0x3F); nPos++; i+=2; continue; } if (utf[i] >= 0xC0) { // 110xxxxx 10xxxxxx buff[nPos] = ((utf[i] & 0x1F) << 6) + (utf[i+1] & 0x3F); nPos++; i++; continue; } if (utf[i] < 0x80) { // 0xxxxxxx buff[nPos] = utf[i]; nPos++; continue; } } return buff; }