Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // MakeMwFont.cpp : Defines the entry point for the console application.
- //
- #include "stdafx.h"
- using namespace std;
- char texarray[1024][1024][4];
- char fntarray[14632];
- float * asfloat = (float*)fntarray;
- char buf[4000];
- struct FNTINFO
- {
- float left;
- float top;
- float right;
- float bottom;
- float width;
- float height;
- float kerning;
- float ascent;
- };
- FNTINFO fntinfo[256];
- const int maxW = 1024;
- const int maxH = 1024;
- int _tmain(int argc, _TCHAR* argv[])
- {
- puts("Font Name (example: Verdana) :");
- gets_s(buf);
- string fontname = buf;
- puts("Font Size (example: 16 for normal, 20 for large) :");
- gets_s(buf);
- long fontsize = atoi(buf);
- puts("Bold? (y for yes, n for no)");
- gets_s(buf);
- bool bold = ( (buf[0]=='y') || (buf[0]=='Y') );
- puts("Anti-aliased? (y for yes, n for no)");
- gets_s(buf);
- bool antialiased = ( (buf[0]=='y') || (buf[0]=='Y') );
- HDC dc = CreateCompatibleDC(GetDC(0));
- assert(dc);
- void * pixelbuffer;
- BITMAPINFO bmi;
- ZeroMemory(&bmi, sizeof(bmi));
- bmi.bmiHeader.biBitCount = 32;
- bmi.bmiHeader.biCompression = BI_RGB;
- bmi.bmiHeader.biWidth = maxW;
- bmi.bmiHeader.biHeight = -maxH;
- bmi.bmiHeader.biPlanes = 1;
- bmi.bmiHeader.biSize = sizeof(bmi);
- bmi.bmiHeader.biXPelsPerMeter = 3600;
- bmi.bmiHeader.biYPelsPerMeter = 3600;
- HBITMAP hbm = CreateDIBSection(dc, &bmi, DIB_RGB_COLORS, &pixelbuffer, NULL, 0);
- assert(hbm);
- assert(pixelbuffer);
- RGBQUAD * pixels = (RGBQUAD*)pixelbuffer;
- memset(pixelbuffer, 0xFF, maxW*maxH*4); // make background white
- HBITMAP origbm = (HBITMAP)SelectObject(dc, hbm);
- HFONT hfont = CreateFont(fontsize, 0, 0, 0,
- bold?FW_BOLD:FW_NORMAL, FALSE, FALSE, FALSE,
- ANSI_CHARSET, OUT_RASTER_PRECIS, CLIP_DEFAULT_PRECIS,
- antialiased?ANTIALIASED_QUALITY:NONANTIALIASED_QUALITY,
- DEFAULT_PITCH|FF_DONTCARE, fontname.c_str());
- assert(hfont);
- HFONT origfont = (HFONT)SelectObject(dc, hfont);
- ABCFLOAT charwidths[256];
- BOOL success = GetCharABCWidthsFloat(dc, 0, 255, charwidths);
- assert(success);
- for (int c=0; c<256; ++c)
- {
- // swap out space for unprintable chars
- if (!isprint(c))
- {
- charwidths[c] = charwidths[' '];
- }
- }
- TEXTMETRIC textinfo;
- success = GetTextMetrics(dc, &textinfo);
- assert(success);
- // Patch up the font name so it's a good filename
- for (int i=0; i<fontname.size(); ++i)
- {
- if (isspace(fontname[i]))
- {
- fontname[i] = '_';
- }
- }
- // First, the .tex file.
- long texSize;
- long testW = 0;
- long accum = 0;
- for (int c=0; c<256; ++c)
- {
- if (c%0x0F == 0)
- {
- accum = 0;
- }
- if (isprint(c))
- {
- // we want an extra column of pixels on left and right
- // to keep the texturing engine from accidentally picking
- // up adjacent characters
- accum += 2 + charwidths[c].abcfA + charwidths[c].abcfB + charwidths[c].abcfC;
- }
- if (accum > testW)
- {
- testW = accum;
- }
- }
- // we want two rows of pixels on top and bottom, as well
- long testH = (textinfo.tmHeight+2)*14; // 16 rows of 16 chars, but the first 32 are non-printable
- long testS = max(testW,testH);
- if (testS <= 128)
- {
- texSize = 128;
- }
- else if (testS <= 256)
- {
- texSize = 256;
- }
- else if (testS <= 512)
- {
- texSize = 512;
- }
- else if (testS <= 1024)
- {
- texSize = 1024;
- }
- else
- {
- puts("Cannot fit the font into 1024x1024 texture.");
- }
- sprintf_s(buf, "%s%s%s_%d_0_Lod_A.tex",
- fontname.c_str(),
- bold?"_Bold":"",
- antialiased?"_AA":"",
- fontsize);
- FILE * texout = fopen(buf, "wb");
- assert(texout);
- fwrite(&texSize, 4, 1, texout);
- fwrite(&texSize, 4, 1, texout);
- int left = 0;
- int top = 0;
- int tallest = 0;
- char disp[2] = " ";
- HDC dbgDC = GetDC(0);
- for (int c = 0; c<256; ++c)
- {
- if ((c&0x0F) == 0)
- {
- left = 0;
- top += tallest;
- }
- if (isprint(c))
- {
- disp[0] = c;
- SIZE sz;
- GetTextExtentPoint32(dc, disp, 1, &sz);
- assert(sz.cx == (long)(charwidths[c].abcfA + charwidths[c].abcfB + charwidths[c].abcfC));
- // make sure we've cleared out previous characters...
- for (int y=0; y<sz.cy+2; ++y)
- {
- for (int x=0; x<sz.cx+2; ++x)
- {
- pixels[y*maxW + x].rgbRed = 0xFF;
- pixels[y*maxW + x].rgbGreen = 0xFF;
- pixels[y*maxW + x].rgbBlue = 0xFF;
- pixels[y*maxW + x].rgbReserved = 0xFF;
- }
- }
- // offset by 1 so that we have some padding around the character.
- TextOut(dc, 1, 1, disp, 1);
- for (int y=0; y<sz.cy+2; ++y)
- {
- for (int x=0; x<sz.cx+2; ++x)
- {
- COLORREF clr = RGB( pixels[y*maxW + x].rgbRed,
- pixels[y*maxW + x].rgbGreen,
- pixels[y*maxW + x].rgbBlue);
- texarray[left+x][top+y][0] = 0xFF;
- texarray[left+x][top+y][1] = 0xFF;
- texarray[left+x][top+y][2] = 0xFF;
- texarray[left+x][top+y][3] = 0xFF - (unsigned char)(pixels[y*maxW + x].rgbRed);
- }
- }
- fntinfo[c].left = (float)(left+1)/(float)texSize;
- fntinfo[c].top = (float)(top+1)/(float)texSize;
- fntinfo[c].right = (float)(left+sz.cx)/(float)texSize;
- fntinfo[c].bottom = (float)(top+sz.cy)/(float)texSize;
- fntinfo[c].width = sz.cx;
- fntinfo[c].height = sz.cy;
- fntinfo[c].ascent = ceil((double)textinfo.tmAscent) + 2;
- fntinfo[c].kerning = ceil(charwidths[c].abcfA);
- left += sz.cx + 2;
- if (sz.cy + 2 > tallest)
- {
- tallest = sz.cy + 2;
- }
- }
- else
- {
- //disp[0] = ' '; // don't put funky boxes in for the non-printable chars...
- // ignore non-printables
- fntinfo[c].left = 0.0;
- fntinfo[c].top = 0.0;
- fntinfo[c].right = 0.0;
- fntinfo[c].bottom = 0.0;
- fntinfo[c].width = 0.0;
- fntinfo[c].height = 0.0;
- fntinfo[c].ascent = 0.0;
- fntinfo[c].kerning = 0.0;
- }
- }
- for (int y=0; y<texSize; ++y)
- {
- for (int x=0; x<texSize; ++x)
- {
- for (int comp=0; comp<4; ++comp)
- {
- fwrite(&texarray[x][y][comp], 1, 1, texout);
- }
- }
- }
- fclose(texout);
- // Now for the .fnt file.
- sprintf_s(buf, "%s%s%s_%d.fnt",
- fontname.c_str(),
- bold?"_Bold":"",
- antialiased?"_AA":"",
- fontsize);
- FILE * fntout = fopen(buf, "wb");
- float fval;
- long ival;
- fval = fontsize;
- fwrite(&fval, 4, 1, fntout);
- ival = 1;
- fwrite(&ival, 4, 1, fntout);
- fwrite(&ival, 4, 1, fntout);
- sprintf_s(buf, "%s%s%s_%d_0_Lod_A",
- fontname.c_str(),
- bold?"_Bold":"",
- antialiased?"_AA":"",
- fontsize);
- long namelen = strlen(buf);
- fwrite(buf, 1, namelen, fntout);
- ZeroMemory(buf, sizeof(buf));
- fwrite(buf, 1, (296-12)-namelen, fntout);
- for (int c=0; c<256; ++c)
- {
- fval = 0.0;
- fwrite(&fval, 4, 1, fntout);
- fwrite(&fntinfo[c].left, 4, 1, fntout);
- fwrite(&fntinfo[c].top, 4, 1, fntout);
- fwrite(&fntinfo[c].right, 4, 1, fntout);
- fwrite(&fntinfo[c].top, 4, 1, fntout);
- fwrite(&fntinfo[c].left, 4, 1, fntout);
- fwrite(&fntinfo[c].bottom, 4, 1, fntout);
- fwrite(&fntinfo[c].right, 4, 1, fntout);
- fwrite(&fntinfo[c].bottom, 4, 1, fntout);
- fwrite(&fntinfo[c].width, 4, 1, fntout);
- fwrite(&fntinfo[c].height, 4, 1, fntout);
- fval = 0.0;
- fwrite(&fval, 4, 1, fntout);
- fwrite(&fntinfo[c].kerning, 4, 1, fntout);
- fwrite(&fntinfo[c].ascent, 4, 1, fntout);
- }
- fclose(fntout);
- DeleteObject(SelectObject(dc,origfont));
- DeleteObject(SelectObject(dc,origbm));
- DeleteDC(dc);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement