Page 8 of 13

Posted: Wed Jul 08, 2009 2:02 am
by Jookia
I'm talking about TrueType fonts, since the TrueType library doesn't want to load from zips.

Posted: Wed Jul 08, 2009 2:22 am
by CuteAlien
OK, I get it now. This is rather hard to do because the loading of those freetype-fonts is happening outside of Irrlicht so you can't just use the comfortable Irrlicht archives. Basically you would have to write a input stream for the freetype library which passes on the content of an Irrlicht archive in some way. Maybe also FT_New_Memory_Face could be used in combination with a MemoryReadFile from Irrlicht somehow. But can't help you there - this is something where I would myself have to invest at least a full day (maybe more) to do that.

Posted: Wed Jul 08, 2009 3:40 am
by Jookia
Well it's kind of essential for this wrapper.

Posted: Wed Jul 08, 2009 5:54 am
by CuteAlien
Jookia wrote:Well it's kind of essential for this wrapper.
Why essential? Just don't put fonts in a zip. This is something that might be solved one day, but there's a lot of work to be done before that makes sense (like cleaning up the font-factory patch enough to include it in the engine as first step).

But well, you might try doing it anyway - I haven't really looked into this yet, but it's probably 2 steps: First load the font from zip into a memory file. Then change the tt-font class in a way that allows it to accept memory additional to a filename. Truetype allows using fonts from memory somehow with FT_New_Memory_Face.

Or maybe someone else has fun doing that - it would certainly be a nice addition.

Posted: Wed Jul 08, 2009 10:46 am
by Jookia
Well, right now you have to type in the full directory name anyway, it doesn't search folder archives OR the current directory. That's FreeType library stuff.

Posted: Fri Jul 10, 2009 7:12 am
by amrit36
hello frnds.. I am compiling Irrlicht1.3 and FREETYPE library.

Everytime i got this ERROR

error C2259: 'irr::gui::CGUITTFont' : cannot instantiate abstract class


help me out of this.

Posted: Fri Jul 10, 2009 7:20 am
by Halifax
amrit36 wrote:hello frnds.. I am compiling Irrlicht1.3 and FREETYPE library.

Everytime i got this ERROR

error C2259: 'irr::gui::CGUITTFont' : cannot instantiate abstract class


help me out of this.
Well, you should definitely update to Irrlicht 1.5, or the SVN. Then you can read up more on the C2259 error here: http://msdn.microsoft.com/en-us/library/zxt206sk.aspx if the problem persists.

Posted: Fri Jul 10, 2009 8:50 am
by amrit36
i have tested the code with Irrlicht1.5 and also i have tried to solve it, still the error. i am using Visual studio 2008.

plz help me out

Posted: Fri Jul 10, 2009 10:42 am
by Halifax
If you follow the link I posted to help you, then you would see the following, "Code declares an instance of an abstract class or structure", with an even more in-depth description, "You cannot instantiate a class or structure with one or more pure virtual functions." If you don't know what pure virtual functions are, then I suggest you learn some more C++.

Now, with that out of the way. Take a look at CGUITTFont; it inherits from IGUIFont. Since we now know what the error stands for, it obviously is not implementing one or more pure virtual functions from IGUIFont. Let's take a look at the IGUIFont documentation and compare it with the interfaces implemented by CGUITTFont.

CGUITTFont only implements IGUIElement::draw(), IGUIElement::getDimension(), and IGUIElement::getCharacterFromPos(). It still requires IGUIElement::getKerningHeight(), IGUIElement::getKerningWidth(), IGUIElement::setKerningHeight(), and IGUIElement::setKerningWidth(), thus making it an abstract base class.

Now that you have all this information, you should be able to fix your problem.

Posted: Fri Jul 10, 2009 12:13 pm
by amrit36
thanks a lot. I have never done C++ programming before. But i have managed to do this. Thank you very much for your support. :P

