make the chat really pretty!!
also slightly optimized text shadow rendering, made sure glyphs with directives stay centered and added two extra Lua arguments to canvas.drawText
This commit is contained in:
parent
9b75bd8eb2
commit
bd783d3195
7
assets/opensb/_metadata
Normal file
7
assets/opensb/_metadata
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"author" : "Not Chucklefish",
|
||||||
|
"name" : "opensb_base",
|
||||||
|
"priority" : -9999,
|
||||||
|
"friendlyName" : "OpenStarbound Assets",
|
||||||
|
"requires" : ["base"]
|
||||||
|
}
|
17
assets/opensb/interface/chat/chat.config.patch
Normal file
17
assets/opensb/interface/chat/chat.config.patch
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"config" : {
|
||||||
|
"font" : {
|
||||||
|
"directives" : "",
|
||||||
|
"padding" : [0, 0] // Padding to prevent border clipping at the edges of the log canvas while keeping compatible with mods that patch the canvas size
|
||||||
|
},
|
||||||
|
"colors" : {
|
||||||
|
"local" : "^white;",
|
||||||
|
"party" : "^blue;",
|
||||||
|
"broadcast" : "^yellow;",
|
||||||
|
"whisper" : "^pink;",
|
||||||
|
"commandResult" : "^lightgray;",
|
||||||
|
"radioMessage" : "^cyan;",
|
||||||
|
"world" : "^cyan;"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -377,7 +377,7 @@ Draws a polygon on the canvas.
|
|||||||
|
|
||||||
Draws a list of filled triangles to the canvas.
|
Draws a list of filled triangles to the canvas.
|
||||||
|
|
||||||
##### `void` drawText(`String` text, `Json` textPositioning, `unsigned` fontSize, [`Color` color])
|
##### `void` drawText(`String` text, `Json` textPositioning, `unsigned` fontSize, [`Color` color], [`float` lineSpacing], [`String` directives])
|
||||||
|
|
||||||
Draws text on the canvas. textPositioning is in the format:
|
Draws text on the canvas. textPositioning is in the format:
|
||||||
|
|
||||||
|
@ -827,29 +827,36 @@ Json Assets::readJson(String const& path) const {
|
|||||||
Json result = inputUtf8Json(streamData.begin(), streamData.end(), false);
|
Json result = inputUtf8Json(streamData.begin(), streamData.end(), false);
|
||||||
for (auto const& pair : m_files.get(path).patchSources) {
|
for (auto const& pair : m_files.get(path).patchSources) {
|
||||||
auto patchStream = pair.second->read(pair.first);
|
auto patchStream = pair.second->read(pair.first);
|
||||||
auto patchData = inputUtf8Json(patchStream.begin(), patchStream.end(), false).toArray();
|
auto patchJson = inputUtf8Json(patchStream.begin(), patchStream.end(), false);
|
||||||
try {
|
if (patchJson.isType(Json::Type::Array)) {
|
||||||
if (patchData.size()) {
|
auto patchData = patchJson.toArray();
|
||||||
if (patchData.at(0).type() == Json::Type::Array) {
|
try {
|
||||||
for (auto const& patch : patchData) {
|
if (patchData.size()) {
|
||||||
|
if (patchData.at(0).type() == Json::Type::Array) {
|
||||||
|
for (auto const& patch : patchData) {
|
||||||
|
try {
|
||||||
|
result = jsonPatch(result, patch.toArray());
|
||||||
|
} catch (JsonPatchTestFail const& e) {
|
||||||
|
Logger::debug("Patch test failure from file %s in source: %s. Caused by: %s", pair.first, m_assetSourcePaths.getLeft(pair.second), e.what());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (patchData.at(0).type() == Json::Type::Object) {
|
||||||
try {
|
try {
|
||||||
result = jsonPatch(result, patch.toArray());
|
result = jsonPatch(result, patchData);
|
||||||
} catch (JsonPatchTestFail const& e) {
|
} catch (JsonPatchTestFail const& e) {
|
||||||
Logger::debug("Patch test failure from file %s in source: %s. Caused by: %s", pair.first, m_assetSourcePaths.getLeft(pair.second), e.what());
|
Logger::debug("Patch test failure from file %s in source: %s. Caused by: %s", pair.first, m_assetSourcePaths.getLeft(pair.second), e.what());
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
throw JsonPatchException(strf("Patch data is wrong type: %s", Json::typeName(patchData.at(0).type())));
|
||||||
}
|
}
|
||||||
} else if (patchData.at(0).type() == Json::Type::Object) {
|
|
||||||
try {
|
|
||||||
result = jsonPatch(result, patchData);
|
|
||||||
} catch (JsonPatchTestFail const& e) {
|
|
||||||
Logger::debug("Patch test failure from file %s in source: %s. Caused by: %s", pair.first, m_assetSourcePaths.getLeft(pair.second), e.what());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw JsonPatchException(strf("Patch data is wrong type: %s", Json::typeName(patchData.at(0).type())));
|
|
||||||
}
|
}
|
||||||
|
} catch (JsonPatchException const& e) {
|
||||||
|
Logger::error("Could not apply patch from file %s in source: %s. Caused by: %s", pair.first, m_assetSourcePaths.getLeft(pair.second), e.what());
|
||||||
}
|
}
|
||||||
} catch (JsonPatchException const& e) {
|
}
|
||||||
Logger::error("Could not apply patch from file %s in source: %s. Caused by: %s", pair.first, m_assetSourcePaths.getLeft(pair.second), e.what());
|
else if (patchJson.isType(Json::Type::Object)) { //Kae: Do a good ol' json merge instead if the .patch file is a Json object
|
||||||
|
auto patchData = patchJson.toObject();
|
||||||
|
result = jsonMerge(result, patchData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -21,7 +21,9 @@ Chat::Chat(UniverseClientPtr client) : m_client(client) {
|
|||||||
|
|
||||||
auto assets = Root::singleton().assets();
|
auto assets = Root::singleton().assets();
|
||||||
m_timeChatLastActive = Time::monotonicMilliseconds();
|
m_timeChatLastActive = Time::monotonicMilliseconds();
|
||||||
m_fontSize = assets->json("/interface/chat/chat.config:config.font.baseSize").toInt();
|
auto fontConfig = assets->json("/interface/chat/chat.config:config.font");
|
||||||
|
m_fontSize = fontConfig.getInt("baseSize");
|
||||||
|
m_fontDirectives = fontConfig.queryString("directives", "");
|
||||||
m_chatLineHeight = assets->json("/interface/chat/chat.config:config.lineHeight").toFloat();
|
m_chatLineHeight = assets->json("/interface/chat/chat.config:config.lineHeight").toFloat();
|
||||||
m_chatVisTime = assets->json("/interface/chat/chat.config:config.visTime").toFloat();
|
m_chatVisTime = assets->json("/interface/chat/chat.config:config.visTime").toFloat();
|
||||||
m_fadeRate = assets->json("/interface/chat/chat.config:config.fadeRate").toDouble();
|
m_fadeRate = assets->json("/interface/chat/chat.config:config.fadeRate").toDouble();
|
||||||
@ -69,6 +71,13 @@ Chat::Chat(UniverseClientPtr client) : m_client(client) {
|
|||||||
m_say = fetchChild<LabelWidget>("say");
|
m_say = fetchChild<LabelWidget>("say");
|
||||||
|
|
||||||
m_chatLog = fetchChild<CanvasWidget>("chatLog");
|
m_chatLog = fetchChild<CanvasWidget>("chatLog");
|
||||||
|
if (auto logPadding = fontConfig.optQuery("padding")) {
|
||||||
|
m_chatLogPadding = jsonToVec2I(logPadding.get());
|
||||||
|
m_chatLog->setSize(m_chatLog->size() + m_chatLogPadding * 2);
|
||||||
|
m_chatLog->setPosition(m_chatLog->position() - m_chatLogPadding);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_chatLogPadding = Vec2I();
|
||||||
|
|
||||||
m_bottomButton = fetchChild<ButtonWidget>("bottomButton");
|
m_bottomButton = fetchChild<ButtonWidget>("bottomButton");
|
||||||
m_upButton = fetchChild<ButtonWidget>("upButton");
|
m_upButton = fetchChild<ButtonWidget>("upButton");
|
||||||
@ -224,7 +233,7 @@ void Chat::renderImpl() {
|
|||||||
m_say->setColor(fadeGreen);
|
m_say->setColor(fadeGreen);
|
||||||
|
|
||||||
m_chatLog->clear();
|
m_chatLog->clear();
|
||||||
Vec2I chatMin;
|
Vec2I chatMin = m_chatLogPadding;
|
||||||
int messageIndex = -m_historyOffset;
|
int messageIndex = -m_historyOffset;
|
||||||
|
|
||||||
GuiContext& guiContext = GuiContext::singleton();
|
GuiContext& guiContext = GuiContext::singleton();
|
||||||
@ -249,7 +258,7 @@ void Chat::renderImpl() {
|
|||||||
|
|
||||||
float messageHeight = 0;
|
float messageHeight = 0;
|
||||||
float lineHeightMargin = + ((m_chatLineHeight * m_fontSize) - m_fontSize);
|
float lineHeightMargin = + ((m_chatLineHeight * m_fontSize) - m_fontSize);
|
||||||
unsigned wrapWidth = m_chatLog->size()[0];
|
unsigned wrapWidth = m_chatLog->size()[0] - m_chatLogPadding[0];
|
||||||
|
|
||||||
if (message.portrait != "") {
|
if (message.portrait != "") {
|
||||||
TextPositioning tp = {Vec2F(chatMin + m_portraitTextOffset), HorizontalAnchor::LeftAnchor, VerticalAnchor::VMidAnchor, (wrapWidth - m_portraitTextOffset[0])};
|
TextPositioning tp = {Vec2F(chatMin + m_portraitTextOffset), HorizontalAnchor::LeftAnchor, VerticalAnchor::VMidAnchor, (wrapWidth - m_portraitTextOffset[0])};
|
||||||
@ -262,13 +271,13 @@ void Chat::renderImpl() {
|
|||||||
m_chatLog->drawImage(m_portraitBackground, Vec2F(imagePosition), 1.0f, fade);
|
m_chatLog->drawImage(m_portraitBackground, Vec2F(imagePosition), 1.0f, fade);
|
||||||
m_chatLog->drawImage(message.portrait, Vec2F(imagePosition + m_portraitImageOffset), m_portraitScale, fade);
|
m_chatLog->drawImage(message.portrait, Vec2F(imagePosition + m_portraitImageOffset), m_portraitScale, fade);
|
||||||
tp.pos += Vec2F(0, floor(messageHeight / 2));
|
tp.pos += Vec2F(0, floor(messageHeight / 2));
|
||||||
m_chatLog->drawText(messageString, tp, m_fontSize, fade, FontMode::Normal, m_chatLineHeight);
|
m_chatLog->drawText(messageString, tp, m_fontSize, fade, FontMode::Normal, m_chatLineHeight, m_fontDirectives);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
TextPositioning tp = {Vec2F(chatMin), HorizontalAnchor::LeftAnchor, VerticalAnchor::BottomAnchor, wrapWidth};
|
TextPositioning tp = {Vec2F(chatMin), HorizontalAnchor::LeftAnchor, VerticalAnchor::BottomAnchor, wrapWidth};
|
||||||
messageHeight = guiContext.determineInterfaceTextSize(messageString, tp).size()[1] + lineHeightMargin;
|
messageHeight = guiContext.determineInterfaceTextSize(messageString, tp).size()[1] + lineHeightMargin;
|
||||||
|
|
||||||
m_chatLog->drawText(messageString, tp, m_fontSize, fade, FontMode::Normal, m_chatLineHeight);
|
m_chatLog->drawText(messageString, tp, m_fontSize, fade, FontMode::Normal, m_chatLineHeight, m_fontDirectives);
|
||||||
}
|
}
|
||||||
|
|
||||||
chatMin[1] += ceil(messageHeight);
|
chatMin[1] += ceil(messageHeight);
|
||||||
|
@ -68,11 +68,13 @@ private:
|
|||||||
float m_chatVisTime;
|
float m_chatVisTime;
|
||||||
float m_fadeRate;
|
float m_fadeRate;
|
||||||
unsigned m_fontSize;
|
unsigned m_fontSize;
|
||||||
|
String m_fontDirectives;
|
||||||
float m_chatLineHeight;
|
float m_chatLineHeight;
|
||||||
unsigned m_chatHistoryLimit;
|
unsigned m_chatHistoryLimit;
|
||||||
int m_historyOffset;
|
int m_historyOffset;
|
||||||
|
|
||||||
CanvasWidgetPtr m_chatLog;
|
CanvasWidgetPtr m_chatLog;
|
||||||
|
Vec2I m_chatLogPadding;
|
||||||
|
|
||||||
ImageStretchWidgetPtr m_background;
|
ImageStretchWidgetPtr m_background;
|
||||||
int m_defaultHeight;
|
int m_defaultHeight;
|
||||||
|
@ -78,8 +78,8 @@ struct LuaUserDataMethods<CanvasWidgetPtr> {
|
|||||||
canvasWidget->drawTriangles(tris, color.value(Color::White).toRgba());
|
canvasWidget->drawTriangles(tris, color.value(Color::White).toRgba());
|
||||||
});
|
});
|
||||||
methods.registerMethod("drawText",
|
methods.registerMethod("drawText",
|
||||||
[](CanvasWidgetPtr canvasWidget, String text, Json tp, unsigned fontSize, Maybe<Color> color) {
|
[](CanvasWidgetPtr canvasWidget, String text, Json tp, unsigned fontSize, Maybe<Color> color, Maybe<float> lineSpacing, Maybe<String> directives) {
|
||||||
canvasWidget->drawText(text, TextPositioning(tp), fontSize, color.value(Color::White).toRgba());
|
canvasWidget->drawText(text, TextPositioning(tp), fontSize, color.value(Color::White).toRgba(), FontMode::Normal, lineSpacing.value(DefaultLineSpacing), directives.value(""));
|
||||||
});
|
});
|
||||||
|
|
||||||
return methods;
|
return methods;
|
||||||
|
@ -12,24 +12,34 @@ void FontTextureGroup::cleanup(int64_t timeout) {
|
|||||||
eraseWhere(m_glyphs, [&](auto const& p) { return currentTime - p.second.time > timeout; });
|
eraseWhere(m_glyphs, [&](auto const& p) { return currentTime - p.second.time > timeout; });
|
||||||
}
|
}
|
||||||
|
|
||||||
TexturePtr FontTextureGroup::glyphTexture(String::Char c, unsigned size) {
|
const FontTextureGroup::GlyphTexture& FontTextureGroup::glyphTexture(String::Char c, unsigned size, String const& processingDirectives)
|
||||||
return glyphTexture(c, size, "");
|
{
|
||||||
}
|
|
||||||
|
|
||||||
TexturePtr FontTextureGroup::glyphTexture(String::Char c, unsigned size, String const& processingDirectives) {
|
|
||||||
auto res = m_glyphs.insert(GlyphDescriptor{c, size, processingDirectives}, GlyphTexture());
|
auto res = m_glyphs.insert(GlyphDescriptor{c, size, processingDirectives}, GlyphTexture());
|
||||||
|
|
||||||
if (res.second) {
|
if (res.second) {
|
||||||
m_font->setPixelSize(size);
|
m_font->setPixelSize(size);
|
||||||
Image image = m_font->render(c);
|
Image image = m_font->render(c);
|
||||||
if (!processingDirectives.empty())
|
if (!processingDirectives.empty()) {
|
||||||
|
Vec2F preSize = Vec2F(image.size());
|
||||||
image = processImageOperations(parseImageOperations(processingDirectives), image);
|
image = processImageOperations(parseImageOperations(processingDirectives), image);
|
||||||
|
res.first->second.processingOffset = preSize - Vec2F(image.size());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
res.first->second.processingOffset = Vec2F();
|
||||||
|
|
||||||
res.first->second.texture = m_textureGroup->create(image);
|
res.first->second.texture = m_textureGroup->create(image);
|
||||||
}
|
}
|
||||||
|
|
||||||
res.first->second.time = Time::monotonicMilliseconds();
|
res.first->second.time = Time::monotonicMilliseconds();
|
||||||
return res.first->second.texture;
|
return res.first->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
TexturePtr FontTextureGroup::glyphTexturePtr(String::Char c, unsigned size) {
|
||||||
|
return glyphTexture(c, size, "").texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
TexturePtr FontTextureGroup::glyphTexturePtr(String::Char c, unsigned size, String const& processingDirectives) {
|
||||||
|
return glyphTexture(c, size, processingDirectives).texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned FontTextureGroup::glyphWidth(String::Char c, unsigned fontSize) {
|
unsigned FontTextureGroup::glyphWidth(String::Char c, unsigned fontSize) {
|
||||||
|
@ -11,24 +11,27 @@ STAR_CLASS(FontTextureGroup);
|
|||||||
|
|
||||||
class FontTextureGroup {
|
class FontTextureGroup {
|
||||||
public:
|
public:
|
||||||
|
typedef tuple<String::Char, unsigned, String> GlyphDescriptor;
|
||||||
|
|
||||||
|
struct GlyphTexture {
|
||||||
|
TexturePtr texture;
|
||||||
|
int64_t time;
|
||||||
|
Vec2F processingOffset;
|
||||||
|
};
|
||||||
|
|
||||||
FontTextureGroup(FontPtr font, TextureGroupPtr textureGroup);
|
FontTextureGroup(FontPtr font, TextureGroupPtr textureGroup);
|
||||||
|
|
||||||
TexturePtr glyphTexture(String::Char, unsigned fontSize);
|
const GlyphTexture& glyphTexture(String::Char, unsigned fontSize, String const& processingDirectives);
|
||||||
TexturePtr glyphTexture(String::Char, unsigned fontSize, String const& processingDirectives);
|
|
||||||
|
TexturePtr glyphTexturePtr(String::Char, unsigned fontSize);
|
||||||
|
TexturePtr glyphTexturePtr(String::Char, unsigned fontSize, String const& processingDirectives);
|
||||||
|
|
||||||
unsigned glyphWidth(String::Char c, unsigned fontSize);
|
unsigned glyphWidth(String::Char c, unsigned fontSize);
|
||||||
|
|
||||||
// Removes glyphs that haven't been used in more than the given time in
|
// Removes glyphs that haven't been used in more than the given time in
|
||||||
// milliseconds
|
// milliseconds
|
||||||
void cleanup(int64_t timeout);
|
void cleanup(int64_t timeout);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef tuple<String::Char, unsigned, String> GlyphDescriptor;
|
|
||||||
|
|
||||||
struct GlyphTexture {
|
|
||||||
TexturePtr texture;
|
|
||||||
int64_t time;
|
|
||||||
};
|
|
||||||
|
|
||||||
FontPtr m_font;
|
FontPtr m_font;
|
||||||
TextureGroupPtr m_textureGroup;
|
TextureGroupPtr m_textureGroup;
|
||||||
|
@ -379,9 +379,16 @@ RectF TextPainter::doRenderGlyph(String::Char c, TextPositioning const& position
|
|||||||
if (reallyRender) {
|
if (reallyRender) {
|
||||||
if ((int)m_renderSettings.mode & (int)FontMode::Shadow) {
|
if ((int)m_renderSettings.mode & (int)FontMode::Shadow) {
|
||||||
Color shadow = Color::Black;
|
Color shadow = Color::Black;
|
||||||
shadow.setAlpha(m_renderSettings.color[3]);
|
uint8_t alphaU = m_renderSettings.color[3];
|
||||||
|
if (alphaU != 255) {
|
||||||
|
float alpha = byteToFloat(alphaU);
|
||||||
|
shadow.setAlpha(floatToByte(alpha * (1.5f - 0.5f * alpha)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
shadow.setAlpha(alphaU);
|
||||||
|
|
||||||
|
//Kae: Draw only one shadow glyph instead of stacking two, alpha modified to appear perceptually the same as vanilla
|
||||||
renderGlyph(c, position.pos + Vec2F(hOffset, vOffset - 2), m_fontSize, 1, shadow.toRgba(), m_processingDirectives);
|
renderGlyph(c, position.pos + Vec2F(hOffset, vOffset - 2), m_fontSize, 1, shadow.toRgba(), m_processingDirectives);
|
||||||
renderGlyph(c, position.pos + Vec2F(hOffset, vOffset - 1), m_fontSize, 1, shadow.toRgba(), m_processingDirectives);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
renderGlyph(c, position.pos + Vec2F(hOffset, vOffset), m_fontSize, 1, m_renderSettings.color, m_processingDirectives);
|
renderGlyph(c, position.pos + Vec2F(hOffset, vOffset), m_fontSize, 1, m_renderSettings.color, m_processingDirectives);
|
||||||
@ -395,8 +402,9 @@ void TextPainter::renderGlyph(String::Char c, Vec2F const& screenPos, unsigned f
|
|||||||
if (!fontSize)
|
if (!fontSize)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto texture = m_fontTextureGroup.glyphTexture(c, fontSize, processingDirectives);
|
const FontTextureGroup::GlyphTexture& glyphTexture = m_fontTextureGroup.glyphTexture(c, fontSize, processingDirectives);
|
||||||
m_renderer->render(renderTexturedRect(move(texture), Vec2F(screenPos), scale, color, 0.0f));
|
Vec2F offset = glyphTexture.processingOffset * (scale * 0.5f); //Kae: Re-center the glyph if the image scale was changed by the directives (it is positioned from the bottom left)
|
||||||
|
m_renderer->render(renderTexturedRect(glyphTexture.texture, Vec2F(screenPos) + offset, scale, color, 0.0f));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -60,8 +60,8 @@ void CanvasWidget::drawTriangles(List<tuple<Vec2F, Vec2F, Vec2F>> const& triangl
|
|||||||
m_renderOps.append(make_tuple(triangles, color));
|
m_renderOps.append(make_tuple(triangles, color));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CanvasWidget::drawText(String s, TextPositioning position, unsigned fontSize, Vec4B const& color, FontMode mode, float lineSpacing) {
|
void CanvasWidget::drawText(String s, TextPositioning position, unsigned fontSize, Vec4B const& color, FontMode mode, float lineSpacing, String processingDirectives) {
|
||||||
m_renderOps.append(make_tuple(move(s), move(position), fontSize, color, mode, lineSpacing));
|
m_renderOps.append(make_tuple(move(s), move(position), fontSize, color, mode, lineSpacing, move(processingDirectives)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec2I CanvasWidget::mousePosition() const {
|
Vec2I CanvasWidget::mousePosition() const {
|
||||||
@ -137,7 +137,7 @@ void CanvasWidget::renderImpl() {
|
|||||||
if (auto args = op.ptr<TrianglesOp>())
|
if (auto args = op.ptr<TrianglesOp>())
|
||||||
tupleUnpackFunction(bind(&CanvasWidget::renderTriangles, this, renderingOffset, _1, _2), *args);
|
tupleUnpackFunction(bind(&CanvasWidget::renderTriangles, this, renderingOffset, _1, _2), *args);
|
||||||
if (auto args = op.ptr<TextOp>())
|
if (auto args = op.ptr<TextOp>())
|
||||||
tupleUnpackFunction(bind(&CanvasWidget::renderText, this, renderingOffset, _1, _2, _3, _4, _5, _6), *args);
|
tupleUnpackFunction(bind(&CanvasWidget::renderText, this, renderingOffset, _1, _2, _3, _4, _5, _6, _7), *args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -222,8 +222,9 @@ void CanvasWidget::renderTriangles(Vec2F const& renderingOffset, List<tuple<Vec2
|
|||||||
context.drawInterfaceTriangles(translated, color);
|
context.drawInterfaceTriangles(translated, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CanvasWidget::renderText(Vec2F const& renderingOffset, String const& s, TextPositioning const& position, unsigned fontSize, Vec4B const& color, FontMode mode, float lineSpacing) {
|
void CanvasWidget::renderText(Vec2F const& renderingOffset, String const& s, TextPositioning const& position, unsigned fontSize, Vec4B const& color, FontMode mode, float lineSpacing, String const& directives) {
|
||||||
auto& context = GuiContext::singleton();
|
auto& context = GuiContext::singleton();
|
||||||
|
context.setFontProcessingDirectives(directives);
|
||||||
context.setFontSize(fontSize);
|
context.setFontSize(fontSize);
|
||||||
context.setFontColor(color);
|
context.setFontColor(color);
|
||||||
context.setFontMode(mode);
|
context.setFontMode(mode);
|
||||||
@ -233,6 +234,7 @@ void CanvasWidget::renderText(Vec2F const& renderingOffset, String const& s, Tex
|
|||||||
translatedPosition.pos += renderingOffset;
|
translatedPosition.pos += renderingOffset;
|
||||||
context.renderInterfaceText(s, translatedPosition);
|
context.renderInterfaceText(s, translatedPosition);
|
||||||
context.setDefaultLineSpacing();
|
context.setDefaultLineSpacing();
|
||||||
|
context.setFontProcessingDirectives("");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,7 @@ public:
|
|||||||
void drawPoly(PolyF const& poly, Vec4B const& color = Vec4B(255, 255, 255, 255), float lineWidth = 1.0f);
|
void drawPoly(PolyF const& poly, Vec4B const& color = Vec4B(255, 255, 255, 255), float lineWidth = 1.0f);
|
||||||
void drawTriangles(List<tuple<Vec2F, Vec2F, Vec2F>> const& poly, Vec4B const& color = Vec4B(255, 255, 255, 255));
|
void drawTriangles(List<tuple<Vec2F, Vec2F, Vec2F>> const& poly, Vec4B const& color = Vec4B(255, 255, 255, 255));
|
||||||
|
|
||||||
void drawText(String s, TextPositioning position, unsigned fontSize, Vec4B const& color = Vec4B(255, 255, 255, 255), FontMode mode = FontMode::Normal, float lineSpacing = Star::DefaultLineSpacing);
|
void drawText(String s, TextPositioning position, unsigned fontSize, Vec4B const& color = Vec4B(255, 255, 255, 255), FontMode mode = FontMode::Normal, float lineSpacing = Star::DefaultLineSpacing, String processingDirectives = "");
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void renderImpl() override;
|
void renderImpl() override;
|
||||||
@ -78,7 +78,7 @@ protected:
|
|||||||
void renderRect(Vec2F const& renderingOffset, RectF const& coords, Vec4B const& color);
|
void renderRect(Vec2F const& renderingOffset, RectF const& coords, Vec4B const& color);
|
||||||
void renderPoly(Vec2F const& renderingOffset, PolyF poly, Vec4B const& color, float lineWidth);
|
void renderPoly(Vec2F const& renderingOffset, PolyF poly, Vec4B const& color, float lineWidth);
|
||||||
void renderTriangles(Vec2F const& renderingOffset, List<tuple<Vec2F, Vec2F, Vec2F>> const& triangles, Vec4B const& color);
|
void renderTriangles(Vec2F const& renderingOffset, List<tuple<Vec2F, Vec2F, Vec2F>> const& triangles, Vec4B const& color);
|
||||||
void renderText(Vec2F const& renderingOffset, String const& s, TextPositioning const& position, unsigned fontSize, Vec4B const& color, FontMode mode, float lineSpacing);
|
void renderText(Vec2F const& renderingOffset, String const& s, TextPositioning const& position, unsigned fontSize, Vec4B const& color, FontMode mode, float lineSpacing, String const& directives);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_captureKeyboard;
|
bool m_captureKeyboard;
|
||||||
@ -95,7 +95,7 @@ private:
|
|||||||
typedef tuple<Vec2F, Vec2F, Vec4B, float> LineOp;
|
typedef tuple<Vec2F, Vec2F, Vec4B, float> LineOp;
|
||||||
typedef tuple<PolyF, Vec4B, float> PolyOp;
|
typedef tuple<PolyF, Vec4B, float> PolyOp;
|
||||||
typedef tuple<List<tuple<Vec2F, Vec2F, Vec2F>>, Vec4B> TrianglesOp;
|
typedef tuple<List<tuple<Vec2F, Vec2F, Vec2F>>, Vec4B> TrianglesOp;
|
||||||
typedef tuple<String, TextPositioning, unsigned, Vec4B, FontMode, float> TextOp;
|
typedef tuple<String, TextPositioning, unsigned, Vec4B, FontMode, float, String> TextOp;
|
||||||
|
|
||||||
typedef MVariant<RectOp, ImageOp, ImageRectOp, DrawableOp, TiledImageOp, LineOp, PolyOp, TrianglesOp, TextOp> RenderOp;
|
typedef MVariant<RectOp, ImageOp, ImageRectOp, DrawableOp, TiledImageOp, LineOp, PolyOp, TrianglesOp, TextOp> RenderOp;
|
||||||
List<RenderOp> m_renderOps;
|
List<RenderOp> m_renderOps;
|
||||||
|
Loading…
Reference in New Issue
Block a user