Ejemplo n.º 1
0
    //==============================================================================
    KERNINGPAIR* getKerningPairs (int& numKPs_)
    {
        if (kps == 0)
        {
            numKPs = GetKerningPairs (dc, 0, 0);
            kps.calloc (numKPs);
            GetKerningPairs (dc, numKPs, kps);
        }

        numKPs_ = numKPs;
        return kps;
    }
Ejemplo n.º 2
0
    void createKerningPairs (HDC dc, const float height)
    {
        HeapBlock<KERNINGPAIR> rawKerning;
        const DWORD numKPs = GetKerningPairs (dc, 0, 0);
        rawKerning.calloc (numKPs);
        GetKerningPairs (dc, numKPs, rawKerning);

        kerningPairs.ensureStorageAllocated ((int) numKPs);

        for (DWORD i = 0; i < numKPs; ++i)
        {
            KerningPair kp;
            kp.glyph1 = getGlyphForChar (dc, rawKerning[i].wFirst);
            kp.glyph2 = getGlyphForChar (dc, rawKerning[i].wSecond);

            const int standardWidth = getGlyphWidth (dc, kp.glyph1);
            kp.kerning = (standardWidth + rawKerning[i].iKernAmount) / height;
            kerningPairs.add (kp);

            kp.glyph2 = -1;  // add another entry for the standard width version..
            kp.kerning = standardWidth / height;
            kerningPairs.add (kp);
        }
    }