Posted: Fri Jul 10, 2009 12:39 pm
by Halifax
amrit36 wrote:thanks a lot. I have never done C++ programming before. But i have managed to do this. Thank you very much for your support. :P
No problem, but it's recommended that you know C++ programming before you attempt anything with Irrlicht. It's generally not a fun experience to learn Irrlicht and C++ at the same time.

Posted: Fri Jul 10, 2009 12:50 pm
by amrit36
actually i am having some immediate requirements. so i was testing Irrlicht Engine with freetype rasterizer. well that was really not for fun :? . i think u can understand.

anywayz thanks again.

Posted: Fri Jul 10, 2009 1:29 pm
by Jookia

Code: Select all

bool CGUITTFace::load(io::IReadFile* file)
{
    if ( !library )
    {
        if (FT_Init_FreeType( &library ))
        {
            return	false;
        }
    }
	
	void* buffer;
	
	file->read(&buffer, file->getSize());
	
	// typedef unsigned char  FT_Byte;
	if(FT_New_Memory_Face(library, (FT_Byte*)buffer, sizeof(buffer), 0, &face) == true)
		return false;
	
	//if (FT_New_Face( library,filename,0,&face ))
	//{
	//	return	false;
	//}
	return	true;
}

Code: Select all

IGUIFont* CGUIEnvironment::getFont(const c8* filename, u32 size, bool AA, bool TP)
{
	// search existing font

	SFont f;
	IGUIFont* ifont=0;
	if (!filename)
		f.Filename = "";
	else
		f.Filename = filename;

	f.Filename.make_lower();

	core::stringc oldName = f.Filename;

	f.Filename.append(":");
	f.Filename.append(size);

	s32 index = Fonts.binary_search(f);

	if (index != -1)
	{
		if(Fonts[index].Font->getType() != EGFT_FREETYPE)
			return Fonts[index].Font;
			
		// We have to edit the AA and TP on the
		// TrueType fonts.
		
		CGUITTFont* font = (CGUITTFont*)Fonts[index].Font;
		
		font->AntiAlias = AA;
		font->TransParency = TP;
		
		return (IGUIFont*)font;
	}

	f.Filename = oldName;

	// font doesn't exist, attempt to load it

	// does the file exist?

	if (!FileSystem->existFile(filename))
	{
		os::Printer::log("Could not load font because the file does not exist", f.Filename.c_str(), ELL_ERROR);
		return 0;
	}

	io::IXMLReader *xml = FileSystem->createXMLReader(filename);
	if (xml)
	{
		// this is an XML font, but we need to know what type
		EGUI_FONT_TYPE t = EGFT_CUSTOM;

		bool found=false;
		while(xml->read() && !found)
		{
			if (xml->getNodeType() == io::EXN_ELEMENT)
			{
				if (core::stringw(L"font") == xml->getNodeName())
				{
					if (core::stringw(L"bitmap") == xml->getAttributeValue(L"type"))
					{
						t = EGFT_BITMAP;
						found=true;
					}
					else found=true;
				}
			}
		}

		if (t==EGFT_BITMAP)
		{
			CGUIFont* font = new CGUIFont(this, filename);
			ifont = (IGUIFont*)font;
			// change working directory, for loading textures
			core::stringc workingDir = FileSystem->getWorkingDirectory();
			FileSystem->changeWorkingDirectoryTo(FileSystem->getFileDir(f.Filename).c_str());

			// load the font
			if (!font->load(xml))
			{
				font->drop();
				font  = 0;
				ifont = 0;
			}
			// change working dir back again
			FileSystem->changeWorkingDirectoryTo(workingDir.c_str());
		}
		xml->drop();
	}


	if (!ifont)
	{
		// The FreeType library is great.
		
		core::stringc name = FileSystem->getAbsolutePath(filename);
		
		CGUITTFace* face = new CGUITTFace;
		
		if(FileSystem->existFile(name.c_str()) == true)
		{
			io::IReadFile* file = FileSystem->createAndOpenFile(name.c_str());
			
			if(face->load(file) == true)
			{
				CGUITTFont* font = new CGUITTFont(Driver);
				
				if(font->attach(face, size) == false)
				{
					font->drop();
					face->drop();
					
					return 0;
				}
				else
				{
					font->AntiAlias = AA;
					font->TransParency = TP;
					
					ifont = (IGUIFont*)font;
				}
			}
			else
			{
				face->drop();
				file->drop();
			}
		}
		else
		{
			face->drop();
			
			CGUIFont* font = new CGUIFont(this, f.Filename.c_str());
			ifont = (IGUIFont*)font;
			if (!font->load(f.Filename.c_str()))
			{
				font->drop();
				return 0;
			}
		}
	}

	// add to fonts.

	f.Filename.append(":");
	f.Filename.append(size);

	f.Font = ifont;
	Fonts.push_back(f);

	return ifont;
}

