#include "header.h" #include "font.h" //* == -- - - - - -= Create Font = - - - - -- - == */ bool CFfont::MakeFont() { if (!isAll || (!isFont && !isGlow)) { timeg = 0; return true; } int sTy = Ty, a; if (bRect) { Ux = rect_sx; Uy = rect_sy; timeg = 0; Ty = MinTex; while( rect_sx > Ty || rect_sy > Ty ) Ty *= 2; Sy = sx = Ty; /*chk*/ if (Ty > MaxTex ) { format(s,S, "%d", Ty ); WrnMsg( s, "Texture size too big" ); } } else // ! bRect { // clear -- //size_t size = MaxTex * MaxTex; //memset(tFont, 0, size); //memset(tGlow, 0, size); //memset(tAlpha, 0, size); /*crt fnt*/ DeleteObject( hf ); hf = 0; DWORD qla[5] = {NONANTIALIASED_QUALITY, ANTIALIASED_QUALITY, PROOF_QUALITY, CLEARTYPE_QUALITY, CLEARTYPE_NATURAL_QUALITY}; hf = CreateFontA( sy, 0, 0, 0, (fbold == 0) ? FW_NORMAL : FW_BOLD, 0, 0, 0, DEFAULT_CHARSET, //EASTEUROPE_CHARSET, ANSI_CHARSET OUT_TT_PRECIS, CLIP_TT_ALWAYS, qla[ql], DEFAULT_PITCH, fontName ); if (hf == 0 ) WrnMsg( "create font fail", "MakeFont" ); int i, j, k, yy; Sy = max( 1, sy + ay + by ); if (Sy > MaxSY ) WrnMsg( "Texture size too big.", "MakeFont" ); /*Codes:*/ ForEachChar if (h[n].ch) h[n].s = h[n].ch; else h[n].s = n + z1; /*[Width]*/ static ABCFLOAT A[256]; SelectObject( dc, hf ); GetCharABCWidthsFloat( dc, 0, 255, A ); ssn = 0; ss = 0; ForEachChar { h[n].h[0] = i = A[h[n].s].abcfA; h[n].h[1] = j = A[h[n].s].abcfB; h[n].h[2] = k = A[h[n].s].abcfC; if (i < 0 ) i = - i; if (k < 0 ) k = - k; w = j + max( k, ax + bx ); h[n].wi = w + h[n].ss; if (w > ss ) { ssn = n; ss = w; } } /*fixed width > */ if (fix ) { int s0 = 0; ForEachChar if (h[n].wi > s0 ) s0 = h[n].wi; //max width ForEachChar { h[n].of = ( s0 - h[n].wi ) / 2; h[n].ps = 1; h[n].wi = s0 + ax + bx; } ss = s0; } /*variable width > */ else ForEachChar { h[n].of = 0; h[n].ps = h[n].pp; /*enter*/ if (h[n].ch == 13 ) h[n].wi = - bx; } // width (smooth) groups if (!fix ) { ZeroMem( grw ); int g; ForEachChar { g = h[n].gr; if (g > 0 && g <= MaxGroups ) if (h[n].wi > grw[g] ) grw[g] = h[n].wi + grwi[g]; } //mx wi gr /*of*/ for (g = 1; g <= MaxGroups; g++) if (grw[g] > 0 ) ForEachChar if (h[n].gr == g ) { h[n].of = ( grw[g] - h[n].wi ) / 2; h[n].ps = 1; h[n].wi = grw[g]; } }
HTEXTURE HGERenderFont::_fontGenerate( const Menge::String& _name, int _size, bool _bold, bool _italic, bool _antialias, int _leftRange, int _rigthRange ) { //char sPath[MAX_PATH]; //OLECHAR sUniPath[MAX_PATH + 1]; //MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, _name.c_str(), -1, sUniPath, // MAX_PATH); HFONT hFont = CreateFont(-_size, 0, 0, 0, (_bold) ? FW_BOLD : FW_NORMAL, _italic, 0, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, (_antialias) ? ANTIALIASED_QUALITY : NONANTIALIASED_QUALITY, DEFAULT_PITCH | FF_DONTCARE, Menge::Utils::AToW( _name ).c_str()); if(!hFont) { return 0; } HDC hBMDC = CreateCompatibleDC(0); SetTextColor(hBMDC, RGB(255,255,255)); SetBkColor(hBMDC, RGB(0,0,0)); SetBkMode(hBMDC, TRANSPARENT); SetMapMode(hBMDC, MM_TEXT); SetTextAlign(hBMDC, TA_TOP); SelectObject(hBMDC, hFont); TEXTMETRIC tTextMetrics; GetTextMetrics(hBMDC, &tTextMetrics); ABCFLOAT abc; for (int j = _leftRange; j <= _rigthRange; j++ ) { GetCharABCWidthsFloat(hBMDC, j, j, &abc); m_letters[j].a = abc.abcfA - 1; m_letters[j].c = abc.abcfC - 1; m_letters[j].w = abc.abcfB + 2; m_letters[j].h = tTextMetrics.tmHeight; if(m_letters[j].h > m_height) { m_height = m_letters[j].h; } } int nWidth = 32; int nHeight = 32; for(;;) { if(_placeSymbols(nWidth, nHeight, _leftRange, _rigthRange)) { break; } if(nWidth<=nHeight) { nWidth<<=1; } else { nHeight<<=1; } if(nWidth > 1024 || nHeight > 1024) { DeleteObject(hFont); DeleteDC(hBMDC); return 0; } } BITMAPINFO bmi; memset(&bmi, 0, sizeof(BITMAPINFO)); bmi.bmiHeader.biWidth = nWidth; bmi.bmiHeader.biHeight = -nHeight; bmi.bmiHeader.biBitCount = 32; bmi.bmiHeader.biCompression = BI_RGB; bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); DWORD * pPixels = 0; HBITMAP hBM = CreateDIBSection(hBMDC, &bmi, DIB_RGB_COLORS, (void**)&pPixels, 0, 0); if(!hBM) { DeleteObject(hFont); DeleteDC(hBMDC); return 0; } SelectObject(hBMDC, hBM); const size_t newsize = 100; size_t origsize = 1; size_t convertedChars = 0; wchar_t wcstring[newsize]; for (int j = _leftRange; j <= _rigthRange; j++ ) { char c = (char)j; mbstowcs( wcstring, &c, newsize); // wcscat_s(wcstring, L" (wchar_t *)"); TextOutW(hBMDC, m_letters[j].x-m_letters[j].a, m_letters[j].y, wcstring, 1); } GdiFlush(); HTEXTURE texture = m_hge->Texture_Create(nWidth, nHeight,Menge::PF_A8R8G8B8); int pitch = 0; DWORD * pTexData = m_hge->Texture_Lock(texture, &pitch); for (int i = 0; i<nHeight; i++) { for (int j = 0; j<nWidth; j++) { DWORD dwPixel = pPixels[i*nWidth+j]; dwPixel = 0xFFFFFF | ((dwPixel & 0xFF) << 24); pTexData[i*nWidth+j] = dwPixel; } } m_hge->Texture_Unlock(texture); float width = m_hge->Texture_GetWidth(texture); float height = m_hge->Texture_GetHeight(texture); for (int j = _leftRange; j <= _rigthRange; j++ ) { m_letters[j].u0 = m_letters[j].x / width; m_letters[j].v0 = m_letters[j].y / height; m_letters[j].u1 = (m_letters[j].x + m_letters[j].w) / width; m_letters[j].v1 = (m_letters[j].y + m_letters[j].h) / height; } DeleteObject(hBM); DeleteObject(hFont); DeleteDC(hBMDC); return texture; }