Example #1
0
Error RichTextLabel::append_bbcode(const String& p_bbcode) {

	int pos = 0;

	List<String> tag_stack;
	Ref<Font> normal_font=get_font("normal_font");
	Ref<Font> bold_font=get_font("bold_font");
	Ref<Font> italics_font=get_font("italics_font");
	Ref<Font> bold_italics_font=get_font("bold_italics_font");
	Ref<Font> mono_font=get_font("mono_font");

	Color base_color=get_color("default_color");

	int indent_level=0;

	bool in_bold=false;
	bool in_italics=false;

	while(pos < p_bbcode.length()) {


		int brk_pos = p_bbcode.find("[",pos);

		if (brk_pos<0)
			brk_pos=p_bbcode.length();

		if (brk_pos > pos) {
			add_text(p_bbcode.substr(pos,brk_pos-pos));
		}

		if (brk_pos==p_bbcode.length())
			break; //nothing else o add

		int brk_end = p_bbcode.find("]",brk_pos+1);

		if (brk_end==-1) {
			//no close, add the rest
			add_text(p_bbcode.substr(brk_pos,p_bbcode.length()-brk_pos));
			break;
		}


		String tag = p_bbcode.substr(brk_pos+1,brk_end-brk_pos-1);


		if (tag.begins_with("/") && tag_stack.size()) {

			bool tag_ok = tag_stack.size() && tag_stack.front()->get()==tag.substr(1,tag.length());



			if (tag_stack.front()->get()=="b")
				in_bold=false;
			if (tag_stack.front()->get()=="i")
				in_italics=false;
			if (tag_stack.front()->get()=="indent")
				indent_level--;


			if (!tag_ok) {

				add_text("[");
				pos++;
				continue;
			}

			tag_stack.pop_front();
			pos=brk_end+1;
			if (tag!="/img")
				pop();

		} else if (tag=="b") {

			//use bold font
			in_bold=true;
			if (in_italics)
				push_font(bold_italics_font);
			else
				push_font(bold_font);
			pos=brk_end+1;
			tag_stack.push_front(tag);
		} else if (tag=="i") {

			//use italics font
			in_italics=true;
			if (in_bold)
				push_font(bold_italics_font);
			else
				push_font(italics_font);
			pos=brk_end+1;
			tag_stack.push_front(tag);
		} else if (tag=="code") {

			//use monospace font
			push_font(mono_font);
			pos=brk_end+1;
			tag_stack.push_front(tag);
		} else if (tag.begins_with("table=")) {

			int columns = tag.substr(6,tag.length()).to_int();
			if (columns<1)
				columns=1;
			//use monospace font
			push_table(columns);
			pos=brk_end+1;
			tag_stack.push_front("table");
		} else if (tag=="cell") {

			push_cell();
			pos=brk_end+1;
			tag_stack.push_front(tag);
		} else if (tag.begins_with("cell=")) {

			int ratio = tag.substr(6,tag.length()).to_int();
			if (ratio<1)
				ratio=1;
			//use monospace font
			set_table_column_expand(get_current_table_column(),true,ratio);
			push_cell();
			pos=brk_end+1;
			tag_stack.push_front("cell");
		} else if (tag=="u") {

			//use underline
			push_underline();
			pos=brk_end+1;
			tag_stack.push_front(tag);
		} else if (tag=="s") {

			//use strikethrough (not supported underline instead)
			push_underline();
			pos=brk_end+1;
			tag_stack.push_front(tag);
		} else if (tag=="center") {

			//use underline
			push_align(ALIGN_CENTER);
			pos=brk_end+1;
			tag_stack.push_front(tag);
		} else if (tag=="fill") {

			//use underline
			push_align(ALIGN_FILL);
			pos=brk_end+1;
			tag_stack.push_front(tag);
		} else if (tag=="right") {

			//use underline
			push_align(ALIGN_RIGHT);
			pos=brk_end+1;
			tag_stack.push_front(tag);
		} else if (tag=="ul") {

			//use underline
			push_list(LIST_DOTS);
			pos=brk_end+1;
			tag_stack.push_front(tag);
		} else if (tag=="ol") {

			//use underline
			push_list(LIST_NUMBERS);
			pos=brk_end+1;
			tag_stack.push_front(tag);
		} else if (tag=="indent") {

			//use underline
			indent_level++;
			push_indent(indent_level);
			pos=brk_end+1;
			tag_stack.push_front(tag);

		} else if (tag=="url") {

			//use strikethrough (not supported underline instead)
			int end=p_bbcode.find("[",brk_end);
			if (end==-1)
				end=p_bbcode.length();
			String url = p_bbcode.substr(brk_end+1,end-brk_end-1);
			push_meta(url);

			pos=brk_end+1;
			tag_stack.push_front(tag);

		} else if (tag.begins_with("url=")) {

			String url = tag.substr(4,tag.length());
			push_meta(url);
			pos=brk_end+1;
			tag_stack.push_front("url");
		} else if (tag=="img") {

			//use strikethrough (not supported underline instead)
			int end=p_bbcode.find("[",brk_end);
			if (end==-1)
				end=p_bbcode.length();
			String image = p_bbcode.substr(brk_end+1,end-brk_end-1);

			Ref<Texture> texture = ResourceLoader::load(image,"Texture");
			if (texture.is_valid())
				add_image(texture);

			pos=end;
			tag_stack.push_front(tag);
		} else if (tag.begins_with("color=")) {

			String col = tag.substr(6,tag.length());
			Color color;

			if (col.begins_with("#"))
				color=Color::html(col);
			else if (col=="aqua")
				color=Color::html("#00FFFF");
			else if (col=="black")
				color=Color::html("#000000");
			else if (col=="blue")
				color=Color::html("#0000FF");
			else if (col=="fuchsia")
				color=Color::html("#FF00FF");
			else if (col=="gray" || col=="grey")
				color=Color::html("#808080");
			else if (col=="green")
				color=Color::html("#008000");
			else if (col=="lime")
				color=Color::html("#00FF00");
			else if (col=="maroon")
				color=Color::html("#800000");
			else if (col=="navy")
				color=Color::html("#000080");
			else if (col=="olive")
				color=Color::html("#808000");
			else if (col=="purple")
				color=Color::html("#800080");
			else if (col=="red")
				color=Color::html("#FF0000");
			else if (col=="silver")
				color=Color::html("#C0C0C0");
			else if (col=="teal")
				color=Color::html("#008008");
			else if (col=="white")
				color=Color::html("#FFFFFF");
			else if (col=="yellow")
				color=Color::html("#FFFF00");
			else
				color=base_color;



			push_color(color);
			pos=brk_end+1;
			tag_stack.push_front("color");

		} else if (tag.begins_with("font=")) {

			String fnt = tag.substr(5,tag.length());


			Ref<Font> font = ResourceLoader::load(fnt,"Font");
			if (font.is_valid())
				push_font(font);
			else
				push_font(normal_font);

			pos=brk_end+1;
			tag_stack.push_front("font");


		} else {

			add_text("["); //ignore
			pos=brk_pos+1;

		}
	}

	return OK;
}
Example #2
0
meta* push_meta_to_stack(lua_State* L, meta s) {
    return push_meta(L, s);
}