Code: Select all

#include <irrlicht.h>
	using namespace irr;

#define FONT "C:\\Documents and Settings\\Administrator\\My Documents\\My Projects\\C++\\Vox\\PeerState\\bin\\data\\font.ttf"

int main(void)
{
	IrrlichtDevice* device = createDevice(video::EDT_OPENGL, core::dimension2d<s32>(640, 480), 32, false, false, false, 0);
	device->setWindowCaption(core::stringw("PeerState").c_str());
	
	device->getFileSystem()->addFolderFileArchive("data");
	
	video::IVideoDriver* driver  = device->getVideoDriver();
	scene::ISceneManager* smgr   = device->getSceneManager();
	gui::IGUIEnvironment* guiEnv = device->getGUIEnvironment();
	
	guiEnv->getSkin()->setFont(guiEnv->getFont(FONT));
	
	scene::ICameraSceneNode* cam = smgr->addCameraSceneNodeFPS();
	cam->setPosition(core::vector3df(0, 0, 0));
	device->getCursorControl()->setVisible(false);
	
	guiEnv->addStaticText(L"This is an example of <font:font.ttf:18:FF0000>BIG RED TEXT <font:font.ttf:12:000000>and little black text.",
		core::rect<s32>(10,10, 630, 470), true);
	
	int fps = -1;
	core::stringw string;
	
	while(device->run() == true)
	{
		if(driver->getFPS() != fps)
		{
			fps = driver->getFPS();
			
			string = core::stringw("PeerState - ");
			string += fps;
			string += " FPS";
			
			device->setWindowCaption(string.c_str());
		}
		
		driver->beginScene(true, true, video::SColor(255, 128, 25, 25));
		
		smgr->drawAll();
		guiEnv->drawAll();
		
		driver->endScene();
	}
	
	device->drop();
}
Crashes, that's what I have modified.

Posted: Sat Oct 10, 2009 3:04 am
by CuteAlien
Just mentioning that I found another problem - getDimensions didn't always return the correct value as it ignored bearing. But I found not out yet how to really fix that, so I've added some workaround in my code. If you have any texts which are clipped because of that (for example the last line in a message-box often lost lower half of characters) then better update. If you still have trouble with characters after updating then add those characters in CGUIFreetypeFont::attach to the workaround section. As always latest version can be found here: http://www.michaelzeilfelder.de/irrlicht.htm#TrueType

Posted: Mon Nov 09, 2009 9:10 pm
by stefbuet
Could this problem make some characters disapearing randomly when using multiple time the "attach" for different CGUITTFont objects with the same GUITTFace object?

In fact I just ported the version which worked with Irrlicht 1.4.2 to 1.6 and I had to change some things : firstly I added the setInvisibleCharacters function which became virtual in Irrlicht 1.6. I didn't put anything in this function.

I changed also the draw function: in fact the "text" parameter type changed, it was a const core::stringw and it became a const core::stringw&, so I converted the new parameter to the older type to use the same function :

Code: Select all

void CGUITTFont::draw(const core::stringw& text2,.....) {
const wchar_t* text=text2.c_str();
//...........
}
Now when the same GUIFace is attached to some GUIFonts, some characters are invisible and it's randomly :shock:

Maybe the fact that I changed the stringw& to stringw could make characters invisible ?

CuteAlien, is your version working with Irrlicht 1.6?

Thanks,

Stef.