TrueType font Support by FreeType Library

A forum to store posts deemed exceptionally wise and useful
Post Reply
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Post by CuteAlien »

Jookia wrote:I don't know. :S
Well, make it global for a test. If it does no longer crash then that is probably your problem.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Jookia
Posts: 170
Joined: Wed Nov 19, 2008 1:11 am

Post by Jookia »

When face is global it still crashes.
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Post by CuteAlien »

You should also create font with new.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Jookia
Posts: 170
Joined: Wed Nov 19, 2008 1:11 am

Post by Jookia »

Aha, I didn't actually have a file there.
Jookia
Posts: 170
Joined: Wed Nov 19, 2008 1:11 am

Post by Jookia »

I've compiled FreeType into my Irrlicht 1.5 library static-linked library. The only files from the FreeType libraries that I've discared is ftrandom.c and ftmac.c.

In infutil.h I had to change 'local uInt inflate_mask[17];' to 'local const uInt inflate_mask[17];' due to type errors.

Now, I had to define these for the FreeType library..

FT2_BUILD_LIBRARY
FT_OPTION_AUTOFIT2

Okay, with that out of the road it compiles fine. I added..
Cristian wrote:here you go, now it works in irrlicht 1.4. That is, if anyone wants it.
http://rapidshare.com/files/100444358/I ... e.zip.html
to the engine and then changed the part of CGUIEnvironment getFont() from

Code: Select all

	if (!ifont)
	{
		CGUIFont* font = new CGUIFont(this, f.Filename.c_str());
		ifont = (IGUIFont*)font;
		if (!font->load(f.Filename.c_str()))
		{
			font->drop();
			return 0;
		}
	}
to

Code: Select all

	if (!ifont)
	{
		#ifdef _IRR_COMPILE_WITH_TTF_LOADER_
		CGUITTFace face;
		
		if(face.load(filename) == true)
		{
			CGUITTFont* font = new CGUITTFont(Driver);
			
			if(font->attach(&face, _IRR_DEFAULT_FONT_SIZE_) == false)
			{
				font->drop();
				face.drop();
				return 0;
			}
			else
				ifont = (IGUIFont*)font;
		}
		else
		{
			face.drop();
		#endif
		
		CGUIFont* font = new CGUIFont(this, f.Filename.c_str());
		ifont = (IGUIFont*)font;
		if (!font->load(f.Filename.c_str()))
		{
			font->drop();
			return 0;
		}
		
		#ifdef _IRR_COMPILE_WITH_TTF_LOADER_
		}
		#endif
	}
Everything is fine until in my project using the modified engine..

Code: Select all

	gui::IGUIFont* font = guiEnv->getFont("font.ttf");
	
	guiEnv->getSkin()->setFont(font);
Now, that's all fine and dandy. UNTIL I draw some GUI elements. It crashes.
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Post by CuteAlien »

Your problem is that you don't understand the difference between variables on the stack and on the heap yet. Read up on that - it is essential when programming c++ all the time.
Once you understand that it will be obvious why putting "face" on the stack makes no sense here and also why calling .drop() for it is a very bad idea.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Jookia
Posts: 170
Joined: Wed Nov 19, 2008 1:11 am

Post by Jookia »

Variables on the stack are ones that aren't referenced to and are only there temporary, like

Code: Select all

function blah()
{
int = 15;
}
but variables on the heap are like

Code: Select all

function blah()
{
myObject object;
object.int = new int;
}
where it won't be deleted unless you do so, because it's being referenced.

Correct me if I'm wrong.
Sylence
Posts: 725
Joined: Sat Mar 03, 2007 9:01 pm
Location: Germany
Contact:

Post by Sylence »

Jookia wrote:where it won't be deleted unless you do so, because it's being referenced
No. C++ doesn't know anything about reference counting. Variables on the heap are deleted when you delete them. No sooner or later.
Software documentation is like sex. If it's good you want more. If it's bad it's better than nothing.
Jookia
Posts: 170
Joined: Wed Nov 19, 2008 1:11 am

Post by Jookia »

Yeah.
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Post by CuteAlien »

References have nothing to do at all with this. In c++ you as programmer are responsible for making sure that your references and pointers point to valid memory, the language will not do that for you (like for example in java). Which is why it is so important to understand the different types of memory.

In short: A stack is a very simple structure where you only can put and remove stuff on top (but still read them all). Stack variables have a known size at compile-time and are pushed on stack when the line where they are defined is executed. Stack variables are removed at the end of the scope in which they have been defined. Which most often means at the next associated }. And as only the top element can be modified in a stack it means they are removed in reverse order. After destruction that memory is no longer available so you as programmer have to make sure that there are no longer any pointers referencing to that. Stack memory is allocated in a part of your memory which is reserved for the stack (how exactly that is done is up to your compiler&OS).

