Skip to content

Commit

Permalink
Overlay: Font - add merge_fonts property
Browse files Browse the repository at this point in the history
  • Loading branch information
paroj committed Nov 9, 2024
1 parent f0b87ee commit 620d63f
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 13 deletions.
20 changes: 18 additions & 2 deletions Components/Overlay/include/OgreFont.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ THE SOFTWARE
#define _Font_H__

#include "OgreOverlayPrerequisites.h"
#include "OgrePrerequisites.h"
#include "OgreResource.h"
#include "OgreCommon.h"
#include "OgreSharedPtr.h"
Expand All @@ -44,6 +45,8 @@ namespace Ogre
/** \addtogroup Overlays
* @{
*/
class Font;
typedef SharedPtr<Font> FontPtr;

/// decode UTF8 encoded bytestream to uint32 codepoints
_OgreOverlayExport std::vector<uint32> utftoc32(String str);
Expand Down Expand Up @@ -124,12 +127,17 @@ namespace Ogre
/// Range of code points to generate glyphs for (truetype only)
CodePointRangeList mCodePointRangeList;

std::vector<FontPtr> mMergeFonts;

/// Internal method for loading from ttf
void createTextureFromFont(void);

void loadImpl() override;
void unloadImpl() override;
size_t calculateSize(void) const override { return 0; } // permanent resource is in the texture

friend class ImGuiOverlay;
DataStreamPtr _getTTFData();
public:

/** Constructor.
Expand Down Expand Up @@ -287,6 +295,16 @@ namespace Ogre
{
return mCodePointRangeList;
}

/** Add a font to merge with this one.
This is useful when you want to use a font for most of the characters, but
fall back to another font for characters not present in the current font. e.g. icons.
*/
void addMergeFont(const FontPtr& font) { mMergeFonts.push_back(font); }

const std::vector<FontPtr>& getMergeFontList() const { return mMergeFonts; }

/** Gets the material generated for this font, as a weak reference.
This will only be valid after the Font has been loaded.
Expand Down Expand Up @@ -343,8 +361,6 @@ namespace Ogre
*/
void _setMaterial(const MaterialPtr& mat);
};

typedef SharedPtr<Font> FontPtr;
/** @} */
/** @} */
}
Expand Down
13 changes: 7 additions & 6 deletions Components/Overlay/src/OgreFont.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -328,14 +328,15 @@ namespace Ogre
mTexture->load();
}
//---------------------------------------------------------------------
DataStreamPtr Font::_getTTFData()
{
// Locate ttf file, load it pre-buffered into memory by wrapping
// the original DataStream in a MemoryDataStream
return ResourceGroupManager::getSingleton().openResource(mSource, mGroup, this);
}
void Font::loadResource(Resource* res)
{
// Locate ttf file, load it pre-buffered into memory by wrapping the
// original DataStream in a MemoryDataStream
DataStreamPtr dataStreamPtr =
ResourceGroupManager::getSingleton().openResource(
mSource, mGroup, this);
MemoryDataStream ttfchunk(dataStreamPtr);
MemoryDataStream ttfchunk = _getTTFData();

// If codepoints not supplied, assume ASCII
if (mCodePointRangeList.empty())
Expand Down
33 changes: 28 additions & 5 deletions Components/Overlay/src/OgreImGuiOverlay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,7 @@ ImFont* ImGuiOverlay::addFont(const String& name, const String& group)
StringUtil::format("Font '%s' not found in group '%s'", name.c_str(), group.c_str()));

OgreAssert(font->getType() == FT_TRUETYPE, "font must be of FT_TRUETYPE");
DataStreamPtr dataStreamPtr =
ResourceGroupManager::getSingleton().openResource(font->getSource(), font->getGroup());
MemoryDataStream ttfchunk(dataStreamPtr, false); // transfer ownership to imgui
MemoryDataStream ttfchunk(font->_getTTFData(), false); // transfer ownership to imgui

// convert codepoint ranges for imgui
CodePointRange cprange;
Expand All @@ -149,8 +147,33 @@ ImFont* ImGuiOverlay::addFont(const String& name, const String& group)

ImFontConfig cfg;
strncpy(cfg.Name, name.c_str(), IM_ARRAYSIZE(cfg.Name) - 1);
return io.Fonts->AddFontFromMemoryTTF(ttfchunk.getPtr(), ttfchunk.size(), font->getTrueTypeSize() * vpScale, &cfg,
cprangePtr);
auto* ret = io.Fonts->AddFontFromMemoryTTF(ttfchunk.getPtr(), ttfchunk.size(), font->getTrueTypeSize() * vpScale,
&cfg, cprangePtr);

cfg.MergeMode = true;

for(const auto& mergeFont : font->getMergeFontList())
{
MemoryDataStream mergeTtfchunk(mergeFont->_getTTFData(), false); // transfer ownership to imgui

CodePointRange mergeCprange;
for (const auto& r : mergeFont->getCodePointRangeList())
{
mergeCprange.push_back(r.first);
mergeCprange.push_back(r.second);
}

OgreAssert(!mergeCprange.empty(), "merge font must have codepoint ranges");
mergeCprange.push_back(0); // terminate
mCodePointRanges.push_back(mergeCprange);
cprangePtr = mCodePointRanges.back().data();

cfg.MergeMode = true;
ret = io.Fonts->AddFontFromMemoryTTF(mergeTtfchunk.getPtr(), mergeTtfchunk.size(),
mergeFont->getTrueTypeSize() * vpScale, &cfg, cprangePtr);
}

return ret;
}

void ImGuiOverlay::ImGUIRenderable::createFontTexture()
Expand Down
25 changes: 25 additions & 0 deletions Components/Overlay/src/OgreOverlayTranslator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,31 @@ void FontTranslator::parseAttribute(ScriptCompiler* compiler, FontPtr& pFont,
pFont->setAntialiasColour(flag);
compiler->addError(ScriptCompiler::CE_DEPRECATEDSYMBOL, prop->file, prop->line, attrib);
}
else if(attrib == "merge_fonts")
{
if (prop->values.empty())
{
compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line);
return;
}

for (auto& v : prop->values)
{
if (!getString(v, &val))
{
compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line);
return;
}

auto mergeFont = FontManager::getSingleton().getByName(val, pFont->getGroup());
if (!mergeFont)
{
compiler->addError(ScriptCompiler::CE_REFERENCETOANONEXISTINGOBJECT, prop->file, prop->line, val);
return;
}
pFont->addMergeFont(mergeFont);
}
}
else if (attrib == "code_points")
{
if (prop->values.empty())
Expand Down
2 changes: 2 additions & 0 deletions Docs/src/scripts.md
Original file line number Diff line number Diff line change
Expand Up @@ -1299,4 +1299,6 @@ Here are the attributes you need to supply:

@param code\_points <b>nn-nn \[nn-nn\] ..</b> This directive allows you to specify which unicode code points should be generated as glyphs into the font texture. If you don’t specify this, code points 32-126 will be generated by default which covers the ASCII glyphs. If you use this flag, you should specify a space-separated list of inclusive code point ranges of the form ’start-end’. Numbers must be decimal.

@param merge_font **name [name2]** @copydetails Ogre::Font::addMergeFont

You can also create new fonts at runtime by using the Ogre::FontManager if you wish.

0 comments on commit 620d63f

Please sign in to comment.