Beispiel #1
0
static void add_prefixes(const ucs4::string& str, size_t length, markov_prefix_map& res)
{
	for(size_t i = 0; i <= str.size(); ++i) {
		const size_t start = i > length ? i - length : 0;
		const ucs4::string key(str.begin() + start, str.begin() + i);
		const ucs4::char_t c = i != str.size() ? str[i] : 0;
		res[key].push_back(c);
	}
}
Beispiel #2
0
bool addon_filename_legal(const std::string& name)
{
	if(name.empty() || name.back() == '.' ||
	   name.find("..") != std::string::npos ||
	   name.size() > 255) {
		return false;
	} else {
		// NOTE: We can't use filesystem::base_name() here, since it returns
		//       the filename up to the *last* dot. "CON.foo.bar" in
		//       "CON.foo.bar.baz" is still redirected to "CON" on Windows;
		//       the base_name() approach would cause the name to not match
		//       any entries on our blacklist.
		//       Do also note that we're relying on the next check after this
		//       to flag the name as illegal if it contains a ':' -- a
		//       trailing colon is a valid way to refer to DOS device names,
		//       meaning that e.g. "CON:" is equivalent to "CON".
		const std::string stem = boost::algorithm::to_upper_copy(name.substr(0, name.find('.')), std::locale::classic());
		if(dos_device_names.find(stem) != dos_device_names.end()) {
			return false;
		}

		const ucs4::string name_ucs4 = unicode_cast<ucs4::string>(name);
		const std::string name_utf8 = unicode_cast<utf8::string>(name_ucs4);
		if(name != name_utf8){ // name is invalid UTF-8
			return false;
		}
		return std::find_if(name_ucs4.begin(), name_ucs4.end(), addon_filename_ucs4char_illegal()) == name_ucs4.end();
	}
}
Beispiel #3
0
surface textbox::add_text_line(const ucs4::string& text, const SDL_Color& color)
{
	line_height_ = font::get_max_height(font_size_);

	if(char_y_.empty()) {
		char_y_.push_back(0);
	} else {
		char_y_.push_back(char_y_.back() + line_height_);
	}

	char_x_.push_back(0);

	// Re-calculate the position of each glyph. We approximate this by asking the
	// width of each substring, but this is a flawed assumption which won't work with
	// some more complex scripts (that is, RTL languages). This part of the work should
	// actually be done by the font-rendering system.
	std::string visible_string;
	ucs4::string wrapped_text;

	ucs4::string::const_iterator backup_itor = text.end();

	ucs4::string::const_iterator itor = text.begin();
	while(itor != text.end()) {
		//If this is a space, save copies of the current state so we can roll back
		if(char(*itor) == ' ') {
			backup_itor = itor;
		}
		visible_string.append(utils::ucs4char_to_string(*itor));

		if(char(*itor) == '\n') {
			backup_itor = text.end();
			visible_string = "";
		}

		int w = font::line_width(visible_string, font_size_);

		if(wrap_ && w >= inner_location().w) {
			if(backup_itor != text.end()) {
				int backup = itor - backup_itor;
				itor = backup_itor + 1;
				if(backup > 0) {
					char_x_.erase(char_x_.end()-backup, char_x_.end());
					char_y_.erase(char_y_.end()-backup, char_y_.end());
					wrapped_text.erase(wrapped_text.end()-backup, wrapped_text.end());
				}
			}
			backup_itor = text.end();
			wrapped_text.push_back(ucs4::char_t('\n'));
			char_x_.push_back(0);
			char_y_.push_back(char_y_.back() + line_height_);
			visible_string = "";
		} else {
			wrapped_text.push_back(*itor);
			char_x_.push_back(w);
			char_y_.push_back(char_y_.back() + (char(*itor) == '\n' ? line_height_ : 0));
			++itor;
		}
	}

	const std::string s = utils::ucs4string_to_string(wrapped_text);
	const surface res(font::get_rendered_text(s, font_size_, color));

	return res;
}