Skip to content

Commit

Permalink
add "link awareness" to font::ttext objects
Browse files Browse the repository at this point in the history
If link awareness is enabled, then tokens that look like links
will be rendered thusly, and a "get_link" function is provided
to check if a layout location is pointing to a token which was
rendered as a link.
  • Loading branch information
cbeck88 committed Oct 19, 2014
1 parent 676db81 commit 854688b
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 1 deletion.
72 changes: 71 additions & 1 deletion src/text.cpp
Expand Up @@ -68,6 +68,8 @@ const unsigned ttext::STYLE_BOLD = TTF_STYLE_BOLD;
const unsigned ttext::STYLE_ITALIC = TTF_STYLE_ITALIC;
const unsigned ttext::STYLE_UNDERLINE = TTF_STYLE_UNDERLINE;

static bool looks_like_url(const std::string & token);

std::string escape_text(const std::string& text)
{
std::string result;
Expand Down Expand Up @@ -99,6 +101,7 @@ ttext::ttext() :
#endif
text_(),
markedup_text_(false),
link_aware_(false),
font_size_(14),
font_style_(STYLE_NORMAL),
foreground_color_(0xFFFFFFFF), // solid white
Expand Down Expand Up @@ -301,6 +304,21 @@ std::string ttext::get_token(const gui2::tpoint & position, const char * delim)
return txt.substr(l,r-l);
}

std::string ttext::get_link(const gui2::tpoint & position) const
{
if (!link_aware_) {
return "";
}

std::string tok = get_token(position, " \n\r\t");

if (looks_like_url(tok)) {
return tok;
} else {
return "";
}
}

gui2::tpoint ttext::get_column_line(const gui2::tpoint& position) const
{
recalculate();
Expand Down Expand Up @@ -509,6 +527,16 @@ ttext& ttext::set_maximum_length(const size_t maximum_length)
return *this;
}

ttext& ttext::set_link_aware(bool b)
{
if (link_aware_ != b) {
calculation_dirty_ = true;
surface_dirty_ = true;
link_aware_ = b;
}
return *this;
}

namespace {

/** Small helper class to make sure the font object is destroyed properly. */
Expand Down Expand Up @@ -758,7 +786,49 @@ void ttext::create_surface_buffer(const size_t size) const
memset(surface_buffer_, 0, size);
}

bool ttext::set_markup(const std::string& text)
static std::string handle_token(const std::string & token);

bool ttext::set_markup(const std::string & text) {
if (!link_aware_) {
return set_markup_helper(text);
} else {
std::string delim = " \n\r\t";

// Tokenize according to these delimiters, and stream the results of `handle_token` on each token to get the new text.

std::stringstream ss;

int last_delim = -1;
for (size_t index = 0; index < text.size(); ++index) {
if (delim.find(text.at(index)) != std::string::npos) {
ss << handle_token(text.substr(last_delim + 1, index - last_delim - 1)); // want to include chars from range since last token, dont want to include any delimiters
ss << text.at(index);
last_delim = index;
}
}
if (last_delim < static_cast<int>(text.size()) - 1) {
ss << handle_token(text.substr(last_delim + 1, text.size() - last_delim - 1));
}

return set_markup_helper(ss.str());
}
}

static bool looks_like_url(const std::string & str)
{
return (str.size() >= 8) && ((str.substr(0,7) == "http://") || (str.substr(0,8) == "https://"));
}

static std::string handle_token(const std::string & token)
{
if (looks_like_url(token)) {
return "<span underline=\'single\' color=\'#8888ff\'>" + token + "</span>";
} else {
return token;
}
}

bool ttext::set_markup_helper(const std::string& text)
{
if(pango_parse_markup(text.c_str(), text.size()
, 0, NULL, NULL, NULL, NULL)) {
Expand Down
16 changes: 16 additions & 0 deletions src/text.hpp
Expand Up @@ -174,6 +174,15 @@ class ttext
*/
std::string get_token(const gui2::tpoint & position, const char * delimiters = " \n\r\t") const;

/**
* Checks if position points to a character in a link in the text, returns it
* if so, empty string otherwise. Link-awareness must be enabled to get results.
* @param position The pixel position in the text area.
*
* @returns The link if one is found, the empty string otherwise.
*/
std::string get_link(const gui2::tpoint & position) const;

/**
* Gets the column of line of the character at the position.
*
Expand Down Expand Up @@ -231,6 +240,9 @@ class ttext

ttext& set_maximum_length(const size_t maximum_length);

bool link_aware() const { return link_aware_; }

ttext& set_link_aware(bool b);
private:

/***** ***** ***** ***** Pango variables ***** ***** ***** *****/
Expand All @@ -256,6 +268,9 @@ class ttext
/** Is the text markedup if so the markedup render routines need to be used. */
bool markedup_text_;

/** Are hyperlinks in the text marked-up, and will get_link return them. */
bool link_aware_;

/** The font size to draw. */
unsigned font_size_;

Expand Down Expand Up @@ -381,6 +396,7 @@ class ttext
*/
bool set_markup(const std::string& text);

bool set_markup_helper(const std::string & text);
};

} // namespace font
Expand Down

0 comments on commit 854688b

Please sign in to comment.