Exemple #1
0
GLuint drawChar_To_Texture(const char* s) {
	wchar_t w;
	HDC hDC = wglGetCurrentDC();

	// 选择字体字号、颜色
	// 不指定字体名字,操作系统提供默认字体
	// 设置颜色为白色
	selectFont(FONT_SIZE, DEFAULT_CHARSET, "");
	glColor3f(1.0f, 1.0f, 1.0f);

	// 转化为宽字符
	MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, s, 2, &w, 1);

	// 计算绘制的位置
	int width, x, y;
	GetCharWidth32W(hDC, w, w, &width);    // 取得字符的宽度
	x = (TEXTURE_SIZE - width) / 2;
	y = FONT_SIZE / 8;
	//glWindowPos2iARB(x, y); // 一个扩展函数

	GLuint list = glGenLists(1);

	glDisable(GL_DEPTH_TEST);
	glDisable(GL_LIGHTING);
	glDisable(GL_FOG);
	glDisable(GL_TEXTURE_2D);

	wglUseFontBitmaps(hDC, w, 1, list);
	glCallList(list);
	glDeleteLists(list, 1);

	GLuint texID;
	glGenTextures(1, &texID);
	glBindTexture(GL_TEXTURE_2D, texID);
	glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE4,
		0, 0, TEXTURE_SIZE, TEXTURE_SIZE, 0);
	glTexParameteri(GL_TEXTURE_2D,
		GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D,
		GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	return texID;
}
static bool FillGlyphDimensions(HDC hDC, const TEXTMETRICW& TextMetric, CTextureStringGlyph* pGlyphs, uint32 nNumGlyphs)
{
	// Setup the transform for the glyph.  Just use identity.
	MAT2 mat;
	mat.eM11 = FixedFromFloat( 1.0f );
	mat.eM12 = FixedFromFloat( 0.0f );
	mat.eM21 = FixedFromFloat( 0.0f );
	mat.eM22 = FixedFromFloat( 1.0f );

	//determine if this is a truetype font or not
	bool bTrueType = (TextMetric.tmPitchAndFamily & TMPF_TRUETYPE) != 0;

	// Get the individual widths of all chars in font, indexed by character values.
	GLYPHMETRICS GlyphMetrics;
	memset( &GlyphMetrics, 0, sizeof( GlyphMetrics ) );

	for( uint32 nCurrGlyph = 0; nCurrGlyph < nNumGlyphs; nCurrGlyph++ )
	{
		// Get the character for this glyph.
		CTextureStringGlyph& Glyph = pGlyphs[nCurrGlyph];

		if(bTrueType)
		{
			// Get the glyph metrics for this glyph.
			if( GDI_ERROR == GetGlyphOutlineW( hDC, Glyph.m_cGlyph, GGO_METRICS, &GlyphMetrics, 0, NULL, &mat ))
			{
				// Use the default character on anything that has issues.
				if( GDI_ERROR == GetGlyphOutlineW( hDC, TextMetric.tmDefaultChar, GGO_METRICS, &GlyphMetrics, 0, NULL, &mat ))
				{
					return false;
				}
			}

			//we have the glyph outline, so we now need to convert the data from that over to the glyph data
			//format
			Glyph.m_nTotalWidth			= GlyphMetrics.gmCellIncX;

			Glyph.m_rBlackBox.Left()	= GlyphMetrics.gmptGlyphOrigin.x;
			Glyph.m_rBlackBox.Top()		= TextMetric.tmAscent - GlyphMetrics.gmptGlyphOrigin.y;

			Glyph.m_rBlackBox.Right()	= Glyph.m_rBlackBox.Left() + GlyphMetrics.gmBlackBoxX + 1;
			Glyph.m_rBlackBox.Bottom()	= Glyph.m_rBlackBox.Top()  + GlyphMetrics.gmBlackBoxY + 1;
		}
		else
		{
			//this is not a truetype font, so we have to use a different approach for getting the glyph
			//sizes
			INT nWidth = 0;
			if(!GetCharWidth32W(hDC, Glyph.m_cGlyph, Glyph.m_cGlyph, &nWidth))
			{
				if(!GetCharWidth32W(hDC, TextMetric.tmDefaultChar, TextMetric.tmDefaultChar, &nWidth))
				{
					return false;
				}
			}

			//setup our character from that information
			Glyph.m_nTotalWidth			= nWidth;

			Glyph.m_rBlackBox.Left()	= 0;
			Glyph.m_rBlackBox.Top()		= 0;

			Glyph.m_rBlackBox.Right()	= nWidth;
			Glyph.m_rBlackBox.Bottom()	= TextMetric.tmHeight;
		}
	}

	//success
	return true;
}
void GR_Win32CharWidths::setCharWidthsOfRange(HDC hdc, UT_UCSChar c0, UT_UCSChar c1)
{
	if(m_vRanges.getItemCount() == 0)
	{
		_retrieveFontInfo(hdc);
	}
	
	UINT k;
	int w;
#ifdef DEBUG
	DWORD iErrorCode = 0;
#endif

	// Windows NT and Windows 95 support the Unicode Font file. 
	// All of the Unicode glyphs can be rendered if the glyph is found in
	// the font file. However, Windows 95 does  not support the Unicode 
	// characters other than the characters for which the particular codepage
	// of the font file is defined.
	// Reference Microsoft knowledge base:
	// Q145754 - PRB ExtTextOutW or TextOutW Unicode Text Output Is Blank
	if (UT_IsWinNT())
	{
		for (k=c0; k<=c1; k++)
		{
			if(k == 0x200B || k == 0xFEFF || k == UCS_LIGATURE_PLACEHOLDER)
				setWidth(k,0);
			else if(!_doesGlyphExist(k))
			{
				setWidth(k,GR_CW_ABSENT);
			}
			else
			{
				GetCharWidth32W(hdc,k,k,&w);
#ifdef DEBUG
				ABC abc;
				int iRes = GetCharABCWidthsW(hdc,k,k,&abc);
#endif
				// handle overstriking chars here
				UT_uint32 iOver = UT_isOverstrikingChar(k);
				if(!w || iOver != UT_NOT_OVERSTRIKING)
				{
					iOver &= UT_OVERSTRIKING_TYPE;

					if(iOver == UT_OVERSTRIKING_RIGHT)
					{
						w = 0;
					}
					else
					{
						ABC abc;
						UT_DebugOnly<int> iRes = GetCharABCWidthsW(hdc,k,k,&abc);
						UT_ASSERT( iRes );
						

						if(iOver == UT_OVERSTRIKING_LEFT)
						{
							UT_ASSERT( abc.abcB <  GR_OC_MAX_WIDTH);
							w = abc.abcB | GR_OC_LEFT_FLUSHED;
						}
						else
						{
							w = abc.abcB /*+ abc.abcA + abc.abcC*/;
							w = -w;
						}
					}
				}
				
				setWidth(k,w);
			}
		}
	}
	else
	{
		HFONT hFont = (HFONT) GetCurrentObject(hdc, OBJ_FONT);
		LOGFONTW aLogFont;
		UT_DebugOnly<int> iRes = GetObjectW(hFont, sizeof(LOGFONTW), &aLogFont);
		UT_ASSERT(iRes);

		xxx_UT_DEBUGMSG(("gr_Win32Graphics::getCharWidth: extra interchar. spacing %d\n", GetTextCharacterExtra(hdc)));
		
		if(aLogFont.lfCharSet == SYMBOL_CHARSET)
		{
			// Symbol character handling
			for (k=c0; k<=c1; k++)
			{
				if(!_doesGlyphExist(k))
				{
					setWidth(k,GR_CW_ABSENT);
				}
				else
				{
					SIZE Size;
					char str[sizeof(UT_UCSChar)];
					int iConverted = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR) &k, 1,
														 str, sizeof(str), NULL, NULL);
					GetTextExtentPoint32A(hdc, str, iConverted, &Size);
					setWidth(k, Size.cx);
				}
			}
		}
		else
		{
			// Unicode font and default character sets
			for (k=c0; k<=c1; k++)
			{
				if(k == 0x200B || k == 0xFEFF || k == UCS_LIGATURE_PLACEHOLDER)
					setWidth(k,0);
				else if(!_doesGlyphExist(k))
				{
					setWidth(k,GR_CW_ABSENT);
				}
				else
				{
					SIZE Size;
					wchar_t sz1[2];
					sz1[0] = k;
					
					GetTextExtentPoint32W(hdc, sz1, 1, &Size);
					// handle overstriking chars here
					UT_uint32 iOver = UT_isOverstrikingChar(k);
					if(!Size.cx ||  iOver != UT_NOT_OVERSTRIKING)
					{
						iOver &= UT_OVERSTRIKING_TYPE;

						if(iOver == UT_OVERSTRIKING_RIGHT)
						{
							Size.cx = 0;
						}
						else
						{
							ABC abc;
							iRes = GetCharABCWidthsW(hdc,k,k,&abc);

							// I have commented out the assert below,
							// because when the function above is called for
							// the first time, it seems to always
							// return 0, even though it fills the abc
							// structure with reasonable values,
							// Tomas, June 22, 2003
							// UT_ASSERT( iRes );
#ifdef DEBUG
							if(!iRes)
							{
								iErrorCode = GetLastError();
							}
#endif

							if(iOver == UT_OVERSTRIKING_LEFT)
							{
								UT_ASSERT( abc.abcB <  GR_OC_MAX_WIDTH);
								Size.cx = abc.abcB | GR_OC_LEFT_FLUSHED;
							}
							else
							{
								Size.cx = abc.abcB;
								Size.cx = -Size.cx;
							}
						}
					}
				
#ifdef DEBUG
					if(iErrorCode)
					{
						LPVOID lpMsgBuf;
						FormatMessageW( 
									  FORMAT_MESSAGE_ALLOCATE_BUFFER | 
									  FORMAT_MESSAGE_FROM_SYSTEM | 
									  FORMAT_MESSAGE_IGNORE_INSERTS,
									  NULL,
									  iErrorCode,
									  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
									  (LPWSTR) &lpMsgBuf,
									  0,
									  NULL 
									  );
						// Process any inserts in lpMsgBuf.
						// ...
						// Display the string.
						//MessageBox( NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION );
						UT_DEBUGMSG(("char width error: %s\n", lpMsgBuf));
						// Free the buffer.
						LocalFree( lpMsgBuf );
					}
#endif
					setWidth(k,Size.cx);
					xxx_UT_DEBUGMSG(("gr_Win32Graphics::getCharWidths: 0x%x: Size.cx %d\n", k, Size.cx));
				}
			}
		}
	}
}
Exemple #4
0
/*
 * @implemented
 */
DWORD
WINAPI
LpkGetCharacterPlacement(
    HDC hdc,
    LPCWSTR lpString,
    INT uCount,
    INT nMaxExtent,
    LPGCP_RESULTSW lpResults,
    DWORD dwFlags,
    DWORD dwUnused)
{
    LPWORD lpGlyphs = NULL;
    SIZE size;
    DWORD ret = 0;
    UINT nSet, i;
    INT cGlyphs;

    UNREFERENCED_PARAMETER(dwUnused);

    /* Sanity check (most likely a direct call) */
    if (!(dwFlags & GCP_REORDER))
       return GetCharacterPlacementW(hdc, lpString, uCount, nMaxExtent, lpResults, dwFlags);

    nSet = (UINT)uCount;
    if (nSet > lpResults->nGlyphs)
        nSet = lpResults->nGlyphs;

    BIDI_Reorder(hdc, lpString, uCount, dwFlags, WINE_GCPW_FORCE_LTR, lpResults->lpOutString,
                 nSet, lpResults->lpOrder, &lpGlyphs, &cGlyphs);

    lpResults->nGlyphs = (UINT)cGlyphs;

    if (lpResults->lpGlyphs)
        wcscpy(lpResults->lpGlyphs, lpGlyphs);

    if (lpResults->lpDx && !(dwFlags & GCP_GLYPHSHAPE))
    {
        int c;
        for (i = 0; i < nSet; i++)
        {
            if (GetCharWidth32W(hdc, lpResults->lpOutString[i], lpResults->lpOutString[i], &c))
                lpResults->lpDx[i] = c;
        }
    }

    /* If glyph shaping was requested */
    else if (lpResults->lpDx && (dwFlags & GCP_GLYPHSHAPE))
    {
        int c;

        if (lpResults->lpGlyphs)
        {
            for (i = 0; i < lpResults->nGlyphs; i++)
            {
                if (GetCharWidth32W(hdc, lpGlyphs[i], lpGlyphs[i], &c))
                    lpResults->lpDx[i] = c;
            }
        }
    }

    /* FIXME: Currently not bidi compliant! */
    if (lpResults->lpCaretPos)
    {
        int pos = 0;

        lpResults->lpCaretPos[0] = 0;
        for (i = 1; i < nSet; i++)
        {
            if (GetTextExtentPoint32W(hdc, &(lpString[i - 1]), 1, &size))
                lpResults->lpCaretPos[i] = (pos += size.cx);
        }
    }

    if (GetTextExtentPoint32W(hdc, lpString, uCount, &size))
        ret = MAKELONG(size.cx, size.cy);

    HeapFree(GetProcessHeap(), 0, lpGlyphs);

    return ret;
}