Skip to content

Commit

Permalink
Merge branch 'release/1.2.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
Benjamin Bojko committed Oct 30, 2019
2 parents 25301e2 + c44c9a8 commit 82f4af4
Show file tree
Hide file tree
Showing 10 changed files with 731 additions and 482 deletions.
7 changes: 3 additions & 4 deletions samples/BasicSample/src/BasicSampleApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,12 @@ void BasicSampleApp::setup() {
mTextLayout->setFontFamily("OpenSans"); // Use a font from your fonts.json
mTextLayout->setFontSize(48.f);
mTextLayout->setTextColor(Color::white());
mTextLayout->setTextAlign(TextAlign::Center);
mTextLayout->setTextAlign(TextAlign::Left);
mTextLayout->setTextTransform(TextTransform::Capitalize);
mTextLayout->setText("Jaded zombies acted quaintly but kept driving their oxen forward.");
//mTextLayout->setText("Jaded zombies acted quaintly but kept driving their oxen forward.");

// And you should be able to render
mTextLayout->setText("Jaded <b><i>zombies</i> acted<br/>quaintly</b> but \
kept driving <i>their oxen forward</i>.");
mTextLayout->setText("Jaded <b><i>zombies</i> acted<br/>quaintly</b> but kept driving-their oxen forward</i>.");
}

void BasicSampleApp::update() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ void PropertyExplorerSampleApp::setup()
mParamLayoutModes.push_back("NoWrap");
mParamLayoutModes.push_back("SingleLine");

