[Scummvm-git-logs] scummvm master -> ec83715b430bddb9a67f1b7fe0e59bb42810be5e

sev- sev at scummvm.org
Tue May 12 12:36:21 UTC 2020


This automated email contains information about 14 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
c30b22c628 COMMON: add bidi support for U32String
5b2bc4a9d3 COMMON: move bidi conversion to str-bidi.h
861d8da600 PINK: support BiDi on menu bar items
625241e3b4 GRAPHICS: MACGUI: flip layout on RTL
38d27ee7ac GRAPHICS: MACGUI: fix accelerator position
028e4be835 COMMON: add method to get visual position for bidi
c39630ad53 GRAPHICS: MACGUI: add text renderer and visual pos
0c30136c0f GRAPHICS: change text renderer parameters position
a92864c8c1 GRAPHICS: MACGUI: allow setting widget alignment
abeb33fb71 PINK: use RTL menu in hebrew version
432dd88bdb GRAPHICS: MACTEXT: draw bidi text
f8e2cc0f0f PINK: draw hebrew characters on pages
6a653312e2 GRAPHICS: remove text_renderer
ec83715b43 COMMON: add UnicodeBiDiText wrapper


Commit: c30b22c62878df22fba89600aa18e31ee962f224
    https://github.com/scummvm/scummvm/commit/c30b22c62878df22fba89600aa18e31ee962f224
Author: BLooperZ (blooperz at users.noreply.github.com)
Date: 2020-05-12T14:36:09+02:00

Commit Message:
COMMON: add bidi support for U32String

Changed paths:
    common/translation.cpp
    common/translation.h


diff --git a/common/translation.cpp b/common/translation.cpp
index 86efdd5371..e5787844f1 100644
--- a/common/translation.cpp
+++ b/common/translation.cpp
@@ -466,25 +466,29 @@ String TranslationManager::convertBiDiString(const String &input) {
 	return TranslationManager::convertBiDiString(input, HE_ISR);
 }
 
-#ifdef USE_FRIBIDI
 String TranslationManager::convertBiDiString(const String &input, const Common::Language lang) {
 	if (lang != HE_ISR)		//TODO: modify when we'll support other RTL languages, such as Arabic and Farsi
 		return input;
 
+	return convertBiDiString(input, kWindows1255);
+}
+
+String TranslationManager::convertBiDiString(const String &input, const Common::CodePage page) {
+	return convertBiDiU32String(input.decode(page)).encode(page);
+}
+
+U32String TranslationManager::convertBiDiU32String(const U32String &input) {
+
+#ifdef USE_FRIBIDI
 	int buff_length = (input.size() + 2) * 2;		// it's more than enough, but it's better to be on the safe side
-	FriBidiChar *input_unicode = (FriBidiChar *)malloc(buff_length * sizeof(FriBidiChar));
 	FriBidiChar *visual_str = (FriBidiChar *)malloc(buff_length * sizeof(FriBidiChar));
-	char *output = (char *)malloc(buff_length);
 
 	FriBidiCharType pbase_dir = FRIBIDI_TYPE_ON;
-	FriBidiCharSet char_set = FRIBIDI_CHAR_SET_ISO8859_8;
-
-	FriBidiStrIndex length = fribidi_charset_to_unicode(char_set, input.c_str(), input.size(), input_unicode);
 
 	if (!fribidi_log2vis(
 		/* input */
-		input_unicode,
-		length,
+		(const FriBidiChar *)input.c_str(),
+		input.size(),
 		&pbase_dir,
 		/* output */
 		visual_str,
@@ -492,28 +496,21 @@ String TranslationManager::convertBiDiString(const String &input, const Common::
 		NULL,			// position_V_to_L_list,
 		NULL			// embedding_level_list
 	)) {
-		warning("convertBiDiString: calling fribidi_log2vis failed");
-		free(input_unicode);
+		warning("convertBiDiU32String: calling fribidi_log2vis failed");
 		free(visual_str);
-		free(output);
 		return input;
 	}
 
-	fribidi_unicode_to_charset(char_set, visual_str, length, output);
-
-	String result = String(output);
-	free(input_unicode);
+	U32String result = U32String(visual_str, input.size());
 	free(visual_str);
-	free(output);
 
 	return result;
-}
 #else
-String TranslationManager::convertBiDiString(const String &input, const Common::Language lang) {
+	warning("convertBiDiU32String: Fribidi not available, using input string as fallback");
 	return input;
-}
 #endif
 
+}
 
 
 } // End of namespace Common
diff --git a/common/translation.h b/common/translation.h
index 88cd86a65d..b1a28002ea 100644
--- a/common/translation.h
+++ b/common/translation.h
@@ -26,6 +26,7 @@
 #include "common/array.h"
 #include "common/fs.h"
 #include "common/str.h"
+#include "common/ustr.h"
 #include "common/singleton.h"
 #include "common/str-array.h"
 #include "common/language.h"
@@ -180,7 +181,9 @@ public:
 	 * For LTR (Left To Right) languages, returns the original input
 	 * For RTL (Right To Left) languages, returns visual representation of a logical single-line input
 	 */
+	U32String convertBiDiU32String(const U32String &input);
 	String convertBiDiString(const String &input);
+	String convertBiDiString(const String &input, const Common::CodePage page);
 	String convertBiDiString(const String &input, const Common::Language lang);
 
 private:


Commit: 5b2bc4a9d34bbd1e4f27d0b15b8a4e0b40824dd1
    https://github.com/scummvm/scummvm/commit/5b2bc4a9d34bbd1e4f27d0b15b8a4e0b40824dd1
Author: BLooperZ (blooperz at users.noreply.github.com)
Date: 2020-05-12T14:36:09+02:00

Commit Message:
COMMON: move bidi conversion to str-bidi.h

Changed paths:
  A common/str-bidi.cpp
  A common/str-bidi.h
    common/module.mk
    common/translation.cpp
    common/translation.h


diff --git a/common/module.mk b/common/module.mk
index aed1f9abc4..43b6493e8c 100644
--- a/common/module.mk
+++ b/common/module.mk
@@ -30,6 +30,7 @@ MODULE_OBJS := \
 	rational.o \
 	rendermode.o \
 	str.o \
+	str-bidi.o \
 	str-enc.o \
 	stream.o \
 	system.o \
diff --git a/common/str-bidi.cpp b/common/str-bidi.cpp
new file mode 100644
index 0000000000..289e2d4ec2
--- /dev/null
+++ b/common/str-bidi.cpp
@@ -0,0 +1,71 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/str-bidi.h"
+#include "common/textconsole.h"
+
+#ifdef USE_FRIBIDI
+#include <fribidi/fribidi.h>
+#endif
+
+namespace Common {
+
+String convertBiDiString(const String &input, const Common::CodePage page) {
+	return convertBiDiU32String(input.decode(page)).encode(page);
+}
+
+U32String convertBiDiU32String(const U32String &input) {
+
+#ifdef USE_FRIBIDI
+	int buff_length = (input.size() + 2) * 2;		// it's more than enough, but it's better to be on the safe side
+	FriBidiChar *visual_str = (FriBidiChar *)malloc(buff_length * sizeof(FriBidiChar));
+
+	FriBidiCharType pbase_dir = FRIBIDI_TYPE_ON;
+
+	if (!fribidi_log2vis(
+		/* input */
+		(const FriBidiChar *)input.c_str(),
+		input.size(),
+		&pbase_dir,
+		/* output */
+		visual_str,
+		NULL,			// position_L_to_V_list,
+		NULL,			// position_V_to_L_list,
+		NULL			// embedding_level_list
+	)) {
+		warning("convertBiDiU32String: calling fribidi_log2vis failed");
+		free(visual_str);
+		return input;
+	}
+
+	U32String result = U32String(visual_str, input.size());
+	free(visual_str);
+
+	return result;
+#else
+	warning("convertBiDiU32String: Fribidi not available, using input string as fallback");
+	return input;
+#endif
+
+}
+
+} // End of namespace Common
diff --git a/common/str-bidi.h b/common/str-bidi.h
new file mode 100644
index 0000000000..1b072c8762
--- /dev/null
+++ b/common/str-bidi.h
@@ -0,0 +1,42 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef COMMON_STRING_BIDI_H
+#define COMMON_STRING_BIDI_H
+
+#include "common/str.h"
+#include "common/ustr.h"
+#include "common/str-enc.h"
+
+namespace Common {
+
+/*
+ * Wrapper for GNU FriBidi implementation of the Unicode Bidirectional Algorithm
+ * For LTR (Left To Right) languages, returns the original input
+ * For RTL (Right To Left) languages, returns visual representation of a logical single-line input
+ */
+U32String convertBiDiU32String(const U32String &input);
+String convertBiDiString(const String &input, const Common::CodePage page);
+
+} // End of namespace Common
+
+#endif
diff --git a/common/translation.cpp b/common/translation.cpp
index e5787844f1..2aa518a8eb 100644
--- a/common/translation.cpp
+++ b/common/translation.cpp
@@ -33,13 +33,10 @@
 #include "common/fs.h"
 #include "common/system.h"
 #include "common/textconsole.h"
+#include "common/str-bidi.h"
 
 #ifdef USE_TRANSLATION
 
