Changeset - r10248:82b5afcc36bb
[Not reviewed]
master
0 2 0
rubidium - 16 years ago 2008-10-17 17:14:09
rubidium@openttd.org
(svn r14479) -Add: initial (optional) support for handling bidirectional scripts and connecting Arabic characters.
2 files changed with 189 insertions and 14 deletions:
0 comments (0 inline, 0 general)
config.lib
Show inline comments
 
@@ -60,24 +60,25 @@ set_default() {
 
	with_cocoa="1"
 
	with_zlib="1"
 
	with_png="1"
 
	with_makedepend="1"
 
	with_direct_music="1"
 
	with_sort="1"
 
	with_iconv="1"
 
	with_midi=""
 
	with_midi_arg=""
 
	with_libtimidity="1"
 
	with_freetype="1"
 
	with_fontconfig="1"
 
	with_icu="1"
 
	with_psp_config="1"
 
	with_threads="1"
 
	with_distcc="1"
 
	with_ccache="1"
 

	
 
	save_params_array="
 
		build
 
		host
 
		cc_build
 
		cc_host
 
		cxx_build
 
		cxx_host
 
@@ -124,24 +125,25 @@ set_default() {
 
		with_cocoa
 
		with_zlib
 
		with_png
 
		with_makedepend
 
		with_direct_music
 
		with_sort
 
		with_iconv
 
		with_midi
 
		with_midi_arg
 
		with_libtimidity
 
		with_freetype
 
		with_fontconfig
 
		with_icu
 
		with_psp_config
 
		with_threads
 
		with_distcc
 
		with_ccache
 
	CC CXX CFLAGS LDFLAGS"
 
}
 

	
 
detect_params() {
 
	# Walk over all params from the user and override any default settings if
 
	#  needed. This also handles any invalid option.
 
	for p in "$@"; do
 
		if [ -n "$prev_p" ]; then
 
@@ -311,24 +313,31 @@ detect_params() {
 
			--with-freetype=*)            with_freetype="$optarg";;
 
			--with-libfreetype)           with_freetype="2";;
 
			--without-libfreetype)        with_freetype="0";;
 
			--with-libfreetype=*)         with_freetype="$optarg";;
 

	
 
			--with-fontconfig)            with_fontconfig="2";;
 
			--without-fontconfig)         with_fontconfig="0";;
 
			--with-fontconfig=*)          with_fontconfig="$optarg";;
 
			--with-libfontconfig)         with_fontconfig="2";;
 
			--without-libfontconfig)      with_fontconfig="0";;
 
			--with-libfontconfig=*)       with_fontconfig="$optarg";;
 

	
 
			--with-icu)                   with_icu="2";;
 
			--without-icu)                with_icu="0";;
 
			--with-icu=*)                 with_icu="$optarg";;
 
			--with-libicu)                with_icu="2";;
 
			--without-libicu)             with_icu="0";;
 
			--with-libicu=*)              with_icu="$optarg";;
 

	
 
			--with-psp-config)            with_psp_config="2";;
 
			--without-psp-config)         with_psp_config="0";;
 
			--with-psp-config=*)          with_psp_config="$optarg";;
 

	
 
			--with-makedepend)            with_makedepend="2";;
 
			--without-makedepend)         with_makedepend="0";;
 
			--with-makedepend=*)          with_makedepend="$optarg";;
 

	
 
			--with-direct-music)          with_direct_music="2";;
 
			--without-direct-music)       with_direct_music="0";;
 
			--with-direct-music=*)        with_direct_music="$optarg";;
 

	
 
@@ -595,24 +604,25 @@ check_params() {
 
	fi
 

	
 
	if [ "$enable_assert" != "0" ]; then
 
		log 1 "checking assert... enabled"
 
	else
 
		log 1 "checking assert... disabled"
 
	fi
 

	
 
	detect_zlib
 
	detect_png
 
	detect_freetype
 
	detect_fontconfig
 
	detect_icu
 
	detect_pspconfig
 
	detect_libtimidity
 

	
 
	if [ "$with_direct_music" = "1" ] || [ "$with_direct_music" = "2" ]; then
 
		if [ "$os" != "MINGW" ] && [ "$os" != "CYGWIN" ]; then
 
			if [ "$with_direct_music" = "2" ]; then
 
				log 1 "configure: error: direct-music is only supported on Win32 targets"
 
				exit 1
 
			fi
 
			with_direct_music="0"
 

	
 
			log 1 "checking direct-music... not Windows, skipping"
 
@@ -1218,24 +1228,32 @@ make_cflags_and_ldflags() {
 
		if [ "$enable_static" != "0" ]; then
 
			if [ "$os" = "OSX" ]; then
 
				LIBS="$LIBS `$freetype_config --prefix`/lib/libfreetype.a"
 
			else
 
				# Is it possible to do static with freetype, if so: how?
 
				LIBS="$LIBS `$freetype_config --libs | tr '\n\r' '  '`"
 
			fi
 
		else
 
			LIBS="$LIBS `$freetype_config --libs | tr '\n\r' '  '`"
 
		fi
 
	fi
 

	
 
	if [ -n "$icu_config" ]; then
 
		CFLAGS="$CFLAGS -DWITH_ICU"
 
		CFLAGS="$CFLAGS `$icu_config --cppflags | tr '\n\r' '  '`"
 

	
 
		LIBS="$LIBS `$icu_config --ldflags-libsonly | tr '\n\r' '  '`"
 
	fi
 

	
 

	
 
	if [ "$with_direct_music" != "0" ]; then
 
		CFLAGS="$CFLAGS -DWIN32_ENABLE_DIRECTMUSIC_SUPPORT"
 
		# GCC 4.0+ doesn't like the DirectX includes (gives tons of
 
		#  warnings on it we won't be able to fix). For now just
 
		#  suppress those warnings.
 
		if [ $cc_version -ge 40 ]; then
 
			CFLAGS="$CFLAGS -Wno-non-virtual-dtor"
 
		fi
 
	fi
 

	
 
	if [ -n "$libtimidity" ]; then
 
		if [ "$enable_static" != "0" ]; then
 
@@ -2051,24 +2069,67 @@ detect_fontconfig() {
 
			log 1 "configure: error: fontconfig-config couldn't be found"
 
			log 1 "configure: error: you supplied '$with_fontconfig', but it seems invalid"
 
			exit 1
 
		fi
 

	
 
		fontconfig_config=""
 
		return 0
 
	fi
 

	
 
	log 1 "checking libfontconfig... found"
 
}
 

	
 
detect_icu() {
 
	# 0 means no, 1 is auto-detect, 2 is force
 
	if [ "$with_icu" = "0" ]; then
 
		log 1 "checking libicu... disabled"
 

	
 
		icu_config=""
 
		return 0
 
	fi
 

	
 
	if [ "$with_icu" = "1" ] || [ "$with_icu" = "" ] || [ "$with_icu" = "2" ]; then
 
		icu_config="icu-config"
 
	else
 
		icu_config="$with_icu"
 
	fi
 

	
 
	version=`$icu_config --version 2>/dev/null`
 
	ret=$?
 
	shortversion=`echo $version | cut -c 1,3`
 
	log 2 "executing $icu_config --version"
 
	log 2 "  returned $version"
 
	log 2 "  exit code $ret"
 

	
 
	if [ -z "$version" ] || [ "$ret" != "0" ] || [ "$shortversion" -lt "20" ]; then
 
		if [ -n "$shortversion" ] && [ "$shortversion" -lt "20" ]; then
 
			log 1 "checking libicu... needs at least version 2.0.0, icu NOT enabled"
 
		else
 
			log 1 "checking libicu... not found"
 
		fi
 

	
 
		# It was forced, so it should be found.
 
		if [ "$with_icu" != "1" ]; then
 
			log 1 "configure: error: icu-config couldn't be found"
 
			log 1 "configure: error: you supplied '$with_icuconfig', but it seems invalid"
 
			exit 1
 
		fi
 

	
 
		icu_config=""
 
		return 0
 
	fi
 

	
 
	log 1 "checking libicu... found"
 
}
 

	
 
detect_pspconfig() {
 
	# 0 means no, 1 is auto-detect, 2 is force
 
	if [ "$with_psp_config" = "0" ]; then
 
		log 1 "checking psp-config... disabled"
 

	
 
		psp_config=""
 
		return 0
 
	fi
 

	
 
	if [ "$with_psp_config" = "1" ] && [ "$os" != "PSP" ]; then
 
		log 1 "checking psp-config... not PSP, skipping"
 

	
src/gfx.cpp
Show inline comments
 
@@ -42,24 +42,25 @@ bool _exit_game;
 
bool _networking;         ///< are we in networking mode?
 
byte _game_mode;
 
int8 _pause_game;
 
int _pal_first_dirty;
 
int _pal_count_dirty;
 

	
 
Colour _cur_palette[256];
 
byte _stringwidth_table[FS_END][224]; ///< Cache containing width of often used characters. @see GetCharacterWidth()
 
DrawPixelInfo *_cur_dpi;
 
byte _colour_gradient[COLOUR_END][8];
 

	
 
static void GfxMainBlitter(const Sprite *sprite, int x, int y, BlitterMode mode, const SubSprite *sub = NULL);
 
static int ReallyDoDrawString(const char *string, int x, int y, uint16 real_colour, bool parse_string_also_when_clipped = false);
 

	
 
FontSize _cur_fontsize;
 
static FontSize _last_fontsize;
 
static uint8 _cursor_backup[64 * 64 * 4];
 

	
 
/**
 
 * The rect for repaint.
 
 *
 
 * This rectangle defines the area which should be repaint by the video driver.
 
 *
 
 * @ingroup dirty
 
 */
 
@@ -229,24 +230,92 @@ void DrawBox(int x, int y, int dx1, int 
 
	GfxDrawLineUnscaled(x, y, x + dx2, y + dy2, color);
 
	GfxDrawLineUnscaled(x, y, x + dx3, y + dy3, color);
 

	
 
	GfxDrawLineUnscaled(x + dx1, y + dy1, x + dx1 + dx2, y + dy1 + dy2, color);
 
	GfxDrawLineUnscaled(x + dx1, y + dy1, x + dx1 + dx3, y + dy1 + dy3, color);
 
	GfxDrawLineUnscaled(x + dx2, y + dy2, x + dx2 + dx1, y + dy2 + dy1, color);
 
	GfxDrawLineUnscaled(x + dx2, y + dy2, x + dx2 + dx3, y + dy2 + dy3, color);
 
	GfxDrawLineUnscaled(x + dx3, y + dy3, x + dx3 + dx1, y + dy3 + dy1, color);
 
	GfxDrawLineUnscaled(x + dx3, y + dy3, x + dx3 + dx2, y + dy3 + dy2, color);
 
}
 

	
 

	
 
#if !defined(WITH_ICU)
 
static void HandleBiDiAndArabicShapes(char *text, const char *lastof) {}
 
#else
 
#include "unicode/ubidi.h"
 
#include "unicode/ushape.h"
 

	
 
/**
 
 * Function to be able to handle right-to-left text and Arabic chars properly.
 
 *
 
 * First: right-to-left (RTL) is stored 'logically' in almost all applications
 
 *        and so do we. This means that their text is stored from right to the
 
 *        left in memory and any non-RTL text (like numbers or English) are
 
 *        then stored from left-to-right. When we want to actually draw the
 
 *        text we need to reverse the RTL text in memory, which is what
 
 *        happens in ubidi_writeReordered.
 
 * Second: Arabic characters "differ" based on their context. To draw the
 
 *        correct variant we pass it through u_shapeArabic. This function can
 
 *        add or remove some characters. This is the reason for the lastof
 
 *        so we know till where we can fill the output.
 
 *
 
 * Sadly enough these functions work with a custom character format, UChar,
 
 * which isn't the same size as WChar. Because of that we need to transform
 
 * our text first to UChars and then back to something we can use.
 
 *
 
 * To be able to truncate strings properly you must truncate before passing to
 
 * this function. This way the logical begin of the string remains and the end
 
 * gets chopped of instead of the other way around.
 
 *
 
 * The reshaping of Arabic characters might increase or decrease the width of
 
 * the characters/string. So it might still overflow after truncation, though
 
 * the chance is fairly slim as most characters get shorter instead of longer.
 
 * @param buffer the buffer to read from/to
 
 * @param lastof the end of the buffer
 
 */
 
static void HandleBiDiAndArabicShapes(char *buffer, const char *lastof)
 
{
 
	UChar input_output[DRAW_STRING_BUFFER];
 
	UChar intermediate[DRAW_STRING_BUFFER];
 

	
 
	char *t = buffer;
 
	size_t length = 0;
 
	while (*t != '\0' && length < lengthof(input_output)) {
 
		WChar tmp;
 
		t += Utf8Decode(&tmp, t);
 
		input_output[length++] = tmp;
 
	}
 
	input_output[length] = 0;
 

	
 
	UErrorCode err = U_ZERO_ERROR;
 
	UBiDi *para = ubidi_openSized(length, 0, &err);
 
	if (para == NULL) return;
 

	
 
	ubidi_setPara(para, input_output, length, UBIDI_DEFAULT_RTL, NULL, &err);
 
	ubidi_writeReordered(para, intermediate, length, 0, &err);
 
	length = u_shapeArabic(intermediate, length, input_output, lengthof(input_output), U_SHAPE_TEXT_DIRECTION_VISUAL_LTR | U_SHAPE_LETTERS_SHAPE, &err);
 
	ubidi_close(para);
 

	
 
	if (U_FAILURE(err)) return;
 

	
 
	t = buffer;
 
	for (size_t i = 0; i < length && t < (lastof - 4); i++) {
 
		t += Utf8Encode(t, input_output[i]);
 
	}
 
	*t = '\0';
 
}
 
#endif /* WITH_ICU */
 

	
 

	
 
/** Truncate a given string to a maximum width if neccessary.
 
 * If the string is truncated, add three dots ('...') to show this.
 
 * @param *str string that is checked and possibly truncated
 
 * @param maxw maximum width in pixels of the string
 
 * @return new width of (truncated) string */
 
static int TruncateString(char *str, int maxw)
 
{
 
	int w = 0;
 
	FontSize size = _cur_fontsize;
 
	int ddd, ddd_w;
 

	
 
	WChar c;
 
@@ -313,82 +382,87 @@ static inline int TruncateStringID(Strin
 
 * @param x      X position to start drawing
 
 * @param y      Y position to start drawing
 
 * @param str    String to draw
 
 * @param color  Color used for drawing the string, see DoDrawString() for details
 
 *
 
 * @return Horizontal coordinate after drawing the string
 
 */
 
int DrawString(int x, int y, StringID str, uint16 color)
 
{
 
	char buffer[DRAW_STRING_BUFFER];
 

	
 
	GetString(buffer, str, lastof(buffer));
 
	return DoDrawString(buffer, x, y, color);
 
	HandleBiDiAndArabicShapes(buffer, lastof(buffer));
 
	return ReallyDoDrawString(buffer, x, y, color);
 
}
 

	
 
/**
 
 * Draw string, possibly truncated to make it fit in its allocated space
 
 *
 
 * @param x      X position to start drawing
 
 * @param y      Y position to start drawing
 
 * @param str    String to draw
 
 * @param color  Color used for drawing the string, see DoDrawString() for details
 
 * @param maxw   Maximal width of the string
 
 *
 
 * @return Horizontal coordinate after drawing the (possibly truncated) string
 
 */
 
int DrawStringTruncated(int x, int y, StringID str, uint16 color, uint maxw)
 
{
 
	char buffer[DRAW_STRING_BUFFER];
 
	TruncateStringID(str, buffer, maxw, lastof(buffer));
 
	return DoDrawString(buffer, x, y, color);
 
	HandleBiDiAndArabicShapes(buffer, lastof(buffer));
 
	return ReallyDoDrawString(buffer, x, y, color);
 
}
 

	
 
/**
 
 * Draw string right-aligned.
 
 *
 
 * @param x      Right-most x position of the string
 
 * @param y      Y position of the string
 
 * @param str    String to draw
 
 * @param color  Color used for drawing the string, see DoDrawString() for details
 
 *
 
 * @return Width of drawn string in pixels
 
 */
 
int DrawStringRightAligned(int x, int y, StringID str, uint16 color)
 
{
 
	char buffer[DRAW_STRING_BUFFER];
 
	int w;
 

	
 
	GetString(buffer, str, lastof(buffer));
 
	HandleBiDiAndArabicShapes(buffer, lastof(buffer));
 

	
 
	w = GetStringBoundingBox(buffer).width;
 
	DoDrawString(buffer, x - w, y, color);
 
	ReallyDoDrawString(buffer, x - w, y, color);
 

	
 
	return w;
 
}
 

	
 
/**
 
 * Draw string right-aligned, possibly truncated to make it fit in its allocated space
 
 *
 
 * @param x      Right-most x position to start drawing
 
 * @param y      Y position to start drawing
 
 * @param str    String to draw
 
 * @param color  Color used for drawing the string, see DoDrawString() for details
 
 * @param maxw   Maximal width of the string
 
 */
 
void DrawStringRightAlignedTruncated(int x, int y, StringID str, uint16 color, uint maxw)
 
{
 
	char buffer[DRAW_STRING_BUFFER];
 

	
 
	TruncateStringID(str, buffer, maxw, lastof(buffer));
 
	DoDrawString(buffer, x - GetStringBoundingBox(buffer).width, y, color);
 
	HandleBiDiAndArabicShapes(buffer, lastof(buffer));
 
	ReallyDoDrawString(buffer, x - GetStringBoundingBox(buffer).width, y, color);
 
}
 

	
 
/**
 
 * Draw string right-aligned with a line underneath it.
 
 *
 
 * @param x      Right-most x position of the string
 
 * @param y      Y position of the string
 
 * @param str    String to draw
 
 * @param color  Color used for drawing the string, see DoDrawString() for details
 
 */
 
void DrawStringRightAlignedUnderline(int x, int y, StringID str, uint16 color)
 
{
 
@@ -403,63 +477,71 @@ void DrawStringRightAlignedUnderline(int
 
 * @param y      Y position of center of the string
 
 * @param str    String to draw
 
 * @param color  Color used for drawing the string, see DoDrawString() for details
 
 *
 
 * @return Width of the drawn string in pixels
 
 */
 
int DrawStringCentered(int x, int y, StringID str, uint16 color)
 
{
 
	char buffer[DRAW_STRING_BUFFER];
 
	int w;
 

	
 
	GetString(buffer, str, lastof(buffer));
 
	HandleBiDiAndArabicShapes(buffer, lastof(buffer));
 

	
 
	w = GetStringBoundingBox(buffer).width;
 
	DoDrawString(buffer, x - w / 2, y, color);
 
	ReallyDoDrawString(buffer, x - w / 2, y, color);
 

	
 
	return w;
 
}
 

	
 
/**
 
 * Draw string centered, possibly truncated to fit in the assigned space.
 
 *
 
 * @param xl     Left-most x position
 
 * @param xr     Right-most x position
 
 * @param y      Y position of the string
 
 * @param str    String to draw
 
 * @param color  Color used for drawing the string, see DoDrawString() for details
 
 *
 
 * @return Right-most coordinate of the (possibly truncated) drawn string
 
 */
 
int DrawStringCenteredTruncated(int xl, int xr, int y, StringID str, uint16 color)
 
{
 
	char buffer[DRAW_STRING_BUFFER];
 
	int w = TruncateStringID(str, buffer, xr - xl, lastof(buffer));
 
	return DoDrawString(buffer, (xl + xr - w) / 2, y, color);
 
	TruncateStringID(str, buffer, xr - xl, lastof(buffer));
 
	HandleBiDiAndArabicShapes(buffer, lastof(buffer));
 

	
 
	int w = GetStringBoundingBox(buffer).width;
 
	return ReallyDoDrawString(buffer, (xl + xr - w) / 2, y, color);
 
}
 

	
 
/**
 
 * Draw string centered.
 
 *
 
 * @param x      X position of center of the string
 
 * @param y      Y position of center of the string
 
 * @param str    String to draw
 
 * @param color  Color used for drawing the string, see DoDrawString() for details
 
 *
 
 * @return Width of the drawn string in pixels
 
 */
 
int DoDrawStringCentered(int x, int y, const char *str, uint16 color)
 
{
 
	int w = GetStringBoundingBox(str).width;
 
	DoDrawString(str, x - w / 2, y, color);
 
	char buffer[DRAW_STRING_BUFFER];
 
	strecpy(buffer, str, lastof(buffer));
 
	HandleBiDiAndArabicShapes(buffer, lastof(buffer));
 

	
 
	int w = GetStringBoundingBox(buffer).width;
 
	ReallyDoDrawString(buffer, x - w / 2, y, color);
 
	return w;
 
}
 

	
 
/**
 
 * Draw string centered, with additional line underneath it
 
 *
 
 * @param x      X position of center of the string
 
 * @param y      Y position of center of the string
 
 * @param str    String to draw
 
 * @param color  Color used for drawing the string, see DoDrawString() for details
 
 */
 
void DrawStringCenterUnderline(int x, int y, StringID str, uint16 color)
 
@@ -604,42 +686,45 @@ int GetStringHeight(StringID str, int ma
 
}
 

	
 

	
 
/** Draw a given string with the centre around the given (x,y) coordinates
 
 * @param x Centre the string around this pixel width
 
 * @param y Centre the string around this pixel height
 
 * @param str String to draw
 
 * @param maxw Maximum width the string can have before it is wrapped */
 
void DrawStringMultiCenter(int x, int y, StringID str, int maxw)
 
{
 
	char buffer[DRAW_STRING_BUFFER];
 
	uint32 tmp;
 
	int num, w, mt;
 
	int num, mt;
 
	const char *src;
 
	WChar c;
 

	
 
	GetString(buffer, str, lastof(buffer));
 

	
 
	tmp = FormatStringLinebreaks(buffer, maxw);
 
	num = GB(tmp, 0, 16);
 

	
 
	mt = GetCharacterHeight((FontSize)GB(tmp, 16, 16));
 

	
 
	y -= (mt >> 1) * num;
 

	
 
	src = buffer;
 

	
 
	for (;;) {
 
		w = GetStringBoundingBox(src).width;
 
		DoDrawString(src, x - (w >> 1), y, 0xFE, true);
 
		char buf2[DRAW_STRING_BUFFER];
 
		strecpy(buf2, src, lastof(buf2));
 
		HandleBiDiAndArabicShapes(buf2, lastof(buf2));
 
		int w = GetStringBoundingBox(buf2).width;
 
		ReallyDoDrawString(buf2, x - (w >> 1), y, 0xFE, true);
 
		_cur_fontsize = _last_fontsize;
 

	
 
		for (;;) {
 
			c = Utf8Consume(&src);
 
			if (c == 0) {
 
				y += mt;
 
				if (--num < 0) {
 
					_cur_fontsize = FS_NORMAL;
 
					return;
 
				}
 
				break;
 
			} else if (c == SCC_SETX) {
 
@@ -671,25 +756,28 @@ uint DrawStringMultiLine(int x, int y, S
 

	
 
	if (maxh != -1 && (int)total_height > maxh) {
 
		/* Check there's room enough for at least one line. */
 
		if (maxh < mt) return 0;
 

	
 
		num = maxh / mt - 1;
 
		total_height = (num + 1) * mt;
 
	}
 

	
 
	src = buffer;
 

	
 
	for (;;) {
 
		DoDrawString(src, x, y, 0xFE, true);
 
		char buf2[DRAW_STRING_BUFFER];
 
		strecpy(buf2, src, lastof(buf2));
 
		HandleBiDiAndArabicShapes(buf2, lastof(buf2));
 
		ReallyDoDrawString(buf2, x, y, 0xFE, true);
 
		_cur_fontsize = _last_fontsize;
 

	
 
		for (;;) {
 
			c = Utf8Consume(&src);
 
			if (c == 0) {
 
				y += mt;
 
				if (--num < 0) {
 
					_cur_fontsize = FS_NORMAL;
 
					return total_height;
 
				}
 
				break;
 
			} else if (c == SCC_SETX) {
 
@@ -758,40 +846,66 @@ void DrawCharCentered(WChar c, int x, in
 
	int w = GetCharacterWidth(size, c);
 

	
 
	_string_colorremap[1] = _string_colormap[_use_palette][color].text;
 
	_string_colorremap[2] = _string_colormap[_use_palette][color].shadow;
 
	_color_remap_ptr = _string_colorremap;
 

	
 
	GfxMainBlitter(GetGlyph(size, c), x - w / 2, y, BM_COLOUR_REMAP);
 
}
 

	
 
/** Draw a string at the given coordinates with the given colour.
 
 *  While drawing the string, parse it in case some formatting is specified,
 
 *  like new colour, new size or even positionning.
 
 * @param string              The string to draw
 
 * @param string              The string to draw. This is not yet bidi reordered.
 
 * @param x                   Offset from left side of the screen
 
 * @param y                   Offset from top side of the screen
 
 * @param real_colour         Colour of the string, see _string_colormap in
 
 *                            table/palettes.h or docs/ottd-colourtext-palette.png or the enum TextColour in gfx_type.h
 
 * @param parse_string_also_when_clipped
 
 *                            By default, always test the available space where to draw the string.
 
 *                            When in multipline drawing, it would already be done,
 
 *                            so no need to re-perform the same kind (more or less) of verifications.
 
 *                            It's not only an optimisation, it's also a way to ensures the string will be parsed
 
 *                            (as there are certain side effects on global variables, which are important for the next line)
 
 * @return                    the x-coordinates where the drawing has finished.
 
 *                            If nothing is drawn, the originally passed x-coordinate is returned
 
 */
 
int DoDrawString(const char *string, int x, int y, uint16 real_colour, bool parse_string_also_when_clipped)
 
{
 
	char buffer[DRAW_STRING_BUFFER];
 
	strecpy(buffer, string, lastof(buffer));
 
	HandleBiDiAndArabicShapes(buffer, lastof(buffer));
 

	
 
	return ReallyDoDrawString(buffer, x, y, real_colour, parse_string_also_when_clipped);
 
}
 

	
 
/** Draw a string at the given coordinates with the given colour.
 
 *  While drawing the string, parse it in case some formatting is specified,
 
 *  like new colour, new size or even positionning.
 
 * @param string              The string to draw. This is already bidi reordered.
 
 * @param x                   Offset from left side of the screen
 
 * @param y                   Offset from top side of the screen
 
 * @param real_colour         Colour of the string, see _string_colormap in
 
 *                            table/palettes.h or docs/ottd-colourtext-palette.png or the enum TextColour in gfx_type.h
 
 * @param parse_string_also_when_clipped
 
 *                            By default, always test the available space where to draw the string.
 
 *                            When in multipline drawing, it would already be done,
 
 *                            so no need to re-perform the same kind (more or less) of verifications.
 
 *                            It's not only an optimisation, it's also a way to ensures the string will be parsed
 
 *                            (as there are certain side effects on global variables, which are important for the next line)
 
 * @return                    the x-coordinates where the drawing has finished.
 
 *                            If nothing is drawn, the originally passed x-coordinate is returned
 
 */
 
static int ReallyDoDrawString(const char *string, int x, int y, uint16 real_colour, bool parse_string_also_when_clipped)
 
{
 
	DrawPixelInfo *dpi = _cur_dpi;
 
	FontSize size = _cur_fontsize;
 
	WChar c;
 
	int xo = x, yo = y;
 

	
 
	byte colour = real_colour & 0xFF;  // extract the 8 bits colour index that is required for the mapping
 
	byte previous_colour = colour;
 

	
 
	if (!parse_string_also_when_clipped) {
 
		/* in "mode multiline", the available space have been verified. Not in regular one.
 
		 * So if the string cannot be drawn, return the original start to say so.*/
 
		if (x >= dpi->left + dpi->width || y >= dpi->top + dpi->height) return x;
0 comments (0 inline, 0 general)