How do you declare a static juce::Image or juce::Font?


#1

If I do this in my plugin somewhere, say, the the constructor of some class…

tekoBoldFont = Font(Typeface::createSystemTypefaceFor(BinaryData::TekBold_ttf, BinaryData::TekoBold_ttfSize));

…doesn’t that mean every instance of my class will load the same font taking up more and more unecessary memory for this font? I will have hundreds of images and a handful of fonts for my plugin. Doesn’t that mean every plugin instance will use up more memory for the same images and fonts?

So I was trying to create static Image / static Font so that every plugin instance refers to the same object, I also tried extern keyword, this all creates runtime errors.


#2

For Images I can clarify, that the Image class is a wrapper around the shared image data. Only if you call Image::createCopy(), it will have it’s own pixel data.
Also there is the ImageCache, that sits between the loading and usage.

Also the Font object is just a state to use. The heavy weight is in the Typeface. The static method Typeface::clearTypefaceCache() suggests, there is also a caching mechanism in place and the Typeface itself is a ReferenceCountedObject. But I haven’t checked the sources.

So you can simply use a Typeface and Images from the ImageCache, the system takes care of caching. You don’t have to reinvent anything on top of that.


#3

You probably want to have an object holding all the shared typefaces and images - the easiest way to manage that is with SharedResourcePointer, which takes care of creating/deleting a singleton object for you.


#4

So, like this?


#5

maybe add some of this to that:

class Resources
{
   enum class FontTypes
   {
       TekoBold,
       TekoMedium, 
       //etc..
   };  

   Font& getFont( FontTypes fontType )
   {
       switch( fontType )
       {
            case TekoBold: return tekoBoldFont;
            case TekoMedium: return tekoMediumFont;
            //etc
       }
   }
};

then, hide the fonts as private members.


#6

oh, because I need to use the & operator to ensure no copy?


#7

sure, but also to provide a nice interface for what fonts are available:

11%20PM


#8

@Elan_Hickler Yep, that’s spot-on.

I wouldn’t confuse things by trying to hide them behind enums, just keep it simple like you did.


#9

one issue is that if you don’t copy the font then you can’t set font height for individual cases. But fonts are small. I’ll use copy constructor when getting a font resource out of my resource class.


#10

Yes, that’s what I meant, when I wrote:

Makes perfect sense to copy the Font object as a stack variable.
If you look in the sources at Font, you find there is only a member of SharedFontInternal, which gets the typeface from the TypeFaceCache.


#11

What about SVGs? Drawing complex SVGs could take a bit of CPU. How would you render an SVG for the Image class?


#12

Something like this:

ScopedPointer<Drawable> svg = Drawable::createFromImageData (data, size);
Rectangle<float> svgBounds (svg->getDrawableBounds());
Image image (Image::RGB, svgBounds.getWidth (), svgBounds.getHeight (), true);
Graphics g (image);
svg->draw (g, 1.0f);

#13

FWIW I wouldn’t rush into the idea of rendering SVGs to bitmaps unless you profile it and actually measure it being significantly quicker. Depending on the SVG and the rendering engine, it’s very often quicker to just draw it with vector graphics.