Ejemplo n.º 3
0
bool CFont::Init()
{
  HDC hDC = CreateCompatibleDC(0);
  int iXdpi, iYdpi;
  iXdpi = GetDeviceCaps(hDC, LOGPIXELSX);
  iYdpi = GetDeviceCaps(hDC, LOGPIXELSY);

  LOGFONT lf;
  lf.lfHeight = m_iSizePt * iYdpi / 72;
  lf.lfWidth = 0;
  lf.lfEscapement = 0;
  lf.lfOrientation = 0;
  lf.lfWeight = FW_DONTCARE;
  lf.lfItalic = false;
  lf.lfUnderline = false;
  lf.lfStrikeOut = false;
  lf.lfCharSet = ANSI_CHARSET;
  lf.lfOutPrecision = OUT_TT_PRECIS;
  lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
  lf.lfQuality = ANTIALIASED_QUALITY;
  lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
  strcpy(lf.lfFaceName, m_sTypeface.m_pBuf);

  HFONT hFont = CreateFontIndirect(&lf);
  SelectObject(hDC, hFont);

  TEXTMETRIC tm;
  bool bRes;
  bRes = !!GetTextMetrics(hDC, &tm);
  m_iAscent = tm.tmAscent;
  m_iDescent = tm.tmDescent;
  m_iHeight = tm.tmHeight;
  m_iInternalLead = tm.tmInternalLeading;
  m_iExternalLead = tm.tmExternalLeading;
  m_iAverageWidth = tm.tmAveCharWidth;
//  m_iMaxWidth = tm.tmMaxCharWidth;
  m_iFirstChar = tm.tmFirstChar;

  int iChars = tm.tmLastChar - tm.tmFirstChar + 1;
  float fCols, fRows;

  ABC abc[MAX_CHARS];
  bRes = !!GetCharABCWidths(hDC, tm.tmFirstChar, tm.tmLastChar, abc + tm.tmFirstChar);

  int i;
  m_iMaxWidth = 0;
  for (i = 0; i < tm.tmFirstChar; i++)
    m_Chars[i].ch = 0;
  while (i <= tm.tmLastChar) {
    m_Chars[i].ch = i;
    m_Chars[i].iA = abc[i].abcA;
    m_Chars[i].iB = abc[i].abcB;
    m_Chars[i].iC = abc[i].abcC;
    m_iMaxWidth = Util::Max(m_iMaxWidth, m_Chars[i].iB);
    i++;
  }
  while (i < MAX_CHARS) {
    m_Chars[i].ch = 0;
    i++;
  }

  int iKernPairs;
  KERNINGPAIR *pKernPairs;
  iKernPairs = GetKerningPairs(hDC, 0, 0);
  pKernPairs = new KERNINGPAIR[iKernPairs];
  GetKerningPairs(hDC, iKernPairs, pKernPairs);

  for (i = 0; i < iKernPairs; i++) 
    m_KerningPairs.Add(TKerningPair((char) pKernPairs[i].wFirst, (char) pKernPairs[i].wSecond, pKernPairs[i].iKernAmount));

  delete [] pKernPairs;

  fRows = sqrt(iChars * m_iMaxWidth / (float) m_iHeight);
  fCols = fRows * m_iHeight / (float) m_iMaxWidth;
  m_iCellCols = (int) ceil(fCols);
  m_iCellRows = (int) ceil(fRows);

  if (m_iCellCols > m_iCellRows) {
    if (m_iCellCols * (m_iCellRows - 1) >= iChars)
      m_iCellRows--;
  } else
    if ((m_iCellCols - 1) * m_iCellRows >= iChars) 
      m_iCellCols--;

  ASSERT(m_iCellRows * m_iCellCols >= iChars);

  BITMAPINFO bmi;
  bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
  bmi.bmiHeader.biWidth = m_iCellCols * m_iMaxWidth; 
  bmi.bmiHeader.biHeight = -m_iCellRows * m_iHeight; 
  bmi.bmiHeader.biPlanes = 1; 
  bmi.bmiHeader.biBitCount = 24; 
  bmi.bmiHeader.biCompression = BI_RGB; 
  bmi.bmiHeader.biSizeImage = 0; 
  bmi.bmiHeader.biXPelsPerMeter = (int) (iXdpi / 2.54f * 100); 
  bmi.bmiHeader.biYPelsPerMeter = (int) (iYdpi / 2.54f * 100); 
  bmi.bmiHeader.biClrUsed = 0; 
  bmi.bmiHeader.biClrImportant = 0; 

  HBITMAP hBmp = CreateDIBSection(hDC, &bmi, 0, 0, 0, 0);
  SelectObject(hDC, hBmp);

  HBRUSH hBrush = CreateSolidBrush(RGB(0, 0, 0)); 
  SelectObject(hDC, hBrush);

  Rectangle(hDC, 0, 0, m_iCellCols * m_iMaxWidth, m_iCellRows * m_iHeight);

  SetTextColor(hDC, RGB(255, 255, 255));
  SetBkColor(hDC, RGB(0, 0, 0));
  SetBkMode(hDC, TRANSPARENT);
  SetTextAlign(hDC, TA_TOP | TA_LEFT | TA_NOUPDATECP);

  for (int iRow = 0; iRow < m_iCellRows; iRow++)
    for (int iCol = 0; iCol < m_iCellCols; iCol++) {
      RECT rc;
      char chBuf[2] = { m_iFirstChar + iRow * m_iCellCols + iCol, 0 };
      if (!m_Chars[(uint8_t) chBuf[0]].ch)
        continue;
      rc.left = iCol * m_iMaxWidth - m_Chars[(uint8_t) chBuf[0]].iA;
      rc.top = iRow * m_iHeight;
      rc.right = rc.left + m_iMaxWidth;
      rc.bottom = rc.top + m_iHeight;
//      DrawText(hDC, chBuf, 1, &rc, DT_LEFT | DT_TOP);
      TextOut(hDC, rc.left, rc.top, chBuf, 1);
    }

  bRes = !!GdiFlush();

  bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
  bmi.bmiHeader.biWidth = m_iCellCols * m_iMaxWidth; 
  bmi.bmiHeader.biHeight = -m_iCellRows * m_iHeight; 
  bmi.bmiHeader.biPlanes = 1; 
  bmi.bmiHeader.biBitCount = 32; 
  bmi.bmiHeader.biCompression = BI_RGB; 
  bmi.bmiHeader.biSizeImage = 0; 
  bmi.bmiHeader.biXPelsPerMeter = (int) (iXdpi / 2.54f * 100); 
  bmi.bmiHeader.biYPelsPerMeter = (int) (iYdpi / 2.54f * 100); 
  bmi.bmiHeader.biClrUsed = 0; 
  bmi.bmiHeader.biClrImportant = 0; 
  int iSize = bmi.bmiHeader.biWidth * abs(bmi.bmiHeader.biHeight) * bmi.bmiHeader.biBitCount / 8;
  uint8_t *pBuf = new uint8_t[iSize];
  bRes = !!GetDIBits(hDC, hBmp, 0, abs(bmi.bmiHeader.biHeight), pBuf, &bmi, DIB_RGB_COLORS);

  for (i = 0; i < iSize; i += 4)
//    Util::Swap(pBuf[i], pBuf[i + 2]);
    pBuf[i / 4] = pBuf[i];

  m_pTexture = new CTexture();
  bRes = m_pTexture->Init(bmi.bmiHeader.biWidth, abs(bmi.bmiHeader.biHeight), DXGI_FORMAT_R8_UNORM, 1, pBuf, bmi.bmiHeader.biWidth /* * bmi.bmiHeader.biBitCount / 8*/, 0);

/*
  ID3D11Resource *pTexRes = 0;
  m_pTexture->m_pTextureView->GetResource(&pTexRes);
  D3DX11SaveTextureToFile(CGraphics::Get()->m_pDeviceContext, pTexRes, D3DX11_IFF_BMP, "font.bmp");
  SAFE_RELEASE(pTexRes);
*/

  delete [] pBuf;
  DeleteObject(hBrush);
  DeleteObject(hBmp);
  DeleteObject(hFont);
  DeleteDC(hDC);

  if (!InitModel())
    return false;

  return true;
}
Ejemplo n.º 4
0
int CFontGen::SaveFont(const char *szFile)
{
	if( isWorking ) return -1;

	// The pages must be generated first
	if( !arePagesGenerated ) return -1;

	// Create a memory dc
	HDC dc = CreateCompatibleDC(0);

	HFONT font = CreateFont(0);
	HFONT oldFont = (HFONT)SelectObject(dc, font);

	// Determine the size needed for the char
	int height, base;

	TEXTMETRIC tm;
	GetTextMetrics(dc, &tm);

	// Round up to make sure fractional pixels are covered
	height = (int)ceil(float(tm.tmHeight)/aa);
	base = (int)ceil(float(tm.tmAscent)/aa);

	// Save the character attributes
	FILE *f;

	string filename = szFile;
	if( _stricmp(filename.substr(filename.length() - 4).c_str(), ".fnt") == 0 )
		filename = filename.substr(0, filename.length() - 4);

	errno_t e = fopen_s(&f, (filename + ".fnt").c_str(), "wb");
	if( e != 0 || f == 0 )
		return -1;

	// Get the filename without path
	int r = filename.rfind('\\');
	string filenameonly;
	if( r != -1 )
		filenameonly = filename.substr(r+1);
	else
		filenameonly = filename;
		
	if( outBitDepth != 32 ) fourChnlPacked = false;
	int numPages = pages.size();

	// Determine the number of digits needed for the page file id
	int numDigits = numPages > 1 ? int(log10(float(numPages-1))+1) : 1;

	if( fontDescFormat == 1 ) 
	{
		fprintf(f, "<?xml version=\"1.0\"?>\r\n");
		fprintf(f, "<font>\r\n");
		fprintf(f, "  <info face=\"%s\" size=\"%d\" bold=\"%d\" italic=\"%d\" charset=\"%s\" unicode=\"%d\" stretchH=\"%d\" smooth=\"%d\" aa=\"%d\" padding=\"%d,%d,%d,%d\" spacing=\"%d,%d\" outline=\"%d\"/>\r\n", fontName.c_str(), fontSize, isBold, isItalic, useUnicode ? "" : GetCharSetName(charSet).c_str(), useUnicode, scaleH, useSmoothing, aa, paddingUp, paddingRight, paddingDown, paddingLeft, spacingHoriz, spacingVert, outlineThickness);
		fprintf(f, "  <common lineHeight=\"%d\" base=\"%d\" scaleW=\"%d\" scaleH=\"%d\" pages=\"%d\" packed=\"%d\" alphaChnl=\"%d\" redChnl=\"%d\" greenChnl=\"%d\" blueChnl=\"%d\"/>\r\n", int(ceilf(height*float(scaleH)/100.0f)), int(ceilf(base*float(scaleH)/100.0f)), outWidth, outHeight, numPages, fourChnlPacked, alphaChnl, redChnl, greenChnl, blueChnl);

		fprintf(f, "  <pages>\r\n");
		for( int n = 0; n < numPages; n++ )
			fprintf(f, "    <page id=\"%d\" file=\"%s_%0*d.%s\" />\r\n", n, filenameonly.c_str(), numDigits, n, textureFormat.c_str());
		fprintf(f, "  </pages>\r\n");
	}
	else if( fontDescFormat == 0 )
	{
		fprintf(f, "info face=\"%s\" size=%d bold=%d italic=%d charset=\"%s\" unicode=%d stretchH=%d smooth=%d aa=%d padding=%d,%d,%d,%d spacing=%d,%d outline=%d\r\n", fontName.c_str(), fontSize, isBold, isItalic, useUnicode ? "" : GetCharSetName(charSet).c_str(), useUnicode, scaleH, useSmoothing, aa, paddingUp, paddingRight, paddingDown, paddingLeft, spacingHoriz, spacingVert, outlineThickness);
		fprintf(f, "common lineHeight=%d base=%d scaleW=%d scaleH=%d pages=%d packed=%d alphaChnl=%d redChnl=%d greenChnl=%d blueChnl=%d\r\n", int(ceilf(height*float(scaleH)/100.0f)), int(ceilf(base*float(scaleH)/100.0f)), outWidth, outHeight, numPages, fourChnlPacked, alphaChnl, redChnl, greenChnl, blueChnl);

		for( int n = 0; n < numPages; n++ )
			fprintf(f, "page id=%d file=\"%s_%0*d.%s\"\r\n", n, filenameonly.c_str(), numDigits, n, textureFormat.c_str());
	}
	else
	{
		// Write the magic word and file version
		fwrite("BMF", 3, 1, f);
		fputc(3, f); 

		// Write the info block
#pragma pack(push)
#pragma pack(1)
		struct infoBlock
		{
			int            blockSize;
			unsigned short fontSize;
			char           reserved    :4;
			char           bold        :1;
			char           italic      :1;
			char           unicode     :1;
			char           smooth      :1;
			unsigned char  charSet;
			unsigned short stretchH;
			char           aa;
			unsigned char  paddingUp;
			unsigned char  paddingRight;
			unsigned char  paddingDown;
			unsigned char  paddingLeft;
			unsigned char  spacingHoriz;
			unsigned char  spacingVert;
			unsigned char  outline;
			char           fontName[1];
		} info;
#pragma pack(pop)

		info.blockSize    = sizeof(info) + fontName.length() - 4;
		info.fontSize     = fontSize;
		info.reserved     = 0;
		info.bold         = isBold;
		info.italic       = isItalic;
		info.unicode      = useUnicode;
		info.smooth       = useSmoothing;
		info.charSet      = charSet;
		info.stretchH     = scaleH;
		info.aa           = aa;
		info.paddingUp    = paddingUp;
		info.paddingRight = paddingRight;
		info.paddingDown  = paddingDown;
		info.paddingLeft  = paddingLeft;
		info.spacingHoriz = spacingHoriz;
		info.spacingVert  = spacingVert;
		info.outline      = outlineThickness;

		fputc(1, f);
		fwrite(&info, sizeof(info)-1, 1, f);
		fwrite(fontName.c_str(), fontName.length()+1, 1, f);

		// Write the common block
#pragma pack(push)
#pragma pack(1)
		struct commonBlock
		{
			int blockSize;
			unsigned short lineHeight;
			unsigned short base;
			unsigned short scaleW;
			unsigned short scaleH;
			unsigned short pages;
			unsigned char  packed:1;
			unsigned char  reserved:7;
			unsigned char  alphaChnl;
			unsigned char  redChnl;
			unsigned char  greenChnl;
			unsigned char  blueChnl;
		} common; 
#pragma pack(pop)

		common.blockSize  = sizeof(common) - 4;
		common.lineHeight = int(ceilf(height*float(scaleH)/100.0f));
		common.base       = int(ceilf(base*float(scaleH)/100.0f));
		common.scaleW     = outWidth;
		common.scaleH     = outHeight;
		common.pages      = numPages;
		common.reserved   = 0;
		common.packed     = fourChnlPacked;
		common.alphaChnl  = alphaChnl;
		common.redChnl    = redChnl;
		common.greenChnl  = greenChnl;
		common.blueChnl   = blueChnl;

		fputc(2, f);
		fwrite(&common, sizeof(common), 1, f);

		// Write the page block
		fputc(3, f);
		int size = (filenameonly.length() + numDigits + 2 + textureFormat.length() + 1)*numPages;
		fwrite(&size, sizeof(size), 1, f);

		for( int n = 0; n < numPages; n++ )
		{
			fprintf(f, "%s_%0*d.%s", filenameonly.c_str(), numDigits, n, textureFormat.c_str());
			fputc(0, f);
		}
	}

	const int maxChars = useUnicode ? maxUnicodeChar+1 : 256;

	// Count the number of characters that will be written
	int numChars = 0;
	int n;
	for( n = 0; n < maxChars; n++ )
		if( chars[n] )
			numChars++;

	if( invalidCharGlyph )
		numChars++;

	if( fontDescFormat == 0 )
		fprintf(f, "chars count=%d\r\n", numChars);
	else if( fontDescFormat == 1 )
		fprintf(f, "  <chars count=\"%d\">\r\n", numChars);
	else if( fontDescFormat == 2 )
	{
		fputc(4, f);

		// Determine the size of this block
		int size = (4+2+2+2+2+2+2+2+1+1)*numChars;
		fwrite(&size, 4, 1, f);
	}

	if( invalidCharGlyph )
	{
		if( fontDescFormat == 1 )
			fprintf(f, "    <char id=\"%d\" x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\" xoffset=\"%d\" yoffset=\"%d\" xadvance=\"%d\" page=\"%d\" chnl=\"%d\" />\r\n", -1, invalidCharGlyph->m_x, invalidCharGlyph->m_y, invalidCharGlyph->m_width, invalidCharGlyph->m_height, invalidCharGlyph->m_xoffset, invalidCharGlyph->m_yoffset, invalidCharGlyph->m_advance, invalidCharGlyph->m_page, invalidCharGlyph->m_chnl);
		else if( fontDescFormat == 0 )
			fprintf(f, "char id=%-4d x=%-5d y=%-5d width=%-5d height=%-5d xoffset=%-5d yoffset=%-5d xadvance=%-5d page=%-2d chnl=%-2d\r\n", -1, invalidCharGlyph->m_x, invalidCharGlyph->m_y, invalidCharGlyph->m_width, invalidCharGlyph->m_height, invalidCharGlyph->m_xoffset, invalidCharGlyph->m_yoffset, invalidCharGlyph->m_advance, invalidCharGlyph->m_page, invalidCharGlyph->m_chnl);
		else
		{
#pragma pack(push)
#pragma pack(1)
			struct charBlock
			{
				DWORD id;
				WORD x;
				WORD y;
				WORD width;
				WORD height;
				short xoffset;
				short yoffset;
				short xadvance;
				char  page;
				char  channel;
			} charInfo;
#pragma pack(pop)

			charInfo.id = -1;
			charInfo.x  = invalidCharGlyph->m_x;
			charInfo.y  = invalidCharGlyph->m_y;
			charInfo.width = invalidCharGlyph->m_width;
			charInfo.height = invalidCharGlyph->m_height;
			charInfo.xoffset = invalidCharGlyph->m_xoffset;
			charInfo.yoffset = invalidCharGlyph->m_yoffset;
			charInfo.xadvance = invalidCharGlyph->m_advance;
			charInfo.page = invalidCharGlyph->m_page;
			charInfo.channel = invalidCharGlyph->m_chnl;

			fwrite(&charInfo, sizeof(charInfo), 1, f);
		}
	}

	for( n = 0; n < maxChars; n++ )
	{
        if( chars[n] )
		{
			int page, chnl;
			page = chars[n]->m_page;
			chnl = chars[n]->m_chnl;
			
			if( fontDescFormat == 1 )
				fprintf(f, "    <char id=\"%d\" x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\" xoffset=\"%d\" yoffset=\"%d\" xadvance=\"%d\" page=\"%d\" chnl=\"%d\" />\r\n", n, chars[n]->m_x, chars[n]->m_y, chars[n]->m_width, chars[n]->m_height, chars[n]->m_xoffset, chars[n]->m_yoffset, chars[n]->m_advance, page, chnl);
			else if( fontDescFormat == 0 )
				fprintf(f, "char id=%-4d x=%-5d y=%-5d width=%-5d height=%-5d xoffset=%-5d yoffset=%-5d xadvance=%-5d page=%-2d chnl=%-2d\r\n", n, chars[n]->m_x, chars[n]->m_y, chars[n]->m_width, chars[n]->m_height, chars[n]->m_xoffset, chars[n]->m_yoffset, chars[n]->m_advance, page, chnl);
			else
			{
#pragma pack(push)
#pragma pack(1)
				struct charBlock
				{
					DWORD id;
					WORD x;
					WORD y;
					WORD width;
					WORD height;
					short xoffset;
					short yoffset;
					short xadvance;
					char  page;
					char  channel;
				} charInfo;
#pragma pack(pop)

				charInfo.id = n;
				charInfo.x  = chars[n]->m_x;
				charInfo.y  = chars[n]->m_y;
				charInfo.width = chars[n]->m_width;
				charInfo.height = chars[n]->m_height;
				charInfo.xoffset = chars[n]->m_xoffset;
				charInfo.yoffset = chars[n]->m_yoffset;
				charInfo.xadvance = chars[n]->m_advance;
				charInfo.page = page;
				charInfo.channel = chnl;

				fwrite(&charInfo, sizeof(charInfo), 1, f);
			}
		}
	}

	if( fontDescFormat == 1 )
		fprintf(f, "  </chars>\r\n");


	// Save the kerning pairs as well
	vector<KERNINGPAIR> pairs;
	if( useUnicode )
	{
		// TODO: How do I obtain the kerning pairs for 
		// the characters in the higher planes?

		int num = GetKerningPairsW(dc, 0, 0);
		if( num > 0 )
		{
			pairs.resize(num);
			GetKerningPairsW(dc, num, &pairs[0]);
		}
	}
	else
	{
		int num = GetKerningPairs(dc, 0, 0);
		if( num > 0 )
		{
			pairs.resize(num);
			GetKerningPairs(dc, num, &pairs[0]);
		}
	}

	if( pairs.size() == 0 )
	{
		// Build a list of all selected chars
		vector<UINT> chars;
		chars.reserve(GetNumCharsSelected());
		for( UINT n = 0; n <= maxUnicodeChar; n++ )
		{
			if( selected[n] )
			{
				chars.push_back(n);
				if( chars.size() == GetNumCharsSelected() )
					break;
			}
		}

		GetKerningPairsFromGPOS(dc, pairs, chars);
	}

	if( pairs.size() > 0 )
	{
		// Count the number of kerning pairs
		int count = 0;
		for( unsigned int n = 0; n < pairs.size(); n++ )
		{
			if( pairs[n].wFirst < maxChars && pairs[n].wSecond < maxChars &&
				!disabled[pairs[n].wFirst] && !disabled[pairs[n].wSecond] &&
				selected[pairs[n].wFirst] && selected[pairs[n].wSecond] &&
				pairs[n].iKernAmount/aa )
			{
				count++;
			}
		}

		if( fontDescFormat == 0 )
			fprintf(f, "kernings count=%d\r\n", count);
		else if( fontDescFormat == 1 )
			fprintf(f, "  <kernings count=\"%d\">\r\n", count);
		else if( fontDescFormat == 2 )
		{
			fputc(5, f);

			// Determine the size of the block
			int size = count*10;
			fwrite(&size, 4, 1, f);
		}
	}

	// It's been reported that for Chinese WinXP the kerning pairs for 
	// non-unicode charsets may contain characters > 255, so we need to 
	// filter for this.
	for( unsigned int n = 0; n < pairs.size(); n++ )
	{
		if( pairs[n].wFirst < maxChars && pairs[n].wSecond < maxChars &&
			!disabled[pairs[n].wFirst] && !disabled[pairs[n].wSecond] &&
			selected[pairs[n].wFirst] && selected[pairs[n].wSecond] &&
			pairs[n].iKernAmount/aa )
		{
			if( fontDescFormat == 1 )
				fprintf(f, "    <kerning first=\"%d\" second=\"%d\" amount=\"%d\" />\r\n", pairs[n].wFirst, pairs[n].wSecond, pairs[n].iKernAmount/aa);
			else if( fontDescFormat == 0 )
				fprintf(f, "kerning first=%-3d second=%-3d amount=%-4d\r\n", pairs[n].wFirst, pairs[n].wSecond, pairs[n].iKernAmount/aa);
			else 
			{
#pragma pack(push)
#pragma pack(1)
				struct kerningBlock
				{
					DWORD first;
					DWORD second;
					short amount;
				} kerning;
#pragma pack(pop)
				kerning.first = pairs[n].wFirst;
				kerning.second = pairs[n].wSecond;
				kerning.amount = pairs[n].iKernAmount/aa;

				fwrite(&kerning, sizeof(kerning), 1, f);
			}
		}
	}

	if( pairs.size() > 0 && fontDescFormat == 1 )
		fprintf(f, "  </kernings>\r\n");

	if( fontDescFormat == 1 ) fprintf(f, "</font>\r\n");

	fclose(f);

	SelectObject(dc, oldFont);
	DeleteObject(font);

	DeleteDC(dc);


	// Save the image file
	for( n = 0; n < (signed)pages.size(); n++ )
	{
		string str = acStringFormat("%s_%0*d.%s", filename.c_str(), numDigits, n, textureFormat.c_str());

		acImage::Image image;
		image.width = outWidth;
		image.height = outHeight;
		if( outBitDepth == 32 )
		{
			image.pitch = image.width*4;
			image.format = acImage::PF_A8R8G8B8;
		}
		else
		{
			image.pitch = image.width;
			image.format = acImage::PF_A8;
		}

		image.data = new BYTE[image.pitch * image.height];

		// Generate the output texture for saving
		pages[n]->GenerateOutputTexture();

		cImage *page = pages[n]->GetPageImage();
		if( outBitDepth == 8 )
		{
			// Write image data
			for( int y = 0; y < outHeight; y++ )
			{
				for( int x = 0; x < outWidth; x++ )
				{
					DWORD pixel = page->pixels[y*outWidth + x];
					image.data[y*image.pitch + x] = (BYTE)(pixel>>24);
				}
			}
		}
		else
		{
			// Write image data
			for( int y = 0; y < outHeight; y++ )
			{
				for( int x = 0; x < outWidth; x++ )
				{
					DWORD pixel = page->pixels[y*outWidth + x];
					*(DWORD*)&image.data[y*image.pitch + x*4] = pixel;
				}
			}
		}

		if( textureFormat == "tga" )
			acImage::SaveTga(str.c_str(), image);
		else if( textureFormat == "png" )
			acImage::SavePng(str.c_str(), image);
		else if( textureFormat == "dds" )
			acImage::SaveDds(str.c_str(), image, textureCompression);
	}
Ejemplo n.º 5
0
FONTENUMPROC
FontFunc(
    LOGFONT    *plf,
    TEXTMETRIC *ptm,
    int         iType,
    FTPARAM    *pftp
)
{
    HFONT hf,
          hfOld;
    int cPair,                // number of kerning pairs
        cPairCopied,          // number of pairs coppied to buffer
        iSpace,               // space between successive lines
        y;                    // current y-coordinate
    char ach[100];            // scratch space
    HBRUSH hbOld;
    TEXTMETRIC tm;

    y = 20;
    iSpace = (int) (ptm->tmHeight + ptm->tmExternalLeading);

    hf = CreateFontIndirect(plf);
    if (hf == 0)
    {
        DbgPrint("FontFunc -- CreateFontIndirect failed\n");
    }
    hfOld = SelectObject(pftp->hdc,hf);
    if (hfOld == 0)
    {
        DbgPrint("FontFunc -- Select Object failed\n");
    }
    cPair = GetKerningPairs(pftp->hdc, 0, (KERNINGPAIR*) NULL);

    if (cPair != 0)
    {
        HANDLE hMem;
        PVOID  pvMem;

        hMem = LocalAlloc(LMEM_FIXED,cPair * sizeof(KERNINGPAIR));
        if (hMem == 0)
        {
            DbgPrint("FontFunc -- LocalAlloc failed\n");
            return(0);
        }
        if (hMem)
        {
            pvMem = LocalLock(hMem);
            if (pvMem == NULL)
            {
                DbgPrint("FontFunc -- LocalLock failed\n");
                return(0);
            }
            if (pvMem != NULL)
            {
                KERNINGPAIR *pkpTooBig;
                KERNINGPAIR *pkp = (KERNINGPAIR*) pvMem;

                cPairCopied = GetKerningPairs(pftp->hdc, cPair, pkp);
                pkpTooBig = pkp + cPairCopied;

                hbOld = SelectObject(pftp->hdc,GetStockObject(WHITE_BRUSH));
                PatBlt(
                    pftp->hdc,
                    pftp->prect->left,
                    pftp->prect->top + y,
                    pftp->prect->right - pftp->prect->left,
                    pftp->prect->bottom - pftp->prect->top,
                    PATCOPY
                );
                SelectObject(pftp->hdc,hbOld);

                wsprintf(ach,"%s has %d kerning pairs",plf->lfFaceName,cPair);
                TextOut(pftp->hdc,0,y,ach,strlen(ach));
                y += iSpace;

                wsprintf(ach,"    wFirst wSecond iKernAmount");
                TextOut(pftp->hdc,0,y,ach,strlen(ach));
                y += iSpace;

                while (pkp < pkpTooBig && (y + ptm->tmHeight < (int) pftp->prect->bottom))
                {
                    wsprintf(
                        ach,
                        "    %-#6lx %-#6lx   %d",
                        pkp->wFirst,
                        pkp->wSecond,
                        pkp->iKernAmount
                    );
                    TextOut(pftp->hdc,0,y,ach,strlen(ach));
                    y += iSpace;
                    pkp += 1;
                }
                vSleep(1);
            }
            LocalUnlock(hMem);
        }
    }

    SelectObject(pftp->hdc,hfOld);
    DeleteObject(hf);

    UNREFERENCED_PARAMETER(iType);
    return(1);
}