SHARE
TWEET

MakeMWFont

a guest Jan 21st, 2011 80 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // MakeMwFont.cpp : Defines the entry point for the console application.
  2. //
  3.  
  4. #include "stdafx.h"
  5.  
  6. using namespace std;
  7.  
  8. char texarray[1024][1024][4];
  9. char fntarray[14632];
  10. float * asfloat = (float*)fntarray;
  11. char buf[4000];
  12.  
  13. struct FNTINFO
  14. {
  15.         float left;
  16.         float top;
  17.         float right;
  18.         float bottom;
  19.         float width;
  20.         float height;
  21.         float kerning;
  22.         float ascent;
  23. };
  24. FNTINFO fntinfo[256];
  25.  
  26. const int maxW = 1024;
  27. const int maxH = 1024;
  28.  
  29. int _tmain(int argc, _TCHAR* argv[])
  30. {
  31.         puts("Font Name (example: Verdana) :");
  32.         gets_s(buf);
  33.         string fontname = buf;
  34.  
  35.         puts("Font Size (example: 16 for normal, 20 for large) :");
  36.         gets_s(buf);
  37.         long fontsize = atoi(buf);
  38.  
  39.         puts("Bold? (y for yes, n for no)");
  40.         gets_s(buf);
  41.         bool bold = ( (buf[0]=='y') || (buf[0]=='Y') );
  42.  
  43.         puts("Anti-aliased? (y for yes, n for no)");
  44.         gets_s(buf);
  45.         bool antialiased = ( (buf[0]=='y') || (buf[0]=='Y') );
  46.  
  47.         HDC dc = CreateCompatibleDC(GetDC(0));
  48.         assert(dc);
  49.  
  50.         void * pixelbuffer;
  51.         BITMAPINFO bmi;
  52.         ZeroMemory(&bmi, sizeof(bmi));
  53.         bmi.bmiHeader.biBitCount = 32;
  54.         bmi.bmiHeader.biCompression = BI_RGB;
  55.         bmi.bmiHeader.biWidth = maxW;
  56.         bmi.bmiHeader.biHeight = -maxH;
  57.         bmi.bmiHeader.biPlanes = 1;
  58.         bmi.bmiHeader.biSize = sizeof(bmi);
  59.         bmi.bmiHeader.biXPelsPerMeter = 3600;
  60.         bmi.bmiHeader.biYPelsPerMeter = 3600;
  61.         HBITMAP hbm = CreateDIBSection(dc, &bmi, DIB_RGB_COLORS, &pixelbuffer, NULL, 0);
  62.         assert(hbm);
  63.         assert(pixelbuffer);
  64.  
  65.         RGBQUAD * pixels = (RGBQUAD*)pixelbuffer;
  66.         memset(pixelbuffer, 0xFF, maxW*maxH*4); // make background white
  67.  
  68.         HBITMAP origbm = (HBITMAP)SelectObject(dc, hbm);
  69.  
  70.         HFONT hfont = CreateFont(fontsize, 0, 0, 0,
  71.                                                 bold?FW_BOLD:FW_NORMAL, FALSE, FALSE, FALSE,
  72.                                                 ANSI_CHARSET, OUT_RASTER_PRECIS, CLIP_DEFAULT_PRECIS,
  73.                                                 antialiased?ANTIALIASED_QUALITY:NONANTIALIASED_QUALITY,
  74.                                                 DEFAULT_PITCH|FF_DONTCARE, fontname.c_str());
  75.         assert(hfont);
  76.  
  77.         HFONT origfont = (HFONT)SelectObject(dc, hfont);
  78.  
  79.         ABCFLOAT charwidths[256];
  80.         BOOL success = GetCharABCWidthsFloat(dc, 0, 255, charwidths);
  81.         assert(success);
  82.         for (int c=0; c<256; ++c)
  83.         {
  84.                 // swap out space for unprintable chars
  85.                 if (!isprint(c))
  86.                 {
  87.                         charwidths[c] = charwidths[' '];
  88.                 }
  89.         }
  90.  
  91.         TEXTMETRIC textinfo;
  92.         success = GetTextMetrics(dc, &textinfo);
  93.         assert(success);
  94.  
  95.  
  96.  
  97.         // Patch up the font name so it's a good filename
  98.         for (int i=0; i<fontname.size(); ++i)
  99.         {
  100.                 if (isspace(fontname[i]))
  101.                 {
  102.                         fontname[i] = '_';
  103.                 }
  104.         }
  105.  
  106.  
  107.         // First, the .tex file.
  108.         long texSize;
  109.         long testW = 0;
  110.         long accum = 0;
  111.         for (int c=0; c<256; ++c)
  112.         {
  113.                 if (c%0x0F == 0)
  114.                 {
  115.                         accum = 0;
  116.                 }
  117.  
  118.                 if (isprint(c))
  119.                 {
  120.                         // we want an extra column of pixels on left and right
  121.                         // to keep the texturing engine from accidentally picking
  122.                         // up adjacent characters
  123.                         accum += 2 + charwidths[c].abcfA + charwidths[c].abcfB + charwidths[c].abcfC;
  124.                 }
  125.  
  126.                 if (accum > testW)
  127.                 {
  128.                         testW = accum;
  129.                 }
  130.         }
  131.         // we want two rows of pixels on top and bottom, as well
  132.         long testH = (textinfo.tmHeight+2)*14; // 16 rows of 16 chars, but the first 32 are non-printable
  133.         long testS = max(testW,testH);
  134.         if (testS <= 128)
  135.         {
  136.                 texSize = 128;
  137.         }
  138.         else if (testS <= 256)
  139.         {
  140.                 texSize = 256;
  141.         }
  142.         else if (testS <= 512)
  143.         {
  144.                 texSize = 512;
  145.         }
  146.         else if (testS <= 1024)
  147.         {
  148.                 texSize = 1024;
  149.         }
  150.         else
  151.         {
  152.                 puts("Cannot fit the font into 1024x1024 texture.");
  153.         }
  154.  
  155.         sprintf_s(buf, "%s%s%s_%d_0_Lod_A.tex",
  156.                 fontname.c_str(),
  157.                 bold?"_Bold":"",
  158.                 antialiased?"_AA":"",
  159.                 fontsize);
  160.         FILE * texout = fopen(buf, "wb");
  161.         assert(texout);
  162.  
  163.         fwrite(&texSize, 4, 1, texout);
  164.         fwrite(&texSize, 4, 1, texout);
  165.         int left = 0;
  166.         int top = 0;
  167.         int tallest = 0;
  168.         char disp[2] = " ";
  169.         HDC dbgDC = GetDC(0);
  170.         for (int c = 0; c<256; ++c)
  171.         {
  172.                 if ((c&0x0F) == 0)
  173.                 {
  174.                         left = 0;
  175.                         top += tallest;
  176.                 }
  177.  
  178.                 if (isprint(c))
  179.                 {
  180.                         disp[0] = c;
  181.  
  182.                         SIZE sz;
  183.                         GetTextExtentPoint32(dc, disp, 1, &sz);
  184.  
  185.                         assert(sz.cx == (long)(charwidths[c].abcfA + charwidths[c].abcfB + charwidths[c].abcfC));
  186.  
  187.                         // make sure we've cleared out previous characters...
  188.                         for (int y=0; y<sz.cy+2; ++y)
  189.                         {
  190.                                 for (int x=0; x<sz.cx+2; ++x)
  191.                                 {
  192.                                         pixels[y*maxW + x].rgbRed = 0xFF;
  193.                                         pixels[y*maxW + x].rgbGreen = 0xFF;
  194.                                         pixels[y*maxW + x].rgbBlue = 0xFF;
  195.                                         pixels[y*maxW + x].rgbReserved = 0xFF;
  196.                                 }
  197.                         }
  198.  
  199.                         // offset by 1 so that we have some padding around the character.
  200.                         TextOut(dc, 1, 1, disp, 1);
  201.  
  202.                         for (int y=0; y<sz.cy+2; ++y)
  203.                         {
  204.                                 for (int x=0; x<sz.cx+2; ++x)
  205.                                 {
  206.                                         COLORREF clr = RGB(     pixels[y*maxW + x].rgbRed,
  207.                                                                                 pixels[y*maxW + x].rgbGreen,
  208.                                                                                 pixels[y*maxW + x].rgbBlue);
  209.                                         texarray[left+x][top+y][0] = 0xFF;
  210.                                         texarray[left+x][top+y][1] = 0xFF;
  211.                                         texarray[left+x][top+y][2] = 0xFF;
  212.                                         texarray[left+x][top+y][3] = 0xFF - (unsigned char)(pixels[y*maxW + x].rgbRed);
  213.                                 }
  214.                         }
  215.  
  216.                         fntinfo[c].left = (float)(left+1)/(float)texSize;
  217.                         fntinfo[c].top = (float)(top+1)/(float)texSize;
  218.                         fntinfo[c].right = (float)(left+sz.cx)/(float)texSize;
  219.                         fntinfo[c].bottom = (float)(top+sz.cy)/(float)texSize;
  220.                         fntinfo[c].width = sz.cx;
  221.                         fntinfo[c].height = sz.cy;
  222.                         fntinfo[c].ascent = ceil((double)textinfo.tmAscent) + 2;
  223.                         fntinfo[c].kerning = ceil(charwidths[c].abcfA);
  224.  
  225.                         left += sz.cx + 2;
  226.                         if (sz.cy + 2 > tallest)
  227.                         {
  228.                                 tallest = sz.cy + 2;
  229.                         }
  230.                 }
  231.                 else
  232.                 {
  233.                         //disp[0] = ' '; // don't put funky boxes in for the non-printable chars...
  234.  
  235.                         // ignore non-printables
  236.                         fntinfo[c].left = 0.0;
  237.                         fntinfo[c].top = 0.0;
  238.                         fntinfo[c].right = 0.0;
  239.                         fntinfo[c].bottom = 0.0;
  240.                         fntinfo[c].width = 0.0;
  241.                         fntinfo[c].height = 0.0;
  242.                         fntinfo[c].ascent = 0.0;
  243.                         fntinfo[c].kerning = 0.0;
  244.                 }
  245.         }
  246.         for (int y=0; y<texSize; ++y)
  247.         {
  248.                 for (int x=0; x<texSize; ++x)
  249.                 {
  250.                         for (int comp=0; comp<4; ++comp)
  251.                         {
  252.                                 fwrite(&texarray[x][y][comp], 1, 1, texout);
  253.                         }
  254.                 }
  255.         }
  256.         fclose(texout);
  257.  
  258.  
  259.  
  260.         // Now for the .fnt file.
  261.         sprintf_s(buf, "%s%s%s_%d.fnt",
  262.                 fontname.c_str(),
  263.                 bold?"_Bold":"",
  264.                 antialiased?"_AA":"",
  265.                 fontsize);
  266.         FILE * fntout = fopen(buf, "wb");
  267.         float fval;
  268.         long ival;
  269.  
  270.         fval = fontsize;
  271.         fwrite(&fval, 4, 1, fntout);
  272.  
  273.         ival = 1;
  274.         fwrite(&ival, 4, 1, fntout);
  275.         fwrite(&ival, 4, 1, fntout);
  276.  
  277.         sprintf_s(buf, "%s%s%s_%d_0_Lod_A",
  278.                 fontname.c_str(),
  279.                 bold?"_Bold":"",
  280.                 antialiased?"_AA":"",
  281.                 fontsize);
  282.         long namelen = strlen(buf);
  283.         fwrite(buf, 1, namelen, fntout);
  284.  
  285.         ZeroMemory(buf, sizeof(buf));
  286.         fwrite(buf, 1, (296-12)-namelen, fntout);
  287.  
  288.         for (int c=0; c<256; ++c)
  289.         {
  290.                 fval = 0.0;
  291.                 fwrite(&fval, 4, 1, fntout);
  292.  
  293.                 fwrite(&fntinfo[c].left, 4, 1, fntout);
  294.                 fwrite(&fntinfo[c].top, 4, 1, fntout);
  295.  
  296.                 fwrite(&fntinfo[c].right, 4, 1, fntout);
  297.                 fwrite(&fntinfo[c].top, 4, 1, fntout);
  298.  
  299.                 fwrite(&fntinfo[c].left, 4, 1, fntout);
  300.                 fwrite(&fntinfo[c].bottom, 4, 1, fntout);
  301.  
  302.                 fwrite(&fntinfo[c].right, 4, 1, fntout);
  303.                 fwrite(&fntinfo[c].bottom, 4, 1, fntout);
  304.  
  305.                 fwrite(&fntinfo[c].width, 4, 1, fntout);
  306.                 fwrite(&fntinfo[c].height, 4, 1, fntout);
  307.  
  308.                 fval = 0.0;
  309.                 fwrite(&fval, 4, 1, fntout);
  310.  
  311.                 fwrite(&fntinfo[c].kerning, 4, 1, fntout);
  312.                 fwrite(&fntinfo[c].ascent, 4, 1, fntout);
  313.         }
  314.  
  315.         fclose(fntout);
  316.  
  317.  
  318.         DeleteObject(SelectObject(dc,origfont));
  319.         DeleteObject(SelectObject(dc,origbm));
  320.         DeleteDC(dc);
  321.         return 0;
  322. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top