Merge pull request #571 from NQNStudios:scale-text
Gorgeous text in scaled mode Fix #316
This commit is contained in:
Binary file not shown.
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 26 KiB |
Binary file not shown.
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 12 KiB |
@@ -9,6 +9,7 @@
|
||||
|
||||
#include "button.hpp"
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include "dialogxml/dialogs/dialog.hpp"
|
||||
#include "gfx/render_image.hpp"
|
||||
#include "gfx/render_text.hpp"
|
||||
@@ -94,7 +95,16 @@ void cButton::draw(){
|
||||
for(size_t key_pos = label.find_first_of(KEY_PLACEHOLDER); key_pos < label.size(); key_pos = label.find_first_of(KEY_PLACEHOLDER)) {
|
||||
label.replace(key_pos, 1, keyDesc);
|
||||
}
|
||||
win_draw_string(*inWindow,to_rect,label,textMode,style);
|
||||
|
||||
std::vector<std::string> forced_lines;
|
||||
boost::split(forced_lines, label, boost::is_any_of("|"));
|
||||
if(forced_lines.size() > 1){
|
||||
to_rect.offset(0, (-style.pointSize/2) * (forced_lines.size() - 1));
|
||||
}
|
||||
for(std::string line : forced_lines){
|
||||
win_draw_string(*inWindow,to_rect,line,textMode,style);
|
||||
to_rect.offset(0, style.pointSize);
|
||||
}
|
||||
// frame default button, to provide a visual cue that it's the default
|
||||
if(key.spec && key.k == key_enter) drawFrame(2,frameStyle);
|
||||
}
|
||||
@@ -180,6 +190,10 @@ void cButton::validatePostParse(ticpp::Element& elem, std::string fname, const s
|
||||
if(getType() == CTRL_BTN && !attrs.count("type")) throw xMissingAttr(elem.Value(), "type", elem.Row(), elem.Column(), fname);
|
||||
if(type == BTN_PUSH && !getText().empty() && !attrs.count("width"))
|
||||
throw xMissingAttr(elem.Value(), "width", elem.Row(), elem.Column(), fname);
|
||||
|
||||
// This needs to happen again after parsing, which sets preset buttons' text to empty
|
||||
initPreset();
|
||||
|
||||
if(labelledButtons.count(type)) {
|
||||
if(!attrs.count("color") && !attrs.count("colour") && parent->getBg() == cDialog::BG_DARK)
|
||||
setColour(sf::Color::White);
|
||||
@@ -243,12 +257,12 @@ void cButton::init(){
|
||||
btnRects[BTN_RIGHT][0] = {46,0,69,63};
|
||||
btnRects[BTN_UP][0] = {69,0,92,63};
|
||||
btnRects[BTN_DOWN][0] = {92,0,115,63};
|
||||
btnRects[BTN_DONE][0] = {115,0,138,63};
|
||||
btnRects[BTN_DONE][0] = {0,0,23,63};
|
||||
btnRects[BTN_LG][0] = {0,0,23,102};
|
||||
btnRects[BTN_HELP][0] = {0,0,13,16};
|
||||
btnRects[BTN_TINY][0] = {0,42,10,56};
|
||||
btnRects[BTN_TALL][0] = {0,0,40,63};
|
||||
btnRects[BTN_TRAIT][0] = {40,0,80,63};
|
||||
btnRects[BTN_TRAIT][0] = {0,0,40,63};
|
||||
btnRects[BTN_PUSH][0] = {0,0,30,30};
|
||||
for(int j = 0; j <= 12; j++)
|
||||
btnRects[j][1] = btnRects[j][0];
|
||||
@@ -306,8 +320,20 @@ void cButton::setBtnType(eBtnType newType){
|
||||
frame.height() = std::min<int>(frame.height(), 10);
|
||||
break;
|
||||
}
|
||||
initPreset();
|
||||
}
|
||||
|
||||
eBtnType cButton::getBtnType() const {
|
||||
return type;
|
||||
}
|
||||
|
||||
void cButton::initPreset() {
|
||||
switch(type){
|
||||
case BTN_DONE:
|
||||
setText("Done");
|
||||
break;
|
||||
case BTN_TRAIT:
|
||||
setText("Race|& Traits");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@@ -43,6 +43,8 @@ public:
|
||||
/// Set the type of this button.
|
||||
/// @param newType The desired button type.
|
||||
void setBtnType(eBtnType newType);
|
||||
/// Initialize types of buttons that used to use their own custom sprite with baked-in text.
|
||||
void initPreset();
|
||||
/// Get the type of this button.
|
||||
/// @return The button type.
|
||||
eBtnType getBtnType() const;
|
||||
|
@@ -481,6 +481,9 @@ void end_startup() {
|
||||
}
|
||||
|
||||
static void loadImageToRenderTexture(sf::RenderTexture& tex, std::string imgName) {
|
||||
// Clear scale-aware text stored for the previous texture instance:
|
||||
clear_scale_aware_text(tex);
|
||||
|
||||
sf::Texture& temp_gworld = *ResMgr::graphics.get(imgName);
|
||||
rectangle texrect(temp_gworld);
|
||||
tex.create(texrect.width(), texrect.height());
|
||||
@@ -661,6 +664,7 @@ void put_text_bar(std::string str, std::string right_str) {
|
||||
text_bar_gworld.setActive(false);
|
||||
auto& bar_gw = *ResMgr::graphics.get("textbar");
|
||||
rect_draw_some_item(bar_gw, rectangle(bar_gw), text_bar_gworld, rectangle(bar_gw));
|
||||
clear_scale_aware_text(text_bar_gworld);
|
||||
TextStyle style;
|
||||
style.colour = sf::Color::White;
|
||||
style.font = FONT_BOLD;
|
||||
@@ -696,7 +700,7 @@ void put_text_bar(std::string str, std::string right_str) {
|
||||
|
||||
void refresh_text_bar() {
|
||||
mainPtr.setActive(false);
|
||||
rect_draw_some_item(text_bar_gworld.getTexture(), rectangle(text_bar_gworld), mainPtr, win_to_rects[WINRECT_STATUS]);
|
||||
rect_draw_some_item(text_bar_gworld, rectangle(text_bar_gworld), mainPtr, win_to_rects[WINRECT_STATUS]);
|
||||
mainPtr.setActive();
|
||||
}
|
||||
|
||||
|
@@ -708,11 +708,13 @@ void draw_shop_graphics(bool item_pressed, bool item_help_pressed, rectangle cli
|
||||
|
||||
area_rect = rectangle(talk_gworld);
|
||||
talk_gworld.setActive(false);
|
||||
|
||||
// Only re-render on top of the item that is clicked:
|
||||
if(item_pressed || item_help_pressed) {
|
||||
clip_area_rect.offset(-area_rect.left, -area_rect.top);
|
||||
clip_rect(talk_gworld, clip_area_rect);
|
||||
} else {
|
||||
clear_scale_aware_text(talk_gworld);
|
||||
frame_rect(talk_gworld, area_rect, Colours::BLACK);
|
||||
area_rect.inset(1,1);
|
||||
tileImage(talk_gworld, area_rect,bg[12]);
|
||||
@@ -870,7 +872,7 @@ void refresh_shopping() {
|
||||
rectangle from_rect(talk_gworld);
|
||||
rectangle to_rect = from_rect;
|
||||
to_rect.offset(talk_gword_offset_x, talk_gword_offset_y);
|
||||
rect_draw_some_item(talk_gworld.getTexture(),from_rect,mainPtr,to_rect);
|
||||
rect_draw_some_item(talk_gworld,from_rect,mainPtr,to_rect);
|
||||
}
|
||||
|
||||
static void place_talk_face() {
|
||||
@@ -898,7 +900,7 @@ void click_talk_rect(word_rect_t word) {
|
||||
|
||||
rectangle talkRect(talk_gworld), wordRect(word.rect);
|
||||
mainPtr.setActive();
|
||||
rect_draw_some_item(talk_gworld.getTexture(),talkRect,mainPtr,talk_area_rect);
|
||||
rect_draw_some_item(talk_gworld,talkRect,mainPtr,talk_area_rect);
|
||||
wordRect.offset(talk_area_rect.topLeft());
|
||||
wordRect.width() += 10; // Arbitrary extra space fixes #481 and shouldn't cause any problems
|
||||
TextStyle style;
|
||||
@@ -911,7 +913,7 @@ void click_talk_rect(word_rect_t word) {
|
||||
help_btn->draw();
|
||||
mainPtr.display();
|
||||
play_sound(37, time_in_ticks(5));
|
||||
rect_draw_some_item(talk_gworld.getTexture(),talkRect,mainPtr,talk_area_rect);
|
||||
rect_draw_some_item(talk_gworld,talkRect,mainPtr,talk_area_rect);
|
||||
place_talk_face();
|
||||
}
|
||||
|
||||
@@ -921,7 +923,6 @@ void place_talk_str(std::string str_to_place,std::string str_to_place2,short col
|
||||
|
||||
rectangle title_rect = {19,48,42,260};
|
||||
rectangle dest_rect,help_from = {46,60,59,76};
|
||||
sf::Text str_to_draw;
|
||||
|
||||
talk_gworld.setActive(false);
|
||||
|
||||
@@ -936,6 +937,7 @@ void place_talk_str(std::string str_to_place,std::string str_to_place2,short col
|
||||
}
|
||||
|
||||
area_rect = rectangle(talk_gworld);
|
||||
clear_scale_aware_text(talk_gworld);
|
||||
frame_rect(talk_gworld, area_rect, sf::Color::Black);
|
||||
area_rect.inset(1,1);
|
||||
tileImage(talk_gworld, area_rect,bg[12]);
|
||||
@@ -1003,14 +1005,14 @@ void place_talk_str(std::string str_to_place,std::string str_to_place2,short col
|
||||
|
||||
// Finally place processed graphics
|
||||
mainPtr.setActive();
|
||||
rect_draw_some_item(talk_gworld.getTexture(),oldRect,mainPtr,talk_area_rect);
|
||||
rect_draw_some_item(talk_gworld,oldRect,mainPtr,talk_area_rect);
|
||||
// I have no idea what this check is for; I'm jsut preserving it in case it was important
|
||||
if(c_rect.right == 0) place_talk_face();
|
||||
}
|
||||
|
||||
void refresh_talking() {
|
||||
rectangle tempRect(talk_gworld);
|
||||
rect_draw_some_item(talk_gworld.getTexture(),tempRect,mainPtr,talk_area_rect);
|
||||
rect_draw_some_item(talk_gworld,tempRect,mainPtr,talk_area_rect);
|
||||
place_talk_face();
|
||||
}
|
||||
|
||||
|
@@ -97,6 +97,7 @@ void put_pc_screen() {
|
||||
rectangle info_from = {0,1,12,13}, switch_from = {0, 13, 12, 25};
|
||||
|
||||
pc_stats_gworld.setActive(false);
|
||||
clear_scale_aware_text(pc_stats_gworld);
|
||||
|
||||
// First clean up gworld with pretty patterns
|
||||
sf::Texture& orig = *ResMgr::graphics.get("statarea");
|
||||
@@ -219,6 +220,7 @@ void put_item_screen(eItemWinMode screen_num) {
|
||||
rectangle upper_frame_rect = {3,3,15,268};
|
||||
|
||||
item_stats_gworld.setActive(false);
|
||||
clear_scale_aware_text(item_stats_gworld);
|
||||
|
||||
// First clean up gworld with pretty patterns
|
||||
sf::Texture& orig = *ResMgr::graphics.get("inventory");
|
||||
@@ -588,9 +590,9 @@ void refresh_stat_areas(short mode) {
|
||||
|
||||
if(mode == 1) x = sf::BlendAdd;
|
||||
else x = sf::BlendNone;
|
||||
rect_draw_some_item(pc_stats_gworld.getTexture(), rectangle(pc_stats_gworld), mainPtr, win_to_rects[WINRECT_PCSTATS], x);
|
||||
rect_draw_some_item(item_stats_gworld.getTexture(), rectangle(item_stats_gworld), mainPtr, win_to_rects[WINRECT_INVEN], x);
|
||||
rect_draw_some_item(text_area_gworld.getTexture(), rectangle(text_area_gworld), mainPtr, win_to_rects[WINRECT_TRANSCRIPT], x);
|
||||
rect_draw_some_item(pc_stats_gworld, rectangle(pc_stats_gworld), mainPtr, win_to_rects[WINRECT_PCSTATS], x);
|
||||
rect_draw_some_item(item_stats_gworld, rectangle(item_stats_gworld), mainPtr, win_to_rects[WINRECT_INVEN], x);
|
||||
rect_draw_some_item(text_area_gworld, rectangle(text_area_gworld), mainPtr, win_to_rects[WINRECT_TRANSCRIPT], x);
|
||||
}
|
||||
|
||||
rectangle get_stat_effect_rect(int code) {
|
||||
@@ -1068,6 +1070,7 @@ void print_buf () {
|
||||
rectangle store_text_rect,dest_rect,erase_rect = {2,2,136,255};
|
||||
|
||||
text_area_gworld.setActive(false);
|
||||
clear_scale_aware_text(text_area_gworld);
|
||||
|
||||
// First clean up gworld with pretty patterns
|
||||
tileImage(text_area_gworld, erase_rect,bg[6]);
|
||||
@@ -1084,7 +1087,7 @@ void print_buf () {
|
||||
sf::Text text(text_buffer[line_to_print].line, *ResMgr::fonts.get("plain"), 12);
|
||||
text.setColor(Colours::BLACK);
|
||||
text.setPosition(moveTo);
|
||||
text_area_gworld.draw(text);
|
||||
draw_scale_aware_text(text_area_gworld, text);
|
||||
num_lines_printed++;
|
||||
line_to_print++;
|
||||
if(line_to_print== TEXT_BUF_LEN) {
|
||||
|
@@ -14,6 +14,7 @@
|
||||
|
||||
#include "fileio/fileio.hpp"
|
||||
#include "gfx/render_shapes.hpp"
|
||||
#include "winutil.hpp"
|
||||
|
||||
sf::Shader maskShader;
|
||||
extern fs::path progDir;
|
||||
@@ -121,6 +122,32 @@ void rect_draw_some_item(const sf::Texture& src_gworld,rectangle src_rect,const
|
||||
rect_draw_some_item(src.getTexture(), dest_rect, targ_gworld, targ_rect, &maskShader);
|
||||
}
|
||||
|
||||
std::map<sf::RenderTexture*,std::vector<sf::Text>> store_scale_aware_text;
|
||||
|
||||
static void draw_stored_scale_aware_text(sf::RenderTexture& texture, sf::RenderTarget& dest_window, rectangle targ_rect) {
|
||||
// Temporarily switch target window to its unscaled view to draw scale-aware text
|
||||
sf::View view = dest_window.getView();
|
||||
dest_window.setView(dest_window.getDefaultView());
|
||||
std::vector<sf::Text> stored_text = store_scale_aware_text[&texture];
|
||||
for(sf::Text str_to_draw : stored_text){
|
||||
sf::Vector2f position = str_to_draw.getPosition();
|
||||
position = position + sf::Vector2f {0.0f+targ_rect.left, 0.0f+targ_rect.top};
|
||||
str_to_draw.setPosition(position * (float)get_ui_scale());
|
||||
dest_window.draw(str_to_draw);
|
||||
}
|
||||
dest_window.setView(view);
|
||||
}
|
||||
|
||||
void rect_draw_some_item(sf::RenderTexture& src_render_gworld,rectangle src_rect,sf::RenderTarget& targ_gworld,rectangle targ_rect,sf::BlendMode mode) {
|
||||
rect_draw_some_item(src_render_gworld.getTexture(), src_rect, targ_gworld, targ_rect, mode);
|
||||
draw_stored_scale_aware_text(src_render_gworld, targ_gworld, targ_rect);
|
||||
}
|
||||
|
||||
void rect_draw_some_item(sf::RenderTexture& src_render_gworld,rectangle src_rect,const sf::Texture& mask_gworld,sf::RenderTarget& targ_gworld,rectangle targ_rect) {
|
||||
rect_draw_some_item(src_render_gworld.getTexture(), src_rect, mask_gworld, targ_gworld, targ_rect);
|
||||
draw_stored_scale_aware_text(src_render_gworld, targ_gworld, targ_rect);
|
||||
}
|
||||
|
||||
void setActiveRenderTarget(sf::RenderTarget& where) {
|
||||
const std::type_info& type = typeid(where);
|
||||
if(type == typeid(sf::RenderWindow&))
|
||||
|
@@ -22,7 +22,9 @@ void init_shaders();
|
||||
void rect_draw_some_item(sf::RenderTarget& targ_gworld,rectangle targ_rect);
|
||||
void rect_draw_some_item(const sf::Texture& src_gworld,rectangle src_rect,sf::RenderTarget& targ_gworld,rectangle targ_rect,sf::BlendMode mode = sf::BlendNone);
|
||||
void rect_draw_some_item(const sf::Texture& src_gworld,rectangle src_rect,sf::RenderTarget& targ_gworld,rectangle targ_rect,rectangle in_frame,sf::BlendMode mode = sf::BlendNone);
|
||||
void rect_draw_some_item(sf::RenderTexture& src_render_gworld,rectangle src_rect,sf::RenderTarget& targ_gworld,rectangle targ_rect,sf::BlendMode mode = sf::BlendNone);
|
||||
void rect_draw_some_item(const sf::Texture& src_gworld,rectangle src_rect,const sf::Texture& mask_gworld,sf::RenderTarget& targ_gworld,rectangle targ_rect);
|
||||
void rect_draw_some_item(sf::RenderTexture& src_render_gworld,rectangle src_rect,const sf::Texture& mask_gworld,sf::RenderTarget& targ_gworld,rectangle targ_rect);
|
||||
void draw_splash(const sf::Texture& splash, sf::RenderWindow& targ, rectangle dest_rect);
|
||||
|
||||
void setActiveRenderTarget(sf::RenderTarget& where);
|
||||
|
@@ -12,6 +12,7 @@
|
||||
#include "fileio/resmgr/res_font.hpp"
|
||||
#include "gfx/render_shapes.hpp"
|
||||
#include <utility>
|
||||
#include "winutil.hpp"
|
||||
|
||||
void TextStyle::applyTo(sf::Text& text) {
|
||||
switch(font) {
|
||||
@@ -134,6 +135,35 @@ break_info_t calculate_line_wrapping(rectangle dest_rect, std::string str, TextS
|
||||
return break_info;
|
||||
}
|
||||
|
||||
// I don't know of a better way to do this than using pointers as keys.
|
||||
extern std::map<sf::RenderTexture*,std::vector<sf::Text>> store_scale_aware_text;
|
||||
|
||||
void clear_scale_aware_text(sf::RenderTexture& texture) {
|
||||
store_scale_aware_text.erase(&texture);
|
||||
}
|
||||
|
||||
void draw_scale_aware_text(sf::RenderTarget& dest_window, sf::Text str_to_draw) {
|
||||
str_to_draw.setCharacterSize(str_to_draw.getCharacterSize() * get_ui_scale());
|
||||
|
||||
if(dynamic_cast<sf::RenderWindow*>(&dest_window) != nullptr){
|
||||
str_to_draw.setPosition(str_to_draw.getPosition() * (float)get_ui_scale());
|
||||
// Temporarily switch window to its unscaled view to draw scale-aware text
|
||||
sf::View view = dest_window.getView();
|
||||
dest_window.setView(dest_window.getDefaultView());
|
||||
dest_window.draw(str_to_draw);
|
||||
dest_window.setView(view);
|
||||
}else if(dynamic_cast<sf::RenderTexture*>(&dest_window) != nullptr){
|
||||
sf::RenderTexture* p = dynamic_cast<sf::RenderTexture*>(&dest_window);
|
||||
// Onto a RenderTexture is trickier because the texture is locked at the smaller size.
|
||||
// What we can do is save the sf::Text with its relative position and render
|
||||
// it onto the RenderWindow that eventually draws the RenderTexture.
|
||||
if(store_scale_aware_text.find(p) == store_scale_aware_text.end()){
|
||||
store_scale_aware_text[p] = std::vector<sf::Text> {};
|
||||
}
|
||||
store_scale_aware_text[p].push_back(str_to_draw);
|
||||
}
|
||||
}
|
||||
|
||||
static void win_draw_string(sf::RenderTarget& dest_window,rectangle dest_rect,std::string str,text_params_t& options) {
|
||||
if(str.empty()) return; // Nothing to do!
|
||||
short line_height = options.style.lineHeight;
|
||||
@@ -227,11 +257,7 @@ static void win_draw_string(sf::RenderTarget& dest_window,rectangle dest_rect,st
|
||||
bounds.inset(0,-4);
|
||||
fill_rect(dest_window, bounds, options.hilite_bg);
|
||||
} else str_to_draw.setColor(options.style.colour);
|
||||
dest_window.draw(str_to_draw);
|
||||
if(options.style.font == FONT_BOLD) {
|
||||
str_to_draw.move(1, 0);
|
||||
dest_window.draw(str_to_draw);
|
||||
}
|
||||
draw_scale_aware_text(dest_window, str_to_draw);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -57,6 +57,8 @@ enum class eTextMode {
|
||||
|
||||
std::vector<rectangle> draw_string_hilite(sf::RenderTarget& dest_window,rectangle dest_rect,std::string str,TextStyle style,std::vector<hilite_t> hilites,sf::Color hiliteClr);
|
||||
std::vector<snippet_t> draw_string_sel(sf::RenderTarget& dest_window,rectangle dest_rect,std::string str,TextStyle style,std::vector<hilite_t> hilites,sf::Color hiliteClr);
|
||||
void draw_scale_aware_text(sf::RenderTarget& dest_window, sf::Text str_to_draw);
|
||||
void clear_scale_aware_text(sf::RenderTexture& texture);
|
||||
void win_draw_string(sf::RenderTarget& dest_window,rectangle dest_rect,std::string str,eTextMode mode,TextStyle style,bool right_align = false);
|
||||
void win_draw_string(sf::RenderTarget& dest_window,rectangle dest_rect,std::string str,eTextMode mode,TextStyle style, break_info_t break_info,bool right_align = false);
|
||||
break_info_t calculate_line_wrapping(rectangle dest_rect, std::string str, TextStyle style);
|
||||
|
Reference in New Issue
Block a user