-#ifdef USE_FRIBIDI
-#include <fribidi/fribidi.h>
-#endif
-
 namespace Common {
 
 DECLARE_SINGLETON(TranslationManager);
@@ -470,49 +467,9 @@ String TranslationManager::convertBiDiString(const String &input, const Common::
 	if (lang != HE_ISR)		//TODO: modify when we'll support other RTL languages, such as Arabic and Farsi
 		return input;
 
-	return convertBiDiString(input, kWindows1255);
-}
-
-String TranslationManager::convertBiDiString(const String &input, const Common::CodePage page) {
-	return convertBiDiU32String(input.decode(page)).encode(page);
+	return Common::convertBiDiString(input, kWindows1255);
 }
 
-U32String TranslationManager::convertBiDiU32String(const U32String &input) {
-
-#ifdef USE_FRIBIDI
-	int buff_length = (input.size() + 2) * 2;		// it's more than enough, but it's better to be on the safe side
-	FriBidiChar *visual_str = (FriBidiChar *)malloc(buff_length * sizeof(FriBidiChar));
-
-	FriBidiCharType pbase_dir = FRIBIDI_TYPE_ON;
-
-	if (!fribidi_log2vis(
-		/* input */
-		(const FriBidiChar *)input.c_str(),
-		input.size(),
-		&pbase_dir,
-		/* output */
-		visual_str,
-		NULL,			// position_L_to_V_list,
-		NULL,			// position_V_to_L_list,
-		NULL			// embedding_level_list
-	)) {
-		warning("convertBiDiU32String: calling fribidi_log2vis failed");
-		free(visual_str);
-		return input;
-	}
-
-	U32String result = U32String(visual_str, input.size());
-	free(visual_str);
-
-	return result;
-#else
-	warning("convertBiDiU32String: Fribidi not available, using input string as fallback");
-	return input;
-#endif
-
-}
-
-
 } // End of namespace Common
 
 #endif // USE_TRANSLATION
diff --git a/common/translation.h b/common/translation.h
index b1a28002ea..88cd86a65d 100644
--- a/common/translation.h
+++ b/common/translation.h
@@ -26,7 +26,6 @@
 #include "common/array.h"
 #include "common/fs.h"
 #include "common/str.h"
-#include "common/ustr.h"
 #include "common/singleton.h"
 #include "common/str-array.h"
 #include "common/language.h"
@@ -181,9 +180,7 @@ public:
 	 * For LTR (Left To Right) languages, returns the original input
 	 * For RTL (Right To Left) languages, returns visual representation of a logical single-line input
 	 */
-	U32String convertBiDiU32String(const U32String &input);
 	String convertBiDiString(const String &input);
-	String convertBiDiString(const String &input, const Common::CodePage page);
 	String convertBiDiString(const String &input, const Common::Language lang);
 
 private:


Commit: 861d8da6000f14cab3b0d9e1c46f30b8521d8c4b
    https://github.com/scummvm/scummvm/commit/861d8da6000f14cab3b0d9e1c46f30b8521d8c4b
Author: BLooperZ (blooperz at users.noreply.github.com)
Date: 2020-05-12T14:36:09+02:00

Commit Message:
PINK: support BiDi on menu bar items

Changed paths:
    graphics/macgui/macmenu.cpp


diff --git a/graphics/macgui/macmenu.cpp b/graphics/macgui/macmenu.cpp
index dfb37c75bc..0f65274361 100644
--- a/graphics/macgui/macmenu.cpp
+++ b/graphics/macgui/macmenu.cpp
@@ -25,6 +25,7 @@
 #include "common/keyboard.h"
 #include "common/macresman.h"
 #include "common/winexe_pe.h"
+#include "common/str-bidi.h"
 
 #include "graphics/primitives.h"
 #include "graphics/font.h"
