About the Chinese font

Discuss about anything related to the Irrlicht Engine, or read announcements about any significant features or usage changes.
Post Reply
ttom
Posts: 43
Joined: Tue Aug 26, 2003 3:43 am
Location: Taiwan

About the Chinese font

Post by ttom »

Dear folk:
I modify the CGUIFont.h and the CGUIFont.cpp let they can use the
D3DFont to draw the chinese. but I got a problem when doing the GUI stuff.
So anyone has some idea.
ttom
ps:sorry for my english.
ps:if anyone need the source code . I will post it lately.
wq

Post by wq »

would u plz post the source code?
ttom
Posts: 43
Joined: Tue Aug 26, 2003 3:43 am
Location: Taiwan

Post by ttom »

wq wrote:would u plz post the source code?
Here is the CGUIFont.h

Code: Select all

// Copyright (C) 2002-2003 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h

#ifndef __C_GUI_FONT_H_INCLUDED__
#define __C_GUI_FONT_H_INCLUDED__

#include "../include/IGUIFont.h"
#include "../include/irrString.h"
#include "../include/IVideoDriver.h"
#include "../include/array.h"

namespace irr
{
namespace gui
{

class CGUIFont : public IGUIFont
{
public:

	//! constructor
	CGUIFont(video::IVideoDriver* Driver);

	//! destructor
	virtual ~CGUIFont();

	//! loads a font file
	bool load(const c8* filename);

	//! loads a font file
	bool load(io::IReadFile* file);

	//! draws an text and clips it to the specified rectangle if wanted
	virtual void draw(const wchar_t* text, const core::rect<s32>& position, video::SColor color, bool hcenter=false, bool vcenter=false, const core::rect<s32>* clip=0);

	//! returns the dimension of a text
	virtual core::dimension2d<s32> getDimension(const wchar_t* text);

private:

	//! load & prepare font from ITexture
	bool loadTexture(video::ITexture* texture);

	video::IVideoDriver* Driver;
	core::array< core::rect<s32> > Positions;
	video::ITexture* Texture;
	s32 WrongCharacter;

	// This is for the D3D font
	// The Font object
	ID3DXFont        *pD3DFont;
	IDirect3DDevice8 *pD3DDevice;
	LOGFONT          LogFont;
    

};

} // end namespace gui
} // end namespace irr

#endif
Last edited by ttom on Mon Feb 09, 2004 2:09 am, edited 1 time in total.
ttom
Posts: 43
Joined: Tue Aug 26, 2003 3:43 am
Location: Taiwan

Post by ttom »

wq wrote:would u plz post the source code?
Here is the CGUIFont.cpp

Code: Select all

// Copyright (C) 2002-2003 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h

#include "CGUIFont.h"
#include "../include/os.h"