mParams = ci::params::InterfaceGl::create("Settings", ivec2(400, 400), ColorA(0, 0, 0, 0.7f));
mParams = ci::params::InterfaceGl::create("Settings", toPixels(ivec2(400, 400)), ColorA(0, 0, 0, 0.7f));
mParams->addParam("Text", &mLoremIpsum).updateFn([&] { updateText(); });
mParams->addButton("Reload", [&] { loadText(); updateText(); });
mParams->addSeparator();
Expand Down Expand Up @@ -180,7 +180,7 @@ void PropertyExplorerSampleApp::resize() {

updateText();

ivec2 paramsPos = getWindowSize() - mParams->getSize() - ivec2(16);
ivec2 paramsPos = toPixels(getWindowSize()) - mParams->getSize() - ivec2(16);
if (paramsPos.x < 0) paramsPos.x = 0;
if (paramsPos.y < 0) paramsPos.y = 0;
mParams->setPosition(paramsPos);
Expand All @@ -190,5 +190,6 @@ CINDER_APP(PropertyExplorerSampleApp,
RendererGl(RendererGl::Options().msaa(4)),
[&](ci::app::App::Settings *settings)
{
settings->setHighDensityDisplayEnabled(true);
settings->setWindowSize(900, 640);
})
162 changes: 97 additions & 65 deletions src/bluecadet/text/FontManager.cpp
Original file line number Diff line number Diff line change
@@ -1,53 +1,58 @@
#include "FontManager.h"
#include "cinder/Json.h"

#include "cinder/Log.h"

using namespace ci;
using namespace ci::app;
using namespace std;

namespace bluecadet {
namespace text {

FontManager::FontManager() :
mDefaultName("Arial"),
mDefaultStyle(FontStyle::Normal),
mDefaultWeight(FontWeight::Regular),
mLogLevel(LogLevel::Error)
{
}
FontManager::FontManager()
: mDefaultName("Arial"),
mDefaultStyle(FontStyle::Normal),
mDefaultWeight(FontWeight::Regular),
mLogLevel(LogLevel::Error) {}

FontManager::~FontManager() {
}
FontManager::~FontManager() {}

void FontManager::setup(ci::fs::path jsonPath) {
if (mLogLevel >= LogLevel::Info) cout << "FontManager: Loading json from '" << jsonPath << "'" << endl;
if (mLogLevel >= LogLevel::Info) {
CI_LOG_I("FontManager: Loading json from '" << jsonPath << "'");
}

if (jsonPath.empty()) {
if (mLogLevel >= LogLevel::Error) cout << "FontManager: Error: Json path is empty or invalid" << endl;
if (mLogLevel >= LogLevel::Error) {
CI_LOG_E("FontManager: Error: Json path is empty or invalid");
}
return;
}

DataSourceRef jsonData = loadFile(jsonPath);

if (!jsonData) {
if (mLogLevel >= LogLevel::Error) cout << "FontManager: Error: Can't load json at '" << jsonPath << "'" << endl;
if (mLogLevel >= LogLevel::Error) {
CI_LOG_E("FontManager: Error: Can't load json at '" << jsonPath << "'");
}
return;
}

try {
JsonTree json = JsonTree(jsonData);
std::string jsonDirPath = jsonPath.remove_filename().string();

auto& familiesJson = json.getChild("fonts").getChildren();
auto & familiesJson = json.getChild("fonts").getChildren();

for (auto& familyJson : familiesJson) {
for (auto & familyJson : familiesJson) {
StylesByWeight styles;

for (auto& weightJson : familyJson.getChildren()) {
for (auto & weightJson : familyJson.getChildren()) {
FilePathsByStyles filePaths;
int weight = stoi(weightJson.getKey());

for (auto& styleJson : weightJson.getChildren()) {
for (auto & styleJson : weightJson.getChildren()) {
FontStyle style = getFontStyleFromString(styleJson.getKey());
string fileName = styleJson.getValue();
fs::path filePath = fs::path(jsonDirPath + "/" + fileName);
Expand All @@ -60,29 +65,35 @@ void FontManager::setup(ci::fs::path jsonPath) {
mWeightsByFamily[familyJson.getKey()] = styles;
}

}
catch (Exception e) {
if (mLogLevel >= LogLevel::Error) cout << "FontManager: Error: Could not parse JSON: " << e.what() << endl;
} catch (const std::exception & e) {
if (mLogLevel >= LogLevel::Error) {
CI_LOG_EXCEPTION("FontManager: Error: Could not parse JSON: ", e);
}
}
}

ci::Font& FontManager::getFont(Style style, FallbackMode fallbackMode) {
ci::Font & FontManager::getFont(Style style, FallbackMode fallbackMode) {
return getFont(style.mFontFamily, style.mFontSize, style.mFontWeight, style.mFontStyle, fallbackMode);
}

ci::Font& FontManager::getFont(std::string family, float size, int weight, FontStyle style, FallbackMode fallbackMode) {
ci::Font & FontManager::getFont(std::string family, float size, int weight, FontStyle style,
FallbackMode fallbackMode) {
auto weightsIt = mWeightsByFamily.find(family);

if (weightsIt == mWeightsByFamily.end()) {
// Check if we have the font family as a system font
auto& systemFontNames = Font::getNames();
auto & systemFontNames = Font::getNames();
auto fontIt = std::find(systemFontNames.begin(), systemFontNames.end(), family);
if (fontIt == systemFontNames.end()) {
if (family == mDefaultName) {
if (mLogLevel >= LogLevel::Warning) cout << "FontManager: Warning: Can't find font with family '" << family << "'" << endl;
}
else {
if (mLogLevel >= LogLevel::Warning) cout << "FontManager: Warning: Can't find font with family '" << family << "'; Returning default font '" << mDefaultName << "'" << endl;
if (mLogLevel >= LogLevel::Warning) {
CI_LOG_W("FontManager: Warning: Can't find font with family '" << family << "'");
}
} else {
if (mLogLevel >= LogLevel::Warning) {
CI_LOG_W("FontManager: Warning: Can't find font with family '"
<< family << "'; Returning default font '" << mDefaultName << "'");
}
}
family = mDefaultName;
}
Expand All @@ -91,19 +102,27 @@ ci::Font& FontManager::getFont(std::string family, float size, int weight, FontS

string path = getFontPath(weightsIt->second, weight, style, fallbackMode);

//cout << "FontManager: Path for family '" << family << "', weight '" << to_string(weight) << "' and style '" << getStringFromStyle(style) << "': '" << path << "'" << endl;
// if (mLogLevel >= LogLevel::Info) CI_LOG_D("FontManager: Path for family '" << family << "', weight '" <<
// to_string(weight) << "' and style '" << getStringFromStyle(style) << "': '" << path << "'");

if (path.empty()) {
if (mLogLevel >= LogLevel::Warning) cout << "FontManager: Warning: Can't find font weight '" << to_string(weight) << "' and style '" << getStringFromFontStyle(style) << "' for family '" << family << "'; Returning default font '" << mDefaultName << "'" << endl;
if (mLogLevel >= LogLevel::Warning) {
CI_LOG_W("FontManager: Warning: Can't find font weight '"
<< to_string(weight) << "' and style '" << getStringFromFontStyle(style) << "' for family '"
<< family << "'; Returning default font '" << mDefaultName << "'");
}
return getCachedFontByName(mDefaultName, size);
}

return getCachedFontByPath(path, size);
}

std::string FontManager::getFontPath(StylesByWeight& weights, int targetWeight, FontStyle targetStyle, FallbackMode fallbackMode) {
std::string FontManager::getFontPath(StylesByWeight & weights, int targetWeight, FontStyle targetStyle,
FallbackMode fallbackMode) {
if (weights.empty()) {
if (mLogLevel >= LogLevel::Warning) cout << "FontManager: Warning: No weights found for font" << endl;
if (mLogLevel >= LogLevel::Warning) {
CI_LOG_W("FontManager: Warning: No weights found for font");
}
return "";
}

Expand All @@ -116,12 +135,18 @@ std::string FontManager::getFontPath(StylesByWeight& weights, int targetWeight,

if (stylesIt != weights.end()) {
// Found a fallback weight
if (mLogLevel >= LogLevel::Warning) cout << "FontManager: Warning: Can't find font weight '" << to_string(targetWeight) << "' for style '" << getStringFromFontStyle(targetStyle) << "'; Falling back to '" << to_string(stylesIt->first) << "'" << endl;

}
else if (targetStyle != mDefaultStyle) {
if (mLogLevel >= LogLevel::Warning) {
CI_LOG_W("FontManager: Warning: Can't find font weight '"
<< to_string(targetWeight) << "' for style '" << getStringFromFontStyle(targetStyle)
<< "'; Falling back to '" << to_string(stylesIt->first) << "'");
}
} else if (targetStyle != mDefaultStyle) {
// Default to normal style if we couldn't find a weight with the target style
if (mLogLevel >= LogLevel::Warning) cout << "FontManager: Warning: Can't find style '" << getStringFromFontStyle(targetStyle) << "'; Defaulting to '" << getStringFromFontStyle(mDefaultStyle) << "'" << endl;
if (mLogLevel >= LogLevel::Warning) {
CI_LOG_W("FontManager: Warning: Can't find style '" << getStringFromFontStyle(targetStyle)
<< "'; Defaulting to '"
<< getStringFromFontStyle(mDefaultStyle) << "'");
}
return getFontPath(weights, targetWeight, mDefaultStyle, fallbackMode);
}
}
Expand All @@ -133,15 +158,18 @@ std::string FontManager::getFontPath(StylesByWeight& weights, int targetWeight,
auto pathIt = stylesIt->second.find(targetStyle);

if (pathIt == stylesIt->second.end()) {
if (mLogLevel >= LogLevel::Error) cout << "FontManager: Error: Could not find an alternate weight to '" << to_string(targetWeight) << "' with style '" << getStringFromFontStyle(targetStyle) << "'" << endl;
if (mLogLevel >= LogLevel::Error) {
CI_LOG_E("FontManager: Error: Could not find an alternate weight to '"
<< to_string(targetWeight) << "' with style '" << getStringFromFontStyle(targetStyle) << "'");
}
return "";
}

return pathIt->second;
}

ci::Font& FontManager::getCachedFontByPath(std::string path, float size) {
auto& sizeMap = getCachedSizesForFont(path);
ci::Font & FontManager::getCachedFontByPath(std::string path, float size) {
auto & sizeMap = getCachedSizesForFont(path);
auto fontIt = sizeMap.find(size);

if (fontIt == sizeMap.end()) {
Expand All @@ -151,29 +179,33 @@ ci::Font& FontManager::getCachedFontByPath(std::string path, float size) {
try {
dataSource = loadFile(path);
} catch (Exception e) {
if (mLogLevel >= LogLevel::Error) cout << "FontManager: Error: Can't load font file at '" << path << "'; Returning default font '" << mDefaultName << "'" << endl;
if (mLogLevel >= LogLevel::Error) {
CI_LOG_E("FontManager: Error: Can't load font file at '" << path << "'; Returning default font '"
<< mDefaultName << "'");
}
return getCachedFontByName(mDefaultName, size);
}

// try creating font
try {
sizeMap[size] = ci::Font(dataSource, size);
sizeMap[size] = ci::Font(dataSource, size * mFontScale);

} catch (Exception e) {
if (mLogLevel >= LogLevel::Error) cout << "FontManager: Error: Can't create font from file at '" << path << "'; Returning default font '" << mDefaultName << "'" << endl;
if (mLogLevel >= LogLevel::Error) {
CI_LOG_E("FontManager: Error: Can't create font from file at '" << path << "'; Returning default font '"
<< mDefaultName << "'");
}
return getCachedFontByName(mDefaultName, size);
}

fontIt = sizeMap.find(size);

}

return fontIt->second;

}

ci::Font& FontManager::getCachedFontByName(std::string name, float size) {
auto& sizeMap = getCachedSizesForFont(name);
ci::Font & FontManager::getCachedFontByName(std::string name, float size) {
auto & sizeMap = getCachedSizesForFont(name);
auto fontIt = sizeMap.find(size);

if (fontIt == sizeMap.end()) {
Expand All @@ -184,7 +216,7 @@ ci::Font& FontManager::getCachedFontByName(std::string name, float size) {
return fontIt->second;
}

std::map<float, ci::Font>& FontManager::getCachedSizesForFont(std::string key) {
std::map<float, ci::Font> & FontManager::getCachedSizesForFont(std::string key) {
auto sizeMapIt = mCachedFonts.find(key);
if (sizeMapIt == mCachedFonts.end()) {
// create new map if it doesn't exist yet
Expand All @@ -194,7 +226,8 @@ std::map<float, ci::Font>& FontManager::getCachedSizesForFont(std::string key) {
return sizeMapIt->second;
}

FontManager::StylesByWeight::iterator FontManager::getFallbackWeight(StylesByWeight& weights, int targetWeight, FontStyle targetStyle, FallbackMode fallbackMode) {
FontManager::StylesByWeight::iterator FontManager::getFallbackWeight(StylesByWeight & weights, int targetWeight,
FontStyle targetStyle, FallbackMode fallbackMode) {
int nextLowest = INT_MIN;
int nextHighest = INT_MAX;
StylesByWeight::iterator nextLowestIt = weights.end();
Expand All @@ -203,37 +236,36 @@ FontManager::StylesByWeight::iterator FontManager::getFallbackWeight(StylesByWei
// Find alternate weights with the same style
for (auto stylesIt = weights.begin(); stylesIt != weights.end(); ++stylesIt) {
int currentWeight = stylesIt->first;
FilePathsByStyles& paths = stylesIt->second;
if (paths.count(targetStyle) == 0) continue; // Only check if we have the right style
FilePathsByStyles & paths = stylesIt->second;
if (paths.count(targetStyle) == 0) continue; // Only check if we have the right style

if (currentWeight < targetWeight && currentWeight > nextLowest) {
nextLowest = currentWeight;
nextLowestIt = stylesIt;

}
else if (currentWeight > targetWeight && currentWeight < nextHighest) {
} else if (currentWeight > targetWeight && currentWeight < nextHighest) {
nextHighest = currentWeight;
nextHighestIt = stylesIt;
}
}

switch (fallbackMode) {
case PrioritizeLighter: {
if (nextLowest != INT_MIN) return nextLowestIt;
if (nextHighest != INT_MAX) return nextHighestIt;
}
case PrioritizeHeavier: {
if (nextHighest != INT_MAX) return nextHighestIt;
if (nextLowest != INT_MIN) return nextLowestIt;
}
case Adaptive: {
if (nextLowest != INT_MIN && (targetWeight <= Regular || nextHighest == INT_MAX)) return nextLowestIt;
if (nextHighest != INT_MAX && (targetWeight > Regular || nextLowest == INT_MIN)) return nextHighestIt;
}
case PrioritizeLighter: {
if (nextLowest != INT_MIN) return nextLowestIt;
if (nextHighest != INT_MAX) return nextHighestIt;
}
case PrioritizeHeavier: {
if (nextHighest != INT_MAX) return nextHighestIt;
if (nextLowest != INT_MIN) return nextLowestIt;
}
case Adaptive: {
if (nextLowest != INT_MIN && (targetWeight <= Regular || nextHighest == INT_MAX)) return nextLowestIt;
if (nextHighest != INT_MAX && (targetWeight > Regular || nextLowest == INT_MIN)) return nextHighestIt;
}
}

return weights.end();
}

}
}
} // namespace text
} // namespace bluecadet
Loading

0 comments on commit 82f4af4

Please sign in to comment.