Hi Robert, Thanks for the reply, modifying the Font*::getKerning() seems to be the best solution.
I will cherry-pick your commit until we can upgrade to the lastest version. Regards, Romain Ouabdelkader. 2016-01-12 18:36 GMT+01:00 Robert Osfield <[email protected]>: > Hi Romain, > > Thanks for investigating and characterising this bug. With your > results in mind I've just done a code review of FreeTypeFont.cpp and > Font.cpp and see that design/implementation both assume that kerning > is invariant of font resolution, which you have found it isn't, so > this is most definitely a flaw. > > From my current review the correct way to solve this would seem to be > modify the Font::getKerning(..) and > FontImplementation/FreeTypeFont::getKerning(..) methods to take a > FontResolulution parameter in the same way that the getGlyph(..) > method does, this would allow the kerning implementation to reset the > font resolution if required as it does during the getGlyph(). > > Unfortunately such a change would break the API so isn't something we > can back port to OSG-3.2 or OSG-3.4, but is something we could merge > with OSG-master/OSG-3.5.x dev series. > > Thoughts? > Robert. > > On 12 January 2016 at 16:44, Romain Ouabdelkader > <[email protected]> wrote: > > Hi, > > > > I have tracked down the issue, the difference in size come from the > kerning > > being calculated in different font resolutions. > > > > If we trace the execution: > > > > osg::ref_ptr<osgText::Text> text0 = new osgText::Text; > > text0->setFont(font_path); > > text0->setFontResolution(128, 128); > > text0->setText("V"); > > text0->setText("a"); > > > > Here we generate the glyph for char 'V' and 'a' with the resolution (128, > > 128). > > > > osg::ref_ptr<osgText::Text> text1 = new osgText::Text; > > text1->setFont(font_path); > > text1->setText("p"); > > > > We generate a dummy glyph that set FreeType face resolution to (32, 32) > > > > text0->setText("Va"); > > float first_call = text0->getBoundingBox().xMax(); > > > > (1) Since the glyph for char 'V' and 'a' are already generated for > > resolution (128, 128), we use the glyph in the cache (see Font::GetGlyph) > > *without modifying FreeType face resolution*. > > We also get kerning from FreeType but we *don't* change the face > resolution, > > thus the kerning is calculated in (32, 32) resolution. > > > > text0->setText("c"); > > > > We generate a dummy glyph (that isn't in the cache) that set FreeType > face > > resolution to (128, 128). > > > > text0->setText("Va"); > > float second_call = text0->getBoundingBox().xMax(); > > > > Same as (1) but FreeType face resolution is (128, 128) while calculating > the > > kerning. > > > > > > > > This isn't a big issue, but it breaks our tests depending of the order of > > execution... > > > > The issue can be resolved if Font::getKerning ask for font resolution, > or if > > we set font resolution at the start of Text::computeGlyphRepresentation > (not > > exposed in Font). > > > > What do you think ? > > > > Regards, > > Romain Ouabdelkader. > > > > > > 2016-01-06 19:16 GMT+01:00 Romain Ouabdelkader > > <[email protected]>: > >> > >> Hi, > >> > >> I have discovered an issue with osgText: under certain conditions, > >> Text::getBoundingBox() returns different values with the same text, > font, > >> font resolution, etc. > >> > >> You can reproduce the issue with this example: > >> > >> int main() { > >> const char *font_path = "museo500.ttf"; > >> > >> osg::ref_ptr<osgText::Text> text0 = new osgText::Text; > >> text0->setFont(font_path); > >> text0->setFontResolution(128, 128); > >> text0->setText("V"); > >> text0->setText("a"); > >> > >> osg::ref_ptr<osgText::Text> text1 = new osgText::Text; > >> text1->setFont(font_path); > >> text1->setText("p"); > >> > >> text0->setText("Va"); > >> float first_call = text0->getBoundingBox().xMax(); > >> > >> text0->setText("c"); > >> > >> text0->setText("Va"); > >> float second_call = text0->getBoundingBox().xMax(); > >> > >> std::cout << first_call << std::endl; > >> std::cout << second_call << std::endl; > >> if (first_call != second_call) { > >> std::cout << "Error!" << std::endl; > >> return 1; > >> } > >> > >> return 0; > >> } > >> > >> Output: > >> 36.4961 > >> 35.9961 > >> Error! > >> > >> The issue seems to be very specific, if I remove any of these lines the > >> issue doesn't appear. > >> > >> I've attached the font if you want to reproduce it. > >> > >> Regards, > >> Romain Ouabdelkader. > >> > > > > > > _______________________________________________ > > osg-users mailing list > > [email protected] > > > http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org > > > _______________________________________________ > osg-users mailing list > [email protected] > http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org >
_______________________________________________ osg-users mailing list [email protected] http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