Heap is just memory that can be basically anywhere except in the part which is reserved for stack memory. Which memory you get exactly is once more up to your compiler & OS. It is explicitly reserved and stays valid until you explicitly free the reserved block. Which is done with malloc/free in c and can additionally be done with new/delete in c++. It can have any size and that size is decided at runtime (when calling new MyClass the size is automatically the number of bytes which MyClass does need for all it's variables).

Because it can be cumbersome counting how many pointers are still referencing some part of memory Irrlicht (like many other libs) has added a mechanism on top of that which is the IReferenceCounted interface from which nearly all Irrlicht classes are derived. IReferenceCounted is initialized with 1 on new and has an internal counter of the pointers which grab()'ed and drop()'ed that memory and calls delete when the counter reaches 0. That interface makes *only* sense for heap memory therefore, because calling delete for stack memory is _always_ wrong.

So in your case 2 big errors: First you pass a pointer to a stack object (face) to a variable on heap (font). The stack memory is automatically destroyed at the end of scope and your heap-object contains now an invalid pointer which will crash the next time it's used when you are lucky and just produce crazy results when you are unlucky.
Second you call .drop() for a stack object which is always wrong. Really always - same as calling grab().

And lastly just a reminder to make sure you understand why references/pointers have nothing to do with the way memory is allocated. You can have pointers to both types of memory and there is basically no way to discern them. You can also pass the content of a pointer as reference so references can also contain both types of memory. Which means - only you can know what type of memory is used - c++ won't help you there. Which is why it is so important always to know what you are dealing with. Actually that also means that .grab() and .drop() are always wrong because a '.' always means you are dealing with stack while ->grab() and ->drop() can be right if you have heap memory but can also be wrong when you deal with stack memory.

Edit: Ok, lets also add an example:

Code: Select all

void fun()
{
  // reserve an "int-pointer" on stack.
  int * c = 0;          

  // reserve an "int-pointer" on stack.
  // reserve an "int" on heap
  // put the address of that heap-memory into the int-pointer (you do that to help yourself, not for the C++ memory-management which does not care at all about you doing that)
  int * x= new int;


  // release the heap memory for an "int" for which you have the address in x;
  delete x;

  // just save to remind yourself that x contains no longer a useful value.
  x = 0;

  // new scope
  {
    // reserve an "int-pointer" on stack.
    // reserve an "int" on heap
    // put the address of that heap-memory into the int-pointer.
    int * y = new int;

    // put the address of that heap-memory which is in "y" also into another int-pointer called "c". C++ memory-management does not care about you doing that.
    c = y;

     // reserve an "int" on the stack.
    int k = 1;
  
    // remember that "int-pointer" x is still valid memory on stack, so we can still fill it with values.
    x = &k; 

   // But then again - k will be invalid in a second - so uh - bad idea to keep that pointer around, better make sure we forget about it. So next line for yourself - not for compiler.
    x = 0;

    // auto-release memory on stack for "int" with name "k"
    // auto-release memory on stack for "int-pointer" y (but not for the heap-memory for which is also has a pointer, c++ does not care about that) 
  }


  // release the heap memory for an "int" for which you have the address in c (remember it was created in y).
  // The order in which you release heap-memory does not matter by the way, but still it is often useful also to use reverse-order of creating.
  delete c;

  // Wrong, you don't need that, x contains no good value here. But wouldn't crash because x is 0 and delete 0 does nothing except cost a little time. 
  // But if x would still contain k then this would crash badly because you would try to release stack memory.
 //  delete x; 

  // auto-release memory on stack for "int-pointer" x (but not it's content).
  // auto-release memory on stack for "int-pointer" c (but not it's content).
}
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Jookia
Posts: 170
Joined: Wed Nov 19, 2008 1:11 am

Post by Jookia »

Thanks for explaining, man.
Jookia
Posts: 170
Joined: Wed Nov 19, 2008 1:11 am

Post by Jookia »

How would I go about loading from an IReadFile or zip files?
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Post by CuteAlien »

Jookia wrote:How would I go about loading from an IReadFile or zip files?
Do you talk about font-files or this a complete off-topic question which does not belong in this thread?
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Jookia
Posts: 170
Joined: Wed Nov 19, 2008 1:11 am

Post by Jookia »

CuteAlien wrote:
Jookia wrote:How would I go about loading from an IReadFile or zip files?
Do you talk about font-files or this a complete off-topic question which does not belong in this thread?
I thought posting in the font thread that relates to my question would kind of give it away.
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Post by CuteAlien »

Jookia wrote:
CuteAlien wrote:
Jookia wrote:How would I go about loading from an IReadFile or zip files?
Do you talk about font-files or this a complete off-topic question which does not belong in this thread?
I thought posting in the font thread that relates to my question would kind of give it away.
Uhm, well - making us guess is always a little tricky in text-only-communication. Actually writing down what you are trying to do and writing which problems you have works just better :-)
I think for zip's you just have to add the zip as archive: http://irrlicht.sourceforge.net/docu/cl ... dcd41f681f

Loading as IReadFile seems not to be supported for fonts so far (maybe something which should be added as it seems to exist for other structures for some reason), so if you have an IReadFile but no filename (?) you probably have to call getFileName () on the IReadFile.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Post Reply