@@ -787,7 +788,8 @@ bool MacMenu::draw(ManagedSurface *g, bool forceRedraw) {
 		int y = it->bbox.top + (_wm->_fontMan->hasBuiltInFonts() ? 2 : 1);
 
 		if (it->unicode) {
-			_font->drawString(&_screen, it->unicodeText, x, y, it->bbox.width(), color);
+			Common::U32String line = convertBiDiU32String(it->unicodeText);
+			_font->drawString(&_screen, line, x, y, it->bbox.width(), color);
 			underlineAccelerator(&_screen, _font, it->unicodeText, x, y, it->shortcutPos, color);
 		} else {
 			const Font *font = getMenuFont(it->style);
@@ -831,7 +833,7 @@ void MacMenu::renderSubmenu(MacMenuSubMenu *menu, bool recursive) {
 		Common::String text(menu->items[i]->text);
 		Common::String acceleratorText(getAcceleratorString(menu->items[i], ""));
 
-		Common::U32String unicodeText(menu->items[i]->unicodeText);
+		Common::U32String unicodeText = convertBiDiU32String(menu->items[i]->unicodeText);
 		int shortcutPos = menu->items[i]->shortcutPos;
 
 		int accelX = r->right - 25;


Commit: 625241e3b4a2ac1f750824c59dfe5d4e1191048b
    https://github.com/scummvm/scummvm/commit/625241e3b4a2ac1f750824c59dfe5d4e1191048b
Author: BLooperZ (blooperz at users.noreply.github.com)
Date: 2020-05-12T14:36:09+02:00

Commit Message:
GRAPHICS: MACGUI: flip layout on RTL

Changed paths:
    graphics/macgui/macmenu.cpp
    graphics/macgui/macmenu.h


diff --git a/graphics/macgui/macmenu.cpp b/graphics/macgui/macmenu.cpp
index 0f65274361..afd8412f06 100644
--- a/graphics/macgui/macmenu.cpp
+++ b/graphics/macgui/macmenu.cpp
@@ -108,6 +108,8 @@ MacMenu::MacMenu(int id, const Common::Rect &bounds, MacWindowManager *wm)
 		: BaseMacWindow(id, false, wm) {
 	_font = getMenuFont();
 
+	_align = kTextAlignRight;
+
 	_screen.create(bounds.width(), bounds.height(), PixelFormat::createFormatCLUT8());
 
 	_bbox.left = 0;
@@ -401,6 +403,14 @@ void MacMenu::calcDimensions() {
 
 		calcSubMenuBounds(_items[i]->submenu, _items[i]->bbox.left - 1, _items[i]->bbox.bottom + 1);
 
+		// FLIP ON CREATE
+		if (_align == kTextAlignRight) {
+			int right = _items[i]->bbox.right;
+			int width = right - _items[i]->bbox.left;
+			_items[i]->bbox.left = _bbox.right + _bbox.left - right;
+			_items[i]->bbox.right = _items[i]->bbox.left + width;
+		}
+
 		x += w + kMenuSpacing;
 	}
 
@@ -708,6 +718,11 @@ void MacMenu::calcSubMenuBounds(MacMenuSubMenu *submenu, int x, int y) {
 	submenu->bbox.right = x2;
 	submenu->bbox.bottom = y2;
 
+	if (_align == kTextAlignRight) {
+		submenu->bbox.left = _bbox.right + _bbox.left - x2;
+		submenu->bbox.right = submenu->bbox.left + x2 - x1;
+	}
+
 	for (uint i = 0; i < submenu->items.size(); i++) {
 		MacMenuSubMenu *menu = submenu->items[i]->submenu;
 
@@ -776,21 +791,45 @@ bool MacMenu::draw(ManagedSurface *g, bool forceRedraw) {
 		if ((uint)_activeItem == i) {
 			Common::Rect hbox = it->bbox;
 
+			// FLIP ON RENDER
+			// if (_align == kTextAlignRight) {
+			// 	hbox.left = r.right + r.left - it->bbox.width() - hbox.left;
+			// 	hbox.right = hbox.left + it->bbox.width();
+			// }
+
 			hbox.left -= 1;
 			hbox.right += 3;
 			hbox.bottom += 1;
 
+			// FLIP ON CREATE
+			if (_align == kTextAlignRight) {
+				hbox.left -= 2;
+				hbox.right -= 2;
+			}
+
 			_screen.fillRect(hbox, _wm->_colorBlack);
 			color = _wm->_colorWhite;
 		}
 
 		int x = it->bbox.left + kMenuLeftMargin;
+
+		// FLIP ON CREATE
+		if (_align == kTextAlignRight) {
+			x -= 2 * kMenuLeftMargin;
+		}
+
 		int y = it->bbox.top + (_wm->_fontMan->hasBuiltInFonts() ? 2 : 1);
 
 		if (it->unicode) {
 			Common::U32String line = convertBiDiU32String(it->unicodeText);
-			_font->drawString(&_screen, line, x, y, it->bbox.width(), color);
-			underlineAccelerator(&_screen, _font, it->unicodeText, x, y, it->shortcutPos, color);
+
+			// FLIP ON RENDER
+			// if (_align == kTextAlignRight) {
+			// 	x = r.right + r.left - it->bbox.width() - x;
+			// }
+
+			_font->drawString(&_screen, line, x, y, it->bbox.width(), color, _align);
+			underlineAccelerator(&_screen, _font, line, x, y, it->shortcutPos, color);
 		} else {
 			const Font *font = getMenuFont(it->style);
 
@@ -822,13 +861,26 @@ void MacMenu::renderSubmenu(MacMenuSubMenu *menu, bool recursive) {
 
 	_screen.fillRect(*r, _wm->_colorWhite);
 	_screen.frameRect(*r, _wm->_colorBlack);
-	_screen.vLine(r->right, r->top + 3, r->bottom + 1, _wm->_colorBlack);
-	_screen.vLine(r->right + 1, r->top + 3, r->bottom + 1, _wm->_colorBlack);
-	_screen.hLine(r->left + 3, r->bottom, r->right + 1, _wm->_colorBlack);
-	_screen.hLine(r->left + 3, r->bottom + 1, r->right + 1, _wm->_colorBlack);
+
+	if (_align != kTextAlignRight) {
+		_screen.vLine(r->right, r->top + 3, r->bottom + 1, _wm->_colorBlack);
+		_screen.vLine(r->right + 1, r->top + 3, r->bottom + 1, _wm->_colorBlack);
+		_screen.hLine(r->left + 3, r->bottom, r->right + 1, _wm->_colorBlack);
+		_screen.hLine(r->left + 3, r->bottom + 1, r->right + 1, _wm->_colorBlack);
+	} else {
+		_screen.vLine(r->left, r->top + 3, r->bottom + 1, _wm->_colorBlack);
+		_screen.vLine(r->left - 1, r->top + 3, r->bottom + 1, _wm->_colorBlack);
+		_screen.hLine(r->left - 3, r->bottom, r->right - 1, _wm->_colorBlack);
+		_screen.hLine(r->left - 3, r->bottom + 1, r->right - 1, _wm->_colorBlack);
+	}
 
 	int x = r->left + kMenuDropdownPadding;
 	int y = r->top + 1;
+
+	if (_align == kTextAlignRight) {
+		x -= 2 * kMenuDropdownPadding;
+	}
+
 	for (uint i = 0; i < menu->items.size(); i++) {
 		Common::String text(menu->items[i]->text);
 		Common::String acceleratorText(getAcceleratorString(menu->items[i], ""));
@@ -839,6 +891,11 @@ void MacMenu::renderSubmenu(MacMenuSubMenu *menu, bool recursive) {
 		int accelX = r->right - 25;
 		int arrowX = r->right - 14;
 
+		if (_align == kTextAlignRight) {
+			accelX = r->left + 25;
+			arrowX += r->left + 14;
+		}
+
 		int color = _wm->_colorBlack;
 		if (i == (uint)menu->highlight && (!text.empty() || !unicodeText.empty()) && menu->items[i]->enabled) {
 			color = _wm->_colorWhite;
@@ -861,7 +918,7 @@ void MacMenu::renderSubmenu(MacMenuSubMenu *menu, bool recursive) {
 			}
 
 			if (menu->items[i]->unicode) {
-				_font->drawString(s, unicodeText, tx, ty, r->width(), color);
+				_font->drawString(s, unicodeText, tx, ty, r->width(), color, _align);
 				underlineAccelerator(s, _font, unicodeText, tx, ty, shortcutPos, color);
 			} else {
 				const Font *font = getMenuFont(menu->items[i]->style);
@@ -914,7 +971,11 @@ void MacMenu::renderSubmenu(MacMenuSubMenu *menu, bool recursive) {
 void MacMenu::drawSubMenuArrow(ManagedSurface *dst, int x, int y, int color) {
 	int height = 11;
 	for (int col = 0; col < 6; col++) {
-		dst->vLine(x + col, y + col + 1, y + col + height + 1, color);
+		if (_align != kTextAlignRight) {
+			dst->vLine(x + col, y + col + 1, y + col + height + 1, color);
+		} else {
+			dst->vLine(x - col, y + col + 1, y + col + height + 1, color);
+		}
 		height -= 2;
 	}
 }
diff --git a/graphics/macgui/macmenu.h b/graphics/macgui/macmenu.h
index e1a1e041da..8054240c11 100644
--- a/graphics/macgui/macmenu.h
+++ b/graphics/macgui/macmenu.h
@@ -25,6 +25,7 @@
 
 #include "common/str-array.h"
 #include "graphics/macgui/macfontmanager.h"
+#include "graphics/font.h"
 
 namespace Common {
 class U32String;
@@ -91,6 +92,7 @@ public:
 private:
 	ManagedSurface _screen;
 	ManagedSurface _tempSurface;
+	TextAlign _align;
 
 private:
 	bool checkCallback(bool unicode = false);


Commit: 38d27ee7ac49df8947c8e260dd3244c2b6d6bd24
    https://github.com/scummvm/scummvm/commit/38d27ee7ac49df8947c8e260dd3244c2b6d6bd24
Author: BLooperZ (blooperz at users.noreply.github.com)
Date: 2020-05-12T14:36:09+02:00

Commit Message:
GRAPHICS: MACGUI: fix accelerator position

Changed paths:
    graphics/macgui/macmenu.cpp


diff --git a/graphics/macgui/macmenu.cpp b/graphics/macgui/macmenu.cpp
index afd8412f06..1bee51e475 100644
--- a/graphics/macgui/macmenu.cpp
+++ b/graphics/macgui/macmenu.cpp
@@ -823,13 +823,18 @@ bool MacMenu::draw(ManagedSurface *g, bool forceRedraw) {
 		if (it->unicode) {
 			Common::U32String line = convertBiDiU32String(it->unicodeText);
 
+			int accOff = line == it->unicodeText ? 0 : _font->getStringWidth(line);
+			if (_align == kTextAlignRight) {
+				accOff += it->bbox.width() - kMenuLeftMargin - _font->getStringWidth(line);
+			}
+
 			// FLIP ON RENDER
 			// if (_align == kTextAlignRight) {
 			// 	x = r.right + r.left - it->bbox.width() - x;
 			// }
 
 			_font->drawString(&_screen, line, x, y, it->bbox.width(), color, _align);
-			underlineAccelerator(&_screen, _font, line, x, y, it->shortcutPos, color);
+			underlineAccelerator(&_screen, _font, line, x + accOff, y, it->shortcutPos, color);
 		} else {
 			const Font *font = getMenuFont(it->style);
 
@@ -886,6 +891,12 @@ void MacMenu::renderSubmenu(MacMenuSubMenu *menu, bool recursive) {
 		Common::String acceleratorText(getAcceleratorString(menu->items[i], ""));
 
 		Common::U32String unicodeText = convertBiDiU32String(menu->items[i]->unicodeText);
+
+		int accOff = unicodeText == menu->items[i]->unicodeText ? 0 : _font->getStringWidth(unicodeText);
+		if (_align == kTextAlignRight) {
+			accOff += r->width() - kMenuDropdownPadding - _font->getStringWidth(unicodeText);
+		}
+
 		int shortcutPos = menu->items[i]->shortcutPos;
 
 		int accelX = r->right - 25;
@@ -893,7 +904,7 @@ void MacMenu::renderSubmenu(MacMenuSubMenu *menu, bool recursive) {
 
 		if (_align == kTextAlignRight) {
 			accelX = r->left + 25;
-			arrowX += r->left + 14;
+			arrowX = r->left + 14;
 		}
 
 		int color = _wm->_colorBlack;
@@ -919,7 +930,7 @@ void MacMenu::renderSubmenu(MacMenuSubMenu *menu, bool recursive) {
 
 			if (menu->items[i]->unicode) {
 				_font->drawString(s, unicodeText, tx, ty, r->width(), color, _align);
-				underlineAccelerator(s, _font, unicodeText, tx, ty, shortcutPos, color);
+				underlineAccelerator(s, _font, unicodeText, tx + accOff, ty, shortcutPos, color);
 			} else {
 				const Font *font = getMenuFont(menu->items[i]->style);
 


Commit: 028e4be835322bfc6ef97d40536a08a2107762d2
    https://github.com/scummvm/scummvm/commit/028e4be835322bfc6ef97d40536a08a2107762d2
Author: BLooperZ (blooperz at users.noreply.github.com)
Date: 2020-05-12T14:36:09+02:00

Commit Message:
COMMON: add method to get visual position for bidi

Changed paths:
    common/str-bidi.cpp
    common/str-bidi.h


diff --git a/common/str-bidi.cpp b/common/str-bidi.cpp
index 289e2d4ec2..896b57c859 100644
--- a/common/str-bidi.cpp
+++ b/common/str-bidi.cpp
@@ -68,4 +68,16 @@ U32String convertBiDiU32String(const U32String &input) {
 
 }
 
+int getVisualPosition(const U32String &str, int pos) {
+	Common::U32String suffix(str.c_str() + pos + 1);
+	Common::U32String visual_str = Common::convertBiDiU32String(str);
+	Common::U32String visual_prefix(visual_str.c_str(), suffix.size());
+	Common::U32String visual_suffix = Common::convertBiDiU32String(suffix);
+	return visual_prefix == visual_suffix ? suffix.size() : pos;
+}
+
+int getVisualPosition(const String &str, const Common::CodePage page, int logicalPos) {
+	return getVisualPosition(str.decode(page), logicalPos);
+}
+
 } // End of namespace Common
diff --git a/common/str-bidi.h b/common/str-bidi.h
index 1b072c8762..5e531526a7 100644
--- a/common/str-bidi.h
+++ b/common/str-bidi.h
@@ -37,6 +37,9 @@ namespace Common {
 U32String convertBiDiU32String(const U32String &input);
 String convertBiDiString(const String &input, const Common::CodePage page);
 
+int getVisualPosition(const U32String &str, int pos);
+int getVisualPosition(const String &str, const Common::CodePage page, int pos);
+
 } // End of namespace Common
 
 #endif


Commit: c39630ad534a0363193c931f6434de91ff7e9d1d
    https://github.com/scummvm/scummvm/commit/c39630ad534a0363193c931f6434de91ff7e9d1d
Author: BLooperZ (blooperz at users.noreply.github.com)
Date: 2020-05-12T14:36:09+02:00

Commit Message:
GRAPHICS: MACGUI: add text renderer and visual pos

Changed paths:
  A graphics/text_renderer.cpp
  A graphics/text_renderer.h
    graphics/macgui/macmenu.cpp
    graphics/module.mk


diff --git a/graphics/macgui/macmenu.cpp b/graphics/macgui/macmenu.cpp
index 1bee51e475..ba5b4671fb 100644
--- a/graphics/macgui/macmenu.cpp
+++ b/graphics/macgui/macmenu.cpp
@@ -33,6 +33,7 @@
 #include "graphics/macgui/macwindowmanager.h"
 #include "graphics/macgui/macwindow.h"
 #include "graphics/macgui/macmenu.h"
+#include "graphics/text_renderer.h"
 
 namespace Graphics {
 
@@ -746,11 +747,12 @@ static void underlineAccelerator(ManagedSurface *dst, const Font *font, const Co
 	if (shortcutPos == -1)
 		return;
 
-	Common::U32String s(str);
+	int visualPos = getVisualPosition(str, shortcutPos);
+	Common::U32String s = Common::convertBiDiU32String(str);
 
 	// Erase characters only if it is not end of the string
-	if ((uint)(shortcutPos + 1) < s.size())
-		s.erase(shortcutPos + 1);
+	if ((uint)(visualPos + 1) < s.size())
+		s.erase(visualPos + 1);
 
 	int pos2 = font->getStringWidth(s);
 	s.deleteLastChar();
@@ -821,20 +823,17 @@ bool MacMenu::draw(ManagedSurface *g, bool forceRedraw) {
 		int y = it->bbox.top + (_wm->_fontMan->hasBuiltInFonts() ? 2 : 1);
 
 		if (it->unicode) {
-			Common::U32String line = convertBiDiU32String(it->unicodeText);
+			// Common::U32String line = convertBiDiU32String(it->unicodeText);
 
-			int accOff = line == it->unicodeText ? 0 : _font->getStringWidth(line);
-			if (_align == kTextAlignRight) {
-				accOff += it->bbox.width() - kMenuLeftMargin - _font->getStringWidth(line);
-			}
+			int accOff = _align == kTextAlignRight ? it->bbox.width() - _font->getStringWidth(it->unicodeText) : 0;
 
 			// FLIP ON RENDER
 			// if (_align == kTextAlignRight) {
 			// 	x = r.right + r.left - it->bbox.width() - x;
 			// }
 
-			_font->drawString(&_screen, line, x, y, it->bbox.width(), color, _align);
-			underlineAccelerator(&_screen, _font, line, x + accOff, y, it->shortcutPos, color);
+			TextRenderer::drawU32String(&_screen, it->unicodeText, *_font, x, y, it->bbox.width(), color, _align);
+			underlineAccelerator(&_screen, _font, it->unicodeText, x + accOff, y, it->shortcutPos, color);
 		} else {
 			const Font *font = getMenuFont(it->style);
 
@@ -867,17 +866,10 @@ void MacMenu::renderSubmenu(MacMenuSubMenu *menu, bool recursive) {
 	_screen.fillRect(*r, _wm->_colorWhite);
 	_screen.frameRect(*r, _wm->_colorBlack);
 
-	if (_align != kTextAlignRight) {
-		_screen.vLine(r->right, r->top + 3, r->bottom + 1, _wm->_colorBlack);
-		_screen.vLine(r->right + 1, r->top + 3, r->bottom + 1, _wm->_colorBlack);
-		_screen.hLine(r->left + 3, r->bottom, r->right + 1, _wm->_colorBlack);
-		_screen.hLine(r->left + 3, r->bottom + 1, r->right + 1, _wm->_colorBlack);
-	} else {
-		_screen.vLine(r->left, r->top + 3, r->bottom + 1, _wm->_colorBlack);
-		_screen.vLine(r->left - 1, r->top + 3, r->bottom + 1, _wm->_colorBlack);
-		_screen.hLine(r->left - 3, r->bottom, r->right - 1, _wm->_colorBlack);
-		_screen.hLine(r->left - 3, r->bottom + 1, r->right - 1, _wm->_colorBlack);
-	}
+	_screen.vLine(r->right, r->top + 3, r->bottom + 1, _wm->_colorBlack);
+	_screen.vLine(r->right + 1, r->top + 3, r->bottom + 1, _wm->_colorBlack);
+	_screen.hLine(r->left + 3, r->bottom, r->right + 1, _wm->_colorBlack);
+	_screen.hLine(r->left + 3, r->bottom + 1, r->right + 1, _wm->_colorBlack);
 
 	int x = r->left + kMenuDropdownPadding;
 	int y = r->top + 1;
@@ -890,12 +882,11 @@ void MacMenu::renderSubmenu(MacMenuSubMenu *menu, bool recursive) {
 		Common::String text(menu->items[i]->text);
 		Common::String acceleratorText(getAcceleratorString(menu->items[i], ""));
 
-		Common::U32String unicodeText = convertBiDiU32String(menu->items[i]->unicodeText);
+		// Common::U32String unicodeText = convertBiDiU32String(menu->items[i]->unicodeText);
+		Common::U32String unicodeText(menu->items[i]->unicodeText);
+
+		int accOff = _align == kTextAlignRight ? r->width() - _font->getStringWidth(unicodeText) : 0;
 
-		int accOff = unicodeText == menu->items[i]->unicodeText ? 0 : _font->getStringWidth(unicodeText);
-		if (_align == kTextAlignRight) {
-			accOff += r->width() - kMenuDropdownPadding - _font->getStringWidth(unicodeText);
-		}
 
 		int shortcutPos = menu->items[i]->shortcutPos;
 
@@ -929,7 +920,7 @@ void MacMenu::renderSubmenu(MacMenuSubMenu *menu, bool recursive) {
 			}
 
 			if (menu->items[i]->unicode) {
-				_font->drawString(s, unicodeText, tx, ty, r->width(), color, _align);
+				TextRenderer::drawU32String(s, unicodeText, *_font, tx, ty, r->width(), color, _align);
 				underlineAccelerator(s, _font, unicodeText, tx + accOff, ty, shortcutPos, color);
 			} else {
 				const Font *font = getMenuFont(menu->items[i]->style);
diff --git a/graphics/module.mk b/graphics/module.mk
index f2a0a52364..dd9b01c5c1 100644
--- a/graphics/module.mk
+++ b/graphics/module.mk
@@ -32,6 +32,7 @@ MODULE_OBJS := \
 	screen.o \
 	sjis.o \
 	surface.o \
+	text_renderer.o \
 	transform_struct.o \
 	transform_tools.o \
 	transparent_surface.o \
diff --git a/graphics/text_renderer.cpp b/graphics/text_renderer.cpp
new file mode 100644
index 0000000000..86e04925b5
--- /dev/null
+++ b/graphics/text_renderer.cpp
@@ -0,0 +1,52 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/str-bidi.h"
+#include "graphics/text_renderer.h"
+
+#ifdef USE_FRIBIDI
+#include <fribidi/fribidi.h>
+#endif
+
+namespace Graphics {
+
+namespace TextRenderer {
+
+void drawString(Surface *dst, const Common::String &str, const Graphics::Font &font, int x, int y, int w, uint32 color, const Common::CodePage page, TextAlign align, int deltax, bool useEllipsis) {
+    font.drawString(dst, convertBiDiString(str, page), x, y, w, color, align, deltax, useEllipsis);
+}
+
+void drawU32String(Surface *dst, const Common::U32String &str, const Graphics::Font &font, int x, int y, int w, uint32 color, TextAlign align, int deltax) {
+    font.drawString(dst, convertBiDiU32String(str), x, y, w, color, align, deltax);
+}
+
+void drawString(ManagedSurface *dst, const Common::String &str, const Graphics::Font &font, int x, int y, int w, uint32 color, const Common::CodePage page, TextAlign align, int deltax, bool useEllipsis) {
+    font.drawString(dst, convertBiDiString(str, page), x, y, w, color, align, deltax, useEllipsis);
+}
+
+void drawU32String(ManagedSurface *dst, const Common::U32String &str, const Graphics::Font &font, int x, int y, int w, uint32 color, TextAlign align, int deltax) {
+    font.drawString(dst, convertBiDiU32String(str), x, y, w, color, align, deltax);
+}
+
+} // End of namespace TextRenderer
+
+} // End of namespace Graphics
diff --git a/graphics/text_renderer.h b/graphics/text_renderer.h
new file mode 100644
index 0000000000..0fadaa3f7a
--- /dev/null
+++ b/graphics/text_renderer.h
@@ -0,0 +1,47 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef GRAPHICS_TEXT_RENDERER_H
+#define GRAPHICS_TEXT_RENDERER_H
+
+#include "common/str.h"
+#include "common/ustr.h"
+#include "common/str-bidi.h"
+#include "graphics/font.h"
+
+namespace Graphics {
+
+/**
+ * high-level methods for drawing strings (with bidi support).
+ */
+namespace TextRenderer {
+
+	// TODO: Add doxygen comments to this
+	void drawString(Surface *dst, const Common::String &str, const Graphics::Font &font, int x, int y, int w, uint32 color, const Common::CodePage page, TextAlign align = kTextAlignLeft, int deltax = 0, bool useEllipsis = true);
+	void drawU32String(Surface *dst, const Common::U32String &str, const Graphics::Font &font, int x, int y, int w, uint32 color, TextAlign align = kTextAlignLeft, int deltax = 0);
+	void drawString(ManagedSurface *dst, const Common::String &str, const Graphics::Font &font, int x, int y, int w, uint32 color, const Common::CodePage page, TextAlign align = kTextAlignLeft, int deltax = 0, bool useEllipsis = true);
+	void drawU32String(ManagedSurface *dst, const Common::U32String &str, const Graphics::Font &font, int x, int y, int w, uint32 color, TextAlign align = kTextAlignLeft, int deltax = 0);
+}
+
+} // End of namespace Graphics
+
+#endif


Commit: 0c30136c0fed5033ff7d1d7b548fcfaf1f0d1883
    https://github.com/scummvm/scummvm/commit/0c30136c0fed5033ff7d1d7b548fcfaf1f0d1883
Author: BLooperZ (blooperz at users.noreply.github.com)
Date: 2020-05-12T14:36:09+02:00

Commit Message:
GRAPHICS: change text renderer parameters position

Changed paths:
    graphics/macgui/macmenu.cpp
    graphics/text_renderer.cpp
    graphics/text_renderer.h


diff --git a/graphics/macgui/macmenu.cpp b/graphics/macgui/macmenu.cpp
index ba5b4671fb..e46c141f30 100644
--- a/graphics/macgui/macmenu.cpp
+++ b/graphics/macgui/macmenu.cpp
@@ -823,16 +823,9 @@ bool MacMenu::draw(ManagedSurface *g, bool forceRedraw) {
 		int y = it->bbox.top + (_wm->_fontMan->hasBuiltInFonts() ? 2 : 1);
 
 		if (it->unicode) {
-			// Common::U32String line = convertBiDiU32String(it->unicodeText);
-
 			int accOff = _align == kTextAlignRight ? it->bbox.width() - _font->getStringWidth(it->unicodeText) : 0;
 
-			// FLIP ON RENDER
-			// if (_align == kTextAlignRight) {
-			// 	x = r.right + r.left - it->bbox.width() - x;
-			// }
-
-			TextRenderer::drawU32String(&_screen, it->unicodeText, *_font, x, y, it->bbox.width(), color, _align);
+			TextRenderer::drawU32String(&_screen, *_font, it->unicodeText, x, y, it->bbox.width(), color, _align);
 			underlineAccelerator(&_screen, _font, it->unicodeText, x + accOff, y, it->shortcutPos, color);
 		} else {
 			const Font *font = getMenuFont(it->style);
@@ -920,7 +913,7 @@ void MacMenu::renderSubmenu(MacMenuSubMenu *menu, bool recursive) {
 			}
 
 			if (menu->items[i]->unicode) {
-				TextRenderer::drawU32String(s, unicodeText, *_font, tx, ty, r->width(), color, _align);
+				TextRenderer::drawU32String(s, *_font, unicodeText, tx, ty, r->width(), color, _align);
 				underlineAccelerator(s, _font, unicodeText, tx + accOff, ty, shortcutPos, color);
 			} else {
 				const Font *font = getMenuFont(menu->items[i]->style);
diff --git a/graphics/text_renderer.cpp b/graphics/text_renderer.cpp
index 86e04925b5..af364c828a 100644
--- a/graphics/text_renderer.cpp
+++ b/graphics/text_renderer.cpp
@@ -31,19 +31,19 @@ namespace Graphics {
 
 namespace TextRenderer {
 
-void drawString(Surface *dst, const Common::String &str, const Graphics::Font &font, int x, int y, int w, uint32 color, const Common::CodePage page, TextAlign align, int deltax, bool useEllipsis) {
+void drawString(Surface *dst, const Graphics::Font &font, const Common::String &str, const Common::CodePage page, int x, int y, int w, uint32 color, TextAlign align, int deltax, bool useEllipsis) {
     font.drawString(dst, convertBiDiString(str, page), x, y, w, color, align, deltax, useEllipsis);
 }
 
-void drawU32String(Surface *dst, const Common::U32String &str, const Graphics::Font &font, int x, int y, int w, uint32 color, TextAlign align, int deltax) {
+void drawU32String(Surface *dst, const Graphics::Font &font,const Common::U32String &str,  int x, int y, int w, uint32 color, TextAlign align, int deltax) {
     font.drawString(dst, convertBiDiU32String(str), x, y, w, color, align, deltax);
 }
 
-void drawString(ManagedSurface *dst, const Common::String &str, const Graphics::Font &font, int x, int y, int w, uint32 color, const Common::CodePage page, TextAlign align, int deltax, bool useEllipsis) {
+void drawString(ManagedSurface *dst, const Graphics::Font &font, const Common::String &str, const Common::CodePage page, int x, int y, int w, uint32 color, TextAlign align, int deltax, bool useEllipsis) {
     font.drawString(dst, convertBiDiString(str, page), x, y, w, color, align, deltax, useEllipsis);
 }
 
-void drawU32String(ManagedSurface *dst, const Common::U32String &str, const Graphics::Font &font, int x, int y, int w, uint32 color, TextAlign align, int deltax) {
+void drawU32String(ManagedSurface *dst, const Graphics::Font &font, const Common::U32String &str, int x, int y, int w, uint32 color, TextAlign align, int deltax) {
     font.drawString(dst, convertBiDiU32String(str), x, y, w, color, align, deltax);
 }
 
diff --git a/graphics/text_renderer.h b/graphics/text_renderer.h
index 0fadaa3f7a..8864d1f63d 100644
--- a/graphics/text_renderer.h
+++ b/graphics/text_renderer.h
@@ -36,10 +36,10 @@ namespace Graphics {
 namespace TextRenderer {
 
 	// TODO: Add doxygen comments to this
-	void drawString(Surface *dst, const Common::String &str, const Graphics::Font &font, int x, int y, int w, uint32 color, const Common::CodePage page, TextAlign align = kTextAlignLeft, int deltax = 0, bool useEllipsis = true);
-	void drawU32String(Surface *dst, const Common::U32String &str, const Graphics::Font &font, int x, int y, int w, uint32 color, TextAlign align = kTextAlignLeft, int deltax = 0);
-	void drawString(ManagedSurface *dst, const Common::String &str, const Graphics::Font &font, int x, int y, int w, uint32 color, const Common::CodePage page, TextAlign align = kTextAlignLeft, int deltax = 0, bool useEllipsis = true);
-	void drawU32String(ManagedSurface *dst, const Common::U32String &str, const Graphics::Font &font, int x, int y, int w, uint32 color, TextAlign align = kTextAlignLeft, int deltax = 0);
+	void drawString(Surface *dst, const Graphics::Font &font, const Common::String &str, const Common::CodePage page, int x, int y, int w, uint32 color, TextAlign align = kTextAlignLeft, int deltax = 0, bool useEllipsis = true);
+	void drawU32String(Surface *dst, const Graphics::Font &font, const Common::U32String &str, int x, int y, int w, uint32 color, TextAlign align = kTextAlignLeft, int deltax = 0);
+	void drawString(ManagedSurface *dst, const Graphics::Font &font, const Common::String &str, const Common::CodePage page, int x, int y, int w, uint32 color, TextAlign align = kTextAlignLeft, int deltax = 0, bool useEllipsis = true);
+	void drawU32String(ManagedSurface *dst, const Graphics::Font &font, const Common::U32String &str, int x, int y, int w, uint32 color, TextAlign align = kTextAlignLeft, int deltax = 0);
 }
 
 } // End of namespace Graphics


Commit: a92864c8c181ef6c4a4b10ce51877e87f2045ac2
    https://github.com/scummvm/scummvm/commit/a92864c8c181ef6c4a4b10ce51877e87f2045ac2
Author: BLooperZ (blooperz at users.noreply.github.com)
Date: 2020-05-12T14:36:09+02:00

Commit Message:
GRAPHICS: MACGUI: allow setting widget alignment

Changed paths:
    graphics/macgui/macmenu.cpp
    graphics/macgui/macmenu.h


diff --git a/graphics/macgui/macmenu.cpp b/graphics/macgui/macmenu.cpp
index e46c141f30..df4a75623d 100644
--- a/graphics/macgui/macmenu.cpp
+++ b/graphics/macgui/macmenu.cpp
@@ -109,7 +109,7 @@ MacMenu::MacMenu(int id, const Common::Rect &bounds, MacWindowManager *wm)
 		: BaseMacWindow(id, false, wm) {
 	_font = getMenuFont();
 
-	_align = kTextAlignRight;
+	_align = kTextAlignLeft;
 
 	_screen.create(bounds.width(), bounds.height(), PixelFormat::createFormatCLUT8());
 
@@ -192,6 +192,9 @@ static Common::U32String readUnicodeString(Common::SeekableReadStream *stream) {
 	return strData.empty() ? Common::U32String() : Common::U32String(strData.data(), strData.size());
 }
 
+void MacMenu::setAlignment(Graphics::TextAlign align) {
+	_align = align;
+}
 
 MacMenu *MacMenu::createMenuFromPEexe(Common::PEResources *exe, MacWindowManager *wm) {
 	Common::SeekableReadStream *menuData = exe->getResource(Common::kWinMenu, 128);
@@ -404,7 +407,6 @@ void MacMenu::calcDimensions() {
 
 		calcSubMenuBounds(_items[i]->submenu, _items[i]->bbox.left - 1, _items[i]->bbox.bottom + 1);
 
-		// FLIP ON CREATE
 		if (_align == kTextAlignRight) {
 			int right = _items[i]->bbox.right;
 			int width = right - _items[i]->bbox.left;
@@ -793,17 +795,10 @@ bool MacMenu::draw(ManagedSurface *g, bool forceRedraw) {
 		if ((uint)_activeItem == i) {
 			Common::Rect hbox = it->bbox;
 
-			// FLIP ON RENDER
-			// if (_align == kTextAlignRight) {
-			// 	hbox.left = r.right + r.left - it->bbox.width() - hbox.left;
-			// 	hbox.right = hbox.left + it->bbox.width();
-			// }
-
 			hbox.left -= 1;
 			hbox.right += 3;
 			hbox.bottom += 1;
 
-			// FLIP ON CREATE
 			if (_align == kTextAlignRight) {
 				hbox.left -= 2;
 				hbox.right -= 2;
@@ -813,14 +808,9 @@ bool MacMenu::draw(ManagedSurface *g, bool forceRedraw) {
 			color = _wm->_colorWhite;
 		}
 
-		int x = it->bbox.left + kMenuLeftMargin;
-
-		// FLIP ON CREATE
-		if (_align == kTextAlignRight) {
-			x -= 2 * kMenuLeftMargin;
-		}
-
 		int y = it->bbox.top + (_wm->_fontMan->hasBuiltInFonts() ? 2 : 1);
+		int x = _align == kTextAlignRight ? -kMenuLeftMargin : kMenuLeftMargin;
+		x += it->bbox.left;
 
 		if (it->unicode) {
 			int accOff = _align == kTextAlignRight ? it->bbox.width() - _font->getStringWidth(it->unicodeText) : 0;
@@ -858,29 +848,23 @@ void MacMenu::renderSubmenu(MacMenuSubMenu *menu, bool recursive) {
 
 	_screen.fillRect(*r, _wm->_colorWhite);
 	_screen.frameRect(*r, _wm->_colorBlack);
-
 	_screen.vLine(r->right, r->top + 3, r->bottom + 1, _wm->_colorBlack);
 	_screen.vLine(r->right + 1, r->top + 3, r->bottom + 1, _wm->_colorBlack);
 	_screen.hLine(r->left + 3, r->bottom, r->right + 1, _wm->_colorBlack);
 	_screen.hLine(r->left + 3, r->bottom + 1, r->right + 1, _wm->_colorBlack);
 
-	int x = r->left + kMenuDropdownPadding;
 	int y = r->top + 1;
-
-	if (_align == kTextAlignRight) {
-		x -= 2 * kMenuDropdownPadding;
-	}
+	int x = _align == kTextAlignRight ? -kMenuDropdownPadding : kMenuDropdownPadding;
+	x += r->left;
 
 	for (uint i = 0; i < menu->items.size(); i++) {
 		Common::String text(menu->items[i]->text);
 		Common::String acceleratorText(getAcceleratorString(menu->items[i], ""));
 
-		// Common::U32String unicodeText = convertBiDiU32String(menu->items[i]->unicodeText);
 		Common::U32String unicodeText(menu->items[i]->unicodeText);
 
 		int accOff = _align == kTextAlignRight ? r->width() - _font->getStringWidth(unicodeText) : 0;
 
-
 		int shortcutPos = menu->items[i]->shortcutPos;
 
 		int accelX = r->right - 25;
diff --git a/graphics/macgui/macmenu.h b/graphics/macgui/macmenu.h
index 8054240c11..3857ab0cf7 100644
--- a/graphics/macgui/macmenu.h
+++ b/graphics/macgui/macmenu.h
@@ -55,6 +55,8 @@ public:
 	static Common::StringArray *readMenuFromResource(Common::SeekableReadStream *res);
 	static MacMenu *createMenuFromPEexe(Common::PEResources *exe, MacWindowManager *wm);
 
+	void setAlignment(Graphics::TextAlign align);
+
 	void setCommandsCallback(void (*callback)(int, Common::String &, void *), void *data) { _ccallback = callback; _cdata = data; }
 	void setCommandsCallback(void (*callback)(int, Common::U32String &, void *), void *data) { _unicodeccallback = callback; _cdata = data; }
 


Commit: abeb33fb7197db3ddaed63096d58f2b9ac2744a1
    https://github.com/scummvm/scummvm/commit/abeb33fb7197db3ddaed63096d58f2b9ac2744a1
Author: BLooperZ (blooperz at users.noreply.github.com)
Date: 2020-05-12T14:36:09+02:00

Commit Message:
PINK: use RTL menu in hebrew version

Changed paths:
    engines/pink/gui.cpp


diff --git a/engines/pink/gui.cpp b/engines/pink/gui.cpp
index d256e92f52..1e97eb86c1 100644
--- a/engines/pink/gui.cpp
+++ b/engines/pink/gui.cpp
@@ -135,6 +135,9 @@ void PinkEngine::initMenu() {
 	_director->getWndManager().setEngine(this);
 
 	_menu = Graphics::MacMenu::createMenuFromPEexe(_exeResources, &_director->getWndManager());
+	if (getLanguage() == Common::HE_ISR) {
+		_menu->setAlignment(Graphics::kTextAlignRight);
+	}
 	_menu->calcDimensions();
 	_menu->setCommandsCallback(&menuCommandsCallback, this);
 }


Commit: 432dd88bdbad77abcd943228b4a2ad799593f88a
    https://github.com/scummvm/scummvm/commit/432dd88bdbad77abcd943228b4a2ad799593f88a
Author: BLooperZ (blooperz at users.noreply.github.com)
Date: 2020-05-12T14:36:09+02:00

Commit Message:
GRAPHICS: MACTEXT: draw bidi text

Changed paths:
    graphics/macgui/mactext.cpp


diff --git a/graphics/macgui/mactext.cpp b/graphics/macgui/mactext.cpp
index dd3c1749a4..7e64bc2c61 100644
--- a/graphics/macgui/mactext.cpp
+++ b/graphics/macgui/mactext.cpp
@@ -23,6 +23,7 @@
 #include "graphics/macgui/mactext.h"
 #include "graphics/macgui/macwindowmanager.h"
 #include "graphics/font.h"
+#include "graphics/text_renderer.h"
 
 namespace Graphics {
 
@@ -462,7 +463,7 @@ void MacText::render(int from, int to) {
 				yOffset = maxHeightForRow - _textLines[i].chunks[j].font->getFontHeight() - 2;
 			}
 
-			_textLines[i].chunks[j].getFont()->drawString(_surface, _textLines[i].chunks[j].text, xOffset, _textLines[i].y + yOffset, w, _fgcolor);
+			TextRenderer::drawU32String(_surface, *_textLines[i].chunks[j].getFont(), _textLines[i].chunks[j].text, xOffset, _textLines[i].y + yOffset, w, _fgcolor);
 			xOffset += _textLines[i].chunks[j].getFont()->getStringWidth(_textLines[i].chunks[j].text);
 		}
 	}


Commit: f8e2cc0f0ff2044f2935787f7efe1ec0fddf2160
    https://github.com/scummvm/scummvm/commit/f8e2cc0f0ff2044f2935787f7efe1ec0fddf2160
Author: BLooperZ (blooperz at users.noreply.github.com)
Date: 2020-05-12T14:36:09+02:00

Commit Message:
PINK: draw hebrew characters on pages

Changed paths:
    engines/pink/objects/actions/action_text.cpp


diff --git a/engines/pink/objects/actions/action_text.cpp b/engines/pink/objects/actions/action_text.cpp
index 146ea3f140..3e1d43f0c8 100644
--- a/engines/pink/objects/actions/action_text.cpp
+++ b/engines/pink/objects/actions/action_text.cpp
@@ -90,6 +90,13 @@ void ActionText::start() {
 		_text = Common::String(str).decode(Common::kWindows1251);
 		break;
 
+	case Common::HE_ISR:
+		_text = Common::String(str).decode(Common::kWindows1255);
+		if (!_centered) {
+			align = Graphics::kTextAlignRight;
+		}
+		break;
+
 	case Common::EN_ANY:
 	default:
 		_text = Common::String(str);
@@ -131,6 +138,9 @@ void ActionText::end() {
 void ActionText::draw(Graphics::ManagedSurface *surface) {
 	// not working
 	Graphics::TextAlign alignment = _centered ? Graphics::kTextAlignCenter : Graphics::kTextAlignLeft;
+	if (!_centered && _actor->getPage()->getGame()->getLanguage() == Common::HE_ISR) {
+		alignment = Graphics::kTextAlignRight;
+	}
 	Graphics::MacFont *font = new Graphics::MacFont();
 	Director *director = _actor->getPage()->getGame()->getDirector();
 	Graphics::MacText text(_text, &director->getWndManager(), font, _textColorIndex, _backgroundColorIndex, _xRight - _xLeft, alignment);


Commit: 6a653312e21e167fa9ed0fdd8685d8deb8523c1d
    https://github.com/scummvm/scummvm/commit/6a653312e21e167fa9ed0fdd8685d8deb8523c1d
Author: BLooperZ (blooperz at users.noreply.github.com)
Date: 2020-05-12T14:36:09+02:00

Commit Message:
GRAPHICS: remove text_renderer

Changed paths:
  R graphics/text_renderer.cpp
  R graphics/text_renderer.h
    graphics/macgui/macmenu.cpp
    graphics/macgui/mactext.cpp
    graphics/module.mk


diff --git a/graphics/macgui/macmenu.cpp b/graphics/macgui/macmenu.cpp
index df4a75623d..97223b5e56 100644
--- a/graphics/macgui/macmenu.cpp
+++ b/graphics/macgui/macmenu.cpp
@@ -33,7 +33,6 @@
 #include "graphics/macgui/macwindowmanager.h"
 #include "graphics/macgui/macwindow.h"
 #include "graphics/macgui/macmenu.h"
-#include "graphics/text_renderer.h"
 
 namespace Graphics {
 
@@ -815,7 +814,7 @@ bool MacMenu::draw(ManagedSurface *g, bool forceRedraw) {
 		if (it->unicode) {
 			int accOff = _align == kTextAlignRight ? it->bbox.width() - _font->getStringWidth(it->unicodeText) : 0;
 
-			TextRenderer::drawU32String(&_screen, *_font, it->unicodeText, x, y, it->bbox.width(), color, _align);
+			_font->drawString(&_screen, convertBiDiU32String(it->unicodeText), x, y, it->bbox.width(), color, _align);
 			underlineAccelerator(&_screen, _font, it->unicodeText, x + accOff, y, it->shortcutPos, color);
 		} else {
 			const Font *font = getMenuFont(it->style);
@@ -897,7 +896,7 @@ void MacMenu::renderSubmenu(MacMenuSubMenu *menu, bool recursive) {
 			}
 
 			if (menu->items[i]->unicode) {
-				TextRenderer::drawU32String(s, *_font, unicodeText, tx, ty, r->width(), color, _align);
+				_font->drawString(s, convertBiDiU32String(unicodeText), tx, ty, r->width(), color, _align);
 				underlineAccelerator(s, _font, unicodeText, tx + accOff, ty, shortcutPos, color);
 			} else {
 				const Font *font = getMenuFont(menu->items[i]->style);
diff --git a/graphics/macgui/mactext.cpp b/graphics/macgui/mactext.cpp
index 7e64bc2c61..2eda6ab5fe 100644
--- a/graphics/macgui/mactext.cpp
+++ b/graphics/macgui/mactext.cpp
@@ -19,11 +19,12 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
+#include "common/str-bidi.h"
+
 #include "graphics/macgui/macfontmanager.h"
 #include "graphics/macgui/mactext.h"
 #include "graphics/macgui/macwindowmanager.h"
 #include "graphics/font.h"
-#include "graphics/text_renderer.h"
 
 namespace Graphics {
 
@@ -463,7 +464,7 @@ void MacText::render(int from, int to) {
 				yOffset = maxHeightForRow - _textLines[i].chunks[j].font->getFontHeight() - 2;
 			}
 
-			TextRenderer::drawU32String(_surface, *_textLines[i].chunks[j].getFont(), _textLines[i].chunks[j].text, xOffset, _textLines[i].y + yOffset, w, _fgcolor);
+			_textLines[i].chunks[j].getFont()->drawString(_surface, convertBiDiU32String(_textLines[i].chunks[j].text), xOffset, _textLines[i].y + yOffset, w, _fgcolor);
 			xOffset += _textLines[i].chunks[j].getFont()->getStringWidth(_textLines[i].chunks[j].text);
 		}
 	}
diff --git a/graphics/module.mk b/graphics/module.mk
index dd9b01c5c1..f2a0a52364 100644
--- a/graphics/module.mk
+++ b/graphics/module.mk
@@ -32,7 +32,6 @@ MODULE_OBJS := \
 	screen.o \
 	sjis.o \
 	surface.o \
-	text_renderer.o \
 	transform_struct.o \
 	transform_tools.o \
 	transparent_surface.o \
diff --git a/graphics/text_renderer.cpp b/graphics/text_renderer.cpp
deleted file mode 100644
index af364c828a..0000000000
--- a/graphics/text_renderer.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/str-bidi.h"
-#include "graphics/text_renderer.h"
-
-#ifdef USE_FRIBIDI
-#include <fribidi/fribidi.h>
-#endif
-
-namespace Graphics {
-
-namespace TextRenderer {
-
-void drawString(Surface *dst, const Graphics::Font &font, const Common::String &str, const Common::CodePage page, int x, int y, int w, uint32 color, TextAlign align, int deltax, bool useEllipsis) {
-    font.drawString(dst, convertBiDiString(str, page), x, y, w, color, align, deltax, useEllipsis);
-}
-
-void drawU32String(Surface *dst, const Graphics::Font &font,const Common::U32String &str,  int x, int y, int w, uint32 color, TextAlign align, int deltax) {
-    font.drawString(dst, convertBiDiU32String(str), x, y, w, color, align, deltax);
-}
-
-void drawString(ManagedSurface *dst, const Graphics::Font &font, const Common::String &str, const Common::CodePage page, int x, int y, int w, uint32 color, TextAlign align, int deltax, bool useEllipsis) {
-    font.drawString(dst, convertBiDiString(str, page), x, y, w, color, align, deltax, useEllipsis);
-}
-
-void drawU32String(ManagedSurface *dst, const Graphics::Font &font, const Common::U32String &str, int x, int y, int w, uint32 color, TextAlign align, int deltax) {
-    font.drawString(dst, convertBiDiU32String(str), x, y, w, color, align, deltax);
-}
-
-} // End of namespace TextRenderer
-
-} // End of namespace Graphics
diff --git a/graphics/text_renderer.h b/graphics/text_renderer.h
deleted file mode 100644
index 8864d1f63d..0000000000
--- a/graphics/text_renderer.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef GRAPHICS_TEXT_RENDERER_H
-#define GRAPHICS_TEXT_RENDERER_H
-
-#include "common/str.h"
-#include "common/ustr.h"
-#include "common/str-bidi.h"
-#include "graphics/font.h"
-
-namespace Graphics {
-
-/**
- * high-level methods for drawing strings (with bidi support).
- */
-namespace TextRenderer {
-
-	// TODO: Add doxygen comments to this
-	void drawString(Surface *dst, const Graphics::Font &font, const Common::String &str, const Common::CodePage page, int x, int y, int w, uint32 color, TextAlign align = kTextAlignLeft, int deltax = 0, bool useEllipsis = true);
-	void drawU32String(Surface *dst, const Graphics::Font &font, const Common::U32String &str, int x, int y, int w, uint32 color, TextAlign align = kTextAlignLeft, int deltax = 0);
-	void drawString(ManagedSurface *dst, const Graphics::Font &font, const Common::String &str, const Common::CodePage page, int x, int y, int w, uint32 color, TextAlign align = kTextAlignLeft, int deltax = 0, bool useEllipsis = true);
-	void drawU32String(ManagedSurface *dst, const Graphics::Font &font, const Common::U32String &str, int x, int y, int w, uint32 color, TextAlign align = kTextAlignLeft, int deltax = 0);
-}
-
-} // End of namespace Graphics
-
-#endif


Commit: ec83715b430bddb9a67f1b7fe0e59bb42810be5e
    https://github.com/scummvm/scummvm/commit/ec83715b430bddb9a67f1b7fe0e59bb42810be5e
Author: BLooperZ (blooperz at users.noreply.github.com)
Date: 2020-05-12T14:36:09+02:00

Commit Message:
COMMON: add UnicodeBiDiText wrapper

Changed paths:
  A common/unicode-bidi.cpp
  A common/unicode-bidi.h
  R common/str-bidi.cpp
  R common/str-bidi.h
    common/module.mk
    common/translation.cpp
    common/ustr.cpp
    common/ustr.h
    graphics/macgui/macmenu.cpp
    graphics/macgui/mactext.cpp


diff --git a/common/module.mk b/common/module.mk
index 43b6493e8c..4887858d16 100644
--- a/common/module.mk
+++ b/common/module.mk
@@ -30,7 +30,6 @@ MODULE_OBJS := \
 	rational.o \
 	rendermode.o \
 	str.o \
-	str-bidi.o \
 	str-enc.o \
 	stream.o \
 	system.o \
@@ -38,6 +37,7 @@ MODULE_OBJS := \
 	tokenizer.o \
 	translation.o \
 	unarj.o \
+	unicode-bidi.o \
 	unzip.o \
 	ustr.o \
 	util.o \
diff --git a/common/str-bidi.cpp b/common/str-bidi.cpp
deleted file mode 100644
index 896b57c859..0000000000
--- a/common/str-bidi.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/str-bidi.h"
-#include "common/textconsole.h"
-
-#ifdef USE_FRIBIDI
-#include <fribidi/fribidi.h>
-#endif
-
-namespace Common {
-
-String convertBiDiString(const String &input, const Common::CodePage page) {
-	return convertBiDiU32String(input.decode(page)).encode(page);
-}
-
-U32String convertBiDiU32String(const U32String &input) {
-
-#ifdef USE_FRIBIDI
-	int buff_length = (input.size() + 2) * 2;		// it's more than enough, but it's better to be on the safe side
-	FriBidiChar *visual_str = (FriBidiChar *)malloc(buff_length * sizeof(FriBidiChar));
-
-	FriBidiCharType pbase_dir = FRIBIDI_TYPE_ON;
-
-	if (!fribidi_log2vis(
-		/* input */
-		(const FriBidiChar *)input.c_str(),
-		input.size(),
-		&pbase_dir,
-		/* output */
-		visual_str,
-		NULL,			// position_L_to_V_list,
-		NULL,			// position_V_to_L_list,
-		NULL			// embedding_level_list
-	)) {
-		warning("convertBiDiU32String: calling fribidi_log2vis failed");
-		free(visual_str);
-		return input;
-	}
-
-	U32String result = U32String(visual_str, input.size());
-	free(visual_str);
-
-	return result;
-#else
-	warning("convertBiDiU32String: Fribidi not available, using input string as fallback");
-	return input;
-#endif
-
-}
-
-int getVisualPosition(const U32String &str, int pos) {
-	Common::U32String suffix(str.c_str() + pos + 1);
-	Common::U32String visual_str = Common::convertBiDiU32String(str);
-	Common::U32String visual_prefix(visual_str.c_str(), suffix.size());
-	Common::U32String visual_suffix = Common::convertBiDiU32String(suffix);
-	return visual_prefix == visual_suffix ? suffix.size() : pos;
-}
-
-int getVisualPosition(const String &str, const Common::CodePage page, int logicalPos) {
-	return getVisualPosition(str.decode(page), logicalPos);
-}
-
-} // End of namespace Common
diff --git a/common/translation.cpp b/common/translation.cpp
index 2aa518a8eb..8007041878 100644
--- a/common/translation.cpp
+++ b/common/translation.cpp
@@ -33,7 +33,7 @@
 #include "common/fs.h"
 #include "common/system.h"
 #include "common/textconsole.h"
-#include "common/str-bidi.h"
+#include "common/unicode-bidi.h"
 
 #ifdef USE_TRANSLATION
 
diff --git a/common/unicode-bidi.cpp b/common/unicode-bidi.cpp
new file mode 100644
index 0000000000..1e5c9f9cd7
--- /dev/null
+++ b/common/unicode-bidi.cpp
@@ -0,0 +1,106 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/ustr.h"
+#include "common/unicode-bidi.h"
+#include "common/textconsole.h"
+
+#ifdef USE_FRIBIDI
+#include <fribidi/fribidi.h>
+#endif
+
+namespace Common {
+
+UnicodeBiDiText::UnicodeBiDiText(const Common::U32String &str) : logical(str), _log_to_vis_index(NULL), _vis_to_log_index(NULL) {
+	initWithU32String(str);
+}
+
+UnicodeBiDiText::UnicodeBiDiText(const Common::String &str, const Common::CodePage page) : logical(str), _log_to_vis_index(NULL), _vis_to_log_index(NULL) {
+	initWithU32String(str.decode(page));
+}
+
+UnicodeBiDiText::~UnicodeBiDiText() {
+	delete[] _log_to_vis_index;
+	delete[] _vis_to_log_index;
+}
+
+uint32 UnicodeBiDiText::getVisualPosition(uint32 logicalPos) const { 
+	if (NULL != _log_to_vis_index && logicalPos < size()) {
+		return _log_to_vis_index[logicalPos];
+	}
+	return logicalPos;
+}
+uint32 UnicodeBiDiText::getLogicalPosition(uint32 visualPos) const {
+	if (NULL != _log_to_vis_index && visualPos < size()) {
+		return _vis_to_log_index[visualPos];
+	}
+	return visualPos;
+}
+
+void UnicodeBiDiText::initWithU32String(const U32String &input) {
+
+#ifdef USE_FRIBIDI
+	uint32 input_size = input.size();
+	uint32 buff_length = (input_size + 2) * 2;		// it's more than enough, but it's better to be on the safe side
+	FriBidiChar *visual_str = new FriBidiChar[buff_length * sizeof(FriBidiChar)];
+	_log_to_vis_index = new uint32[input_size];
+	_vis_to_log_index = new uint32[input_size];
+	FriBidiCharType pbase_dir = FRIBIDI_TYPE_ON;
+
+	if (!fribidi_log2vis(
+		/* input */
+		(const FriBidiChar *)input.c_str(),
+		input_size,
+		&pbase_dir,
+		/* output */
+		visual_str,
+		(FriBidiStrIndex *)_log_to_vis_index,	// position_L_to_V_list,
+		(FriBidiStrIndex *)_vis_to_log_index,	// position_V_to_L_list,
+		NULL									// embedding_level_list
+	)) {
+		warning("initWithU32String: calling fribidi_log2vis failed");
+		delete[] visual_str;
+		delete[] _log_to_vis_index;
+		delete[] _vis_to_log_index;
+		visual = input;
+		_log_to_vis_index = NULL;
+		_vis_to_log_index = NULL;
+	} else {
+		visual = U32String(visual_str, input.size());
+		delete[] visual_str;
+	}
+#else
+	warning("initWithU32String: Fribidi not available, using input string as fallback");
+	visual = input;
+#endif
+
+}
+
+String convertBiDiString(const String &input, const Common::CodePage page) {
+	return convertBiDiU32String(input.decode(page)).visual.encode(page);
+}
+
+UnicodeBiDiText convertBiDiU32String(const U32String &input) {
+	return UnicodeBiDiText(input);
+}
+
+} // End of namespace Common
diff --git a/common/str-bidi.h b/common/unicode-bidi.h
similarity index 61%
rename from common/str-bidi.h
rename to common/unicode-bidi.h
index 5e531526a7..414f9a1e0d 100644
--- a/common/str-bidi.h
+++ b/common/unicode-bidi.h
@@ -25,20 +25,30 @@
 
 #include "common/str.h"
 #include "common/ustr.h"
-#include "common/str-enc.h"
 
 namespace Common {
 
-/*
- * Wrapper for GNU FriBidi implementation of the Unicode Bidirectional Algorithm
- * For LTR (Left To Right) languages, returns the original input
- * For RTL (Right To Left) languages, returns visual representation of a logical single-line input
- */
-U32String convertBiDiU32String(const U32String &input);
-String convertBiDiString(const String &input, const Common::CodePage page);
+class UnicodeBiDiText {
+private:
+	uint32 *_log_to_vis_index; // from fribidi conversion
+	uint32 *_vis_to_log_index; // from fribidi conversion
+	void initWithU32String(const Common::U32String &str);
+public:
+	const Common::U32String logical; // original string, ordered logically
+	Common::U32String visual; // from fribidi conversion, ordered visually
+
+	UnicodeBiDiText(const Common::U32String &str);
+	UnicodeBiDiText(const Common::String &str, const Common::CodePage page);
+	~UnicodeBiDiText();
 
-int getVisualPosition(const U32String &str, int pos);
-int getVisualPosition(const String &str, const Common::CodePage page, int pos);
+	uint32 getVisualPosition(uint32 logicalPos) const;
+	uint32 getLogicalPosition(uint32 visualPos) const;
+	uint32 size() const { return logical.size(); }
+};
+
+/* just call the constructor for convenience */
+UnicodeBiDiText convertBiDiU32String(const U32String &input);
+String convertBiDiString(const String &input, const Common::CodePage page);
 
 } // End of namespace Common
 
diff --git a/common/ustr.cpp b/common/ustr.cpp
index f85237a788..5a45a8bec1 100644
--- a/common/ustr.cpp
+++ b/common/ustr.cpp
@@ -23,6 +23,7 @@
 #include "common/ustr.h"
 #include "common/memorypool.h"
 #include "common/util.h"
+#include "unicode-bidi.h"
 
 namespace Common {
 
@@ -94,6 +95,10 @@ U32String::U32String(const String &str) : _size(0), _str(_storage) {
 	initWithCStr(str.c_str(), str.size());
 }
 
+U32String::U32String(const UnicodeBiDiText &txt) : _size(0), _str(_storage) {
+	initWithCStr(txt.visual.c_str(), txt.visual.size());
+}
+
 U32String::~U32String() {
 	decRefCount(_extern._refCount);
 }
diff --git a/common/ustr.h b/common/ustr.h
index 7fbc9bb040..fd93ebd89d 100644
--- a/common/ustr.h
+++ b/common/ustr.h
@@ -29,6 +29,7 @@
 namespace Common {
 
 class String;
+class UnicodeBiDiText;
 
 /**
  * Very simple string class for UTF-32 strings in ScummVM. The main intention
@@ -103,6 +104,9 @@ public:
 	/** Construct a copy of the given string. */
 	U32String(const U32String &str);
 
+	/** Construct a copy of the given unicode BiDi converted string. */
+	U32String(const UnicodeBiDiText &txt);
+
 	/** Construct a new string from the given NULL-terminated C string. */
 	explicit U32String(const char *str);
 
diff --git a/graphics/macgui/macmenu.cpp b/graphics/macgui/macmenu.cpp
index 97223b5e56..c2426a2e3c 100644
--- a/graphics/macgui/macmenu.cpp
+++ b/graphics/macgui/macmenu.cpp
@@ -25,7 +25,7 @@
 #include "common/keyboard.h"
 #include "common/macresman.h"
 #include "common/winexe_pe.h"
-#include "common/str-bidi.h"
+#include "common/unicode-bidi.h"
 
 #include "graphics/primitives.h"
 #include "graphics/font.h"
@@ -744,12 +744,12 @@ static void drawFilledRoundRect(ManagedSurface *surface, Common::Rect &rect, int
 	drawRoundRect(rect, arc, color, true, drawPixelPlain, surface);
 }
 
-static void underlineAccelerator(ManagedSurface *dst, const Font *font, const Common::U32String &str, int x, int y, int shortcutPos, uint32 color) {
+static void underlineAccelerator(ManagedSurface *dst, const Font *font, const Common::UnicodeBiDiText &txt, int x, int y, int shortcutPos, uint32 color) {
 	if (shortcutPos == -1)
 		return;
 
-	int visualPos = getVisualPosition(str, shortcutPos);
-	Common::U32String s = Common::convertBiDiU32String(str);
+	int visualPos = txt.getVisualPosition(shortcutPos);
+	Common::U32String s(txt.visual);
 
 	// Erase characters only if it is not end of the string
 	if ((uint)(visualPos + 1) < s.size())
@@ -813,9 +813,10 @@ bool MacMenu::draw(ManagedSurface *g, bool forceRedraw) {
 
 		if (it->unicode) {
 			int accOff = _align == kTextAlignRight ? it->bbox.width() - _font->getStringWidth(it->unicodeText) : 0;
+			Common::UnicodeBiDiText utxt(it->unicodeText);
 
-			_font->drawString(&_screen, convertBiDiU32String(it->unicodeText), x, y, it->bbox.width(), color, _align);
-			underlineAccelerator(&_screen, _font, it->unicodeText, x + accOff, y, it->shortcutPos, color);
+			_font->drawString(&_screen, utxt.visual, x, y, it->bbox.width(), color, _align);
+			underlineAccelerator(&_screen, _font, utxt, x + accOff, y, it->shortcutPos, color);
 		} else {
 			const Font *font = getMenuFont(it->style);
 
@@ -896,8 +897,9 @@ void MacMenu::renderSubmenu(MacMenuSubMenu *menu, bool recursive) {
 			}
 
 			if (menu->items[i]->unicode) {
-				_font->drawString(s, convertBiDiU32String(unicodeText), tx, ty, r->width(), color, _align);
-				underlineAccelerator(s, _font, unicodeText, tx + accOff, ty, shortcutPos, color);
+				Common::UnicodeBiDiText utxt(unicodeText);
+				_font->drawString(s, utxt.visual, tx, ty, r->width(), color, _align);
+				underlineAccelerator(s, _font, utxt, tx + accOff, ty, shortcutPos, color);
 			} else {
 				const Font *font = getMenuFont(menu->items[i]->style);
 
diff --git a/graphics/macgui/mactext.cpp b/graphics/macgui/mactext.cpp
index 2eda6ab5fe..8675b12f74 100644
--- a/graphics/macgui/mactext.cpp
+++ b/graphics/macgui/mactext.cpp
@@ -19,7 +19,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
-#include "common/str-bidi.h"
+#include "common/unicode-bidi.h"
 
 #include "graphics/macgui/macfontmanager.h"
 #include "graphics/macgui/mactext.h"




More information about the Scummvm-git-logs mailing list