AffineTransform::scale and Font


#1

Hi,

I’m quite a newbie to Juce.
I’m using AffineTransform::scale and I get different results for fonts and for vectorial graphics:
actually I’m using a music font and the music glyphs are placed on a 5 lines staff at the correct position but the glyphs are 2.5 times smaller than expected. The same using a native device (Quartz for example on Mac OS) and native fonts gives me correct results.
Note also that scaling works for the text font, I’ve the problem only with the music font.
I’m probably doing something wrong but what? or there is a problem with my music font (which works correctly on Mac OS, linux and windows using native devices)
Any idea ?

Dominique

I’ve attached an example of what I get.
[attachment=0]jucescale.png[/attachment]


#2

Interesting… Are you sure you’re not scaling the font height as well as changing the transform? I’m pretty sure that if you just change the transform, any font heights drawn inside it will be transformed correctly…


#3

Actually what I do is the following:

  AffineTransform transform = AffineTransform::scale (fXScale, fYScale);
  fGraphics->addTransform (transform);

where fGraphics is a juce::Graphics
How could I change the font height only? and why only the music font could be affected?
Note that with the previous attached example, only the note heads, sharps, flats and clefs are glyphs. The remaining is vectorial graphics or text font.


#4

Weird! Sounds like it’s your music font that’s doing something strange then… Some fonts contain hacks and tricks to make them behave in special ways - perhaps this one will only work at certain sizes? Certainly if other fonts behave correctly and this one doesn’t, it sounds like you need a more sensible font!

Something to try might be to make your component use the software rendering engine, rather than the CoreGraphics engine, because that renders fonts with a different method, and see what difference that makes.

You could also get the font glyphs directly using Typeface::getOutlineForGlyph and render them as paths.


#5

[quote=“jules”]
Weird! Sounds like it’s your music font that’s doing something strange then… Some fonts contain hacks and tricks to make them behave in special ways - perhaps this one will only work at certain sizes? Certainly if other fonts behave correctly and this one doesn’t, it sounds like you need a more sensible font![/quote]
It’s a true type font, edited using fontforge. I’ve normalized the Em size to 1024 (a power of 2, on recommendation from fontforge) to see if it makes a difference, but it doesn’t :frowning:

How can I do that? Do you mean “CoreGraphics” for Mac OS native rendering and “software rendering” for juce rendering? Is there a switch somewhere?

[quote]
You could also get the font glyphs directly using Typeface::getOutlineForGlyph and render them as paths.[/quote]

Thanks for the tip. I’ll try that but it requires a bit more coding because the juce font is embedded in an abstract object and for the moment, I don’t have access to the Typeface.


#6

see ComponentPeer::setCurrentRenderingEngine()


#7

Thanks for your help.
I’ve tried the software rendering engine… but I get the same results.
I’ve also make a test program to isolate the problem: a simple juce application with a MainWindow including a component derived only to overload the paint method.

void TestComponent::paint (Graphics& g)
{
	Font guido("Guido2", 200, 0);
	Font times("Times", 75, 0);

	g.addTransform (AffineTransform::scale (0.350638, 0.350638));
	g.setFont(times); 
	g.drawSingleLineText ("This is the times font", 40, 80);
	g.setFont(guido); 
	g.drawSingleLineText ("Xq&?", 40, 260);
	g.drawTextAsPath ("Xq&?", AffineTransform::translation(240,260));

The music font is “Guido2”. The font sizes are large but everything is scaled down. I tried also to render the text as path (drawTextAsPath)… but again, no change. I also tried using the glyphs outline and to render as a path… no change :frowning:
For the moment, my conclusion is that my font has something special that prevents correct scaling.


#8

Why not convert the font to a juce custom font, and embed that in your app? See CustomTypeface::writeToStream.

That’ll definitely store it as just a set of paths, and also avoids the hassle of having to install the font on your user’s machines.


#9

[quote=“jules”]Why not convert the font to a juce custom font, and embed that in your app? See CustomTypeface::writeToStream.
That’ll definitely store it as just a set of paths, and also avoids the hassle of having to install the font on your user’s machines.[/quote]

I’m not sure it’ll solve the scaling problem but anyway it’s a good idea (and the scaling issue could be handle differently).
How does it compares to svg fonts?


#10

This occurs with no transformation. Just choose any music font and draw a few characters. They are very small. I have tried this in several music fonts. Try “Opus” and you’ll see. PLEASE fix this.


#11

I just ran the juce demo fonts page, and looked at the Opus fonts, and they all scale just fine when I change the size. That’s on OSX, are you saying it doesn’t work the same in Windows?


#12

Here is what I get on a Mac an the same thing happens on a PC.

[attachment=0]Opus Font Test.png[/attachment]


#13

The font height in juce is the entire height, not just the ascender height, so there’s no point in comparing those two values in a font like this which has a lot of space for descenders.

But the reason I looked into this is because you originally said the font doesn’t scale when you change its size… But it does scale, as you can see if you wiggle the size slider in the demo!


#14

Sorry, I didn’t look at exactly who had said what. I think it’s exaggerating to call this a “major” problem, isn’t it? For a given font the ratio will always be the same, just figure out what the magic number is that makes it the size you want it, and multiply the height by that.


#15

Major problem might be exaggeration, but how are we to know that a particular font needs the magic number? Shouldn’t this be handled by the juce font routines. Yes we can have a list of known music fonts, but any new music fonts will be missed. When I stated above that the symbols become too think, I was using drawSingleLineText. I tested it with drawText and they look fine.

Finally I would deeply appreciate a drawCharAt( int theChar, int x,int y ). No other parameters are need. If you think about music programs or programs that draw symbols from a font, this would be the way to do it.


#16

Ok, I didn’t realise that you’re using fonts that all have some kind of standard size. Not sure what to suggest there… I can’t change the way the heights are interpreted without breaking everyone else’s apps. To use the OS size directly isn’t hard, but would involve some kind of extra hooks and options deep in the native code to expose a new way of creating a font. I’ll ponder it.


#17

Thanks and I think I can get around the problem. While on the Opus font subject, how do I draw characters 128-160 on the screen for the Opus Metronome font. You answered this before with the following type of code, but it does not display characters 128-160.

int x = 100;
int y = 100;
		
for ( int i = 128; i < 160; i++, x += 20 )
{
    String s (String::charToString (i));
    g.drawMultiLineText( s, x, y, 1000 );
}

Thank you for taking the time to answer.


#18

That code will certainly display characters over 128 if the font contains them. There’s no problem I know about involving extended characters.

BTW you might want to use a GlyphArrangement directly, rather than using the normal Graphics text methods.


#19

Sorry but I didn’t ever call this a major problem (despite what your quote might suggest). I’m using the “magic ratio number” solution and that’s a satisfying solution to me. For more robustness, I’m still looking for a solution to embed my music font as a juce custom font. CustomTypeface::writeToStream writes binary data which is not very convenient for inclusion into source code, but maybe I’m missing an obvious point. :?: :idea:


#20

I think I was confusing the various posts on this thread…

Surely it’s very convenient indeed if you add it as a binary resource using the introjucer or binarybuilder?