namespace irr
{
namespace gui
{

//! constructor
CGUIFont::CGUIFont(video::IVideoDriver* driver)
: Driver(driver), Positions(382), Texture(0), WrongCharacter(0)
{
	#ifdef _DEBUG
	setDebugName("CGUIFont");
	#endif

	if (Driver)
		Driver->grab();
	// The Font object
	pD3DFont=NULL;
	pD3DDevice=NULL;

    
    // Create the font
	ZeroMemory(&LogFont, sizeof(LogFont));
	strcpy(LogFont.lfFaceName, "Arial Unicode MS");
	LogFont.lfHeight = -16;
	pD3DDevice=driver->GetD3DDevice();
	D3DXCreateFontIndirect(pD3DDevice, &LogFont, &pD3DFont);

    

	
}



//! destructor
CGUIFont::~CGUIFont()
{
	if (Driver)
		Driver->drop();

	if (Texture)
		Texture->drop();
		
	// Release D3D font
	if(pD3DFont!= NULL)	
	    pD3DFont->Release();
    
}



//! loads a font file
bool CGUIFont::load(io::IReadFile* file)
{
	if (!Driver)
		return false;

	return loadTexture(Driver->getTexture(file));
}


//! loads a font file
bool CGUIFont::load(const c8* filename)
{
	if (!Driver)
		return false;

	return loadTexture(Driver->getTexture(filename));
}



//! load & prepare font from ITexture
bool CGUIFont::loadTexture(video::ITexture* texture)
{
	if (!texture)
		return false;

	Texture = texture;
	Texture->grab();

	s32 pitch = texture->getPitch();
	core::dimension2d<s32> size = texture->getDimension();

	s32 lowerRightPostions = 0;

	if (texture->getColorFormat() == video::EHCF_R5G5B5)
	{
        s16* p = (s16*)texture->lock();
		if (!p)
		{
			os::Warning::print("Could not lock texture while preparing texture for a font.");
			return false;
		}

		s16 colorTopLeft = *p;
		s16 colorLowerRight = *(p+1);
		s16 colorBackGround = *(p+2);
		s16 colorBackGroundWithAlphaTrue = (0x1<<15) | (~(0x1<<15) & colorBackGround);
		s16 colorBackGroundWithAlphaFalse = (0x0<<15) | (~(0x1<<15) & colorBackGround);
		s16 colorFont = (0x1<<15) | (~(0x1<<15) & video::RGB16(255,255,255));

		*(p+1) = colorBackGround;
		*(p+2) = colorBackGround;

		// start parsing

		core::position2d<s32> pos(0,0);

		c8* row = (c8*)((void*)p);

		for (pos.Y=0; pos.Y<size.Height; ++pos.Y)
		{
			p = (s16*)((void*)row);

			for (pos.X=0; pos.X<size.Width; ++pos.X)
			{
				if (*p == colorTopLeft)
				{
					*p = colorBackGroundWithAlphaFalse;
					Positions.push_back(core::rect<s32>(pos, pos));
				}
				else
				if (*p == colorLowerRight)
				{
					if (Positions.size()<=(u32)lowerRightPostions)
					{
						texture->unlock();
						return false;
					}

					*p = colorBackGroundWithAlphaFalse;
					Positions[lowerRightPostions].LowerRightCorner = pos;
					++lowerRightPostions;
				}
				else 
				if (*p == colorBackGround)
					*p = colorBackGroundWithAlphaFalse;
				else
					*p = colorFont;


				++p;
			}

			row += pitch;
		}

   
		// Positions parsed.

		texture->unlock();

		// output warnings
		if (!lowerRightPostions || !Positions.size())
			os::Warning::print("The amount of upper corner pixels or lower corner pixels is == 0, font file may be corrupted.");
		else
		if (lowerRightPostions != (s32)Positions.size())
			os::Warning::print("The amount of upper corner pixels and the lower corner pixels is not equal, font file may be corrupted.");

	}

	if (Positions.size() > 127)
		WrongCharacter = 127;

	return (!Positions.empty() && lowerRightPostions);
}


//! returns the dimension of a text
core::dimension2d<s32> CGUIFont::getDimension(const wchar_t* text)
{
    if(wcslen(text)==1)
    {
        core::dimension2d<s32> dim(0, Positions[0].getHeight());
        
        u32 n;
        
        for(const wchar_t* p = text; *p; ++p)
        {
            n = (*p) - 32;
            if ( n > Positions.size())
                n = WrongCharacter;
            
            dim.Width += Positions[n].getWidth();
        }
        
        return dim;
    }else{
    
    HDC hDC;
    SIZE size_01;
    int iret;
    hDC=GetDC(NULL);
    SetTextJustification(hDC,0,0);
    iret = GetTextExtentPoint32W(
        hDC,			// handle to device context
        text,		// pointer to text string
        wcslen(text),  // number of characters in string
        &size_01		// pointer to structure for string size
        );
    ReleaseDC(NULL,hDC);
    //core::dimension2d<s32> dim(size_01.cx+LogFont.lfWidth, (size_01.cy+2));
    core::dimension2d<s32> dim(size_01.cx, size_01.cy);
    return dim;
    }
    /*
	core::dimension2d<s32> dim(0, Positions[0].getHeight());

	u32 n;

	for(const wchar_t* p = text; *p; ++p)
	{
		n = (*p) - 32;
		if ( n > Positions.size())
			n = WrongCharacter;

		dim.Width += Positions[n].getWidth();
	}

	return dim;
    */
}



//! draws an text and clips it to the specified rectangle if wanted
void CGUIFont::draw(const wchar_t* text, const core::rect<s32>& position, video::SColor color, bool hcenter, bool vcenter, const core::rect<s32>* clip)
{
	if (!Driver)
		return;
//----------------------------------------------------------------------
  	if(!pD3DFont)
    	return;
//    core::position2d<s32> offset = position.UpperLeftCorner;
//    core::position2d<s32> textDimension;
    
//    core::dimension2d<s32> dim=getDimension(text);
//    textDimension.X=dim.Width;
//    textDimension.Y=dim.Height;
//    RECT Rect = { offset.X,offset.Y,offset.X+textDimension.X+16,offset.Y+textDimension.Y+2 };
//    pD3DFont->Begin();
    //g_pFont->DrawText("中文測式Programming is Fun!", -1, &Rect, 0/*DT_CENTER | DT_VCENTER*/, 0xFFFFFFFF);
    //pD3DFont->DrawTextW(L"中文測式Programming is Fun!", -1, &Rect, 0/*DT_CENTER | DT_VCENTER*/, 0xFFFFFFFF);
//    pD3DFont->DrawTextW(text, -1, &Rect, 0/*DT_CENTER | DT_VCENTER*/, 0xFFFFFFFF);
//    pD3DFont->End();	
    
//-------------------------------------------------    
/*
	core::dimension2d<s32> textDimension;
	core::position2d<s32> offset = position.UpperLeftCorner;
    textDimension = getDimension(text);
    if (hcenter || vcenter)
	{
		textDimension = getDimension(text);

		if (hcenter)
			offset.X = ((position.getWidth() - textDimension.Width)>>1) + offset.X;

		if (vcenter)
			offset.Y = ((position.getHeight() - textDimension.Height)>>1) + offset.Y;
	}

	u32 n;
	
	while(*text)
	{
		n = (*text) - 32;
		if ( n > Positions.size())
			n = WrongCharacter;

		Driver->draw2DImage(Texture, offset, Positions[n], clip, color, true);
        
		offset.X += Positions[n].getWidth();

		++text;
	}
*/
    if(wcslen(text)< 2)
    {
        core::dimension2d<s32> textDimension;
        core::position2d<s32> offset = position.UpperLeftCorner;
        textDimension = getDimension(text);
        if (hcenter || vcenter)
        {
            textDimension = getDimension(text);
            
            if (hcenter)
                offset.X = ((position.getWidth() - textDimension.Width)>>1) + offset.X;
            
            if (vcenter)
                offset.Y = ((position.getHeight() - textDimension.Height)>>1) + offset.Y;
        }

        u32 n;
        
        while(*text)
        {
            n = (*text) - 32;
            if ( n > Positions.size())
                n = WrongCharacter;
            
            Driver->draw2DImage(Texture, offset, Positions[n], clip, color, true);
            
            offset.X += Positions[n].getWidth();
            
            ++text;
        }
    }else{

        core::dimension2d<s32> textDimension;
        core::position2d<s32> offset = position.UpperLeftCorner;
        textDimension = getDimension(text);
        UINT uFormat=0;
        if (hcenter || vcenter)
        {
            if (hcenter) 
            {
                uFormat|=DT_CENTER;
                offset.X = ((position.getWidth() - textDimension.Width)>>1) + offset.X;
                
            }
            if (vcenter) 
            {
                uFormat|=DT_VCENTER;
                offset.Y = ((position.getHeight() - textDimension.Height)>>1) + offset.Y;
            }

        }
        //RECT Rect = { offset.X,offset.Y,offset.X+textDimension.Width+(-LogFont.lfHeight),offset.Y+textDimension.Height+textDimension.Height/3};
        
        
        RECT Rect = { position.UpperLeftCorner.X,position.UpperLeftCorner.Y,position.LowerRightCorner.X,position.LowerRightCorner.Y};
        pD3DFont->Begin();
        //g_pFont->DrawText("中文測式Programming is Fun!", -1, &Rect, 0/*DT_CENTER | DT_VCENTER*/, 0xFFFFFFFF);
        //pD3DFont->DrawTextW(L"中文測式Programming is Fun!", -1, &Rect, 0/*DT_CENTER | DT_VCENTER*/, 0xFFFFFFFF);
        pD3DFont->DrawTextW(text, -1, &Rect, uFormat, color.color);
        pD3DFont->End();	
        
    }
}


} // end namespace gui
} // end namespace irr
U need to modify the class of device to get the d3d object or do your way
Post Reply