mirror of https://github.com/OpenTTD/OpenTTD.git
(svn r15837) -Codechange: support SETX(Y) with RTL text, swap alignment for RTL text.
This commit is contained in:
parent
8cba245791
commit
5c44bb6b63
128
src/gfx.cpp
128
src/gfx.cpp
|
@ -18,6 +18,7 @@
|
|||
#include "core/sort_func.hpp"
|
||||
#include "landscape_type.h"
|
||||
#include "network/network_func.h"
|
||||
#include "core/smallvec_type.hpp"
|
||||
|
||||
#include "table/palettes.h"
|
||||
#include "table/sprites.h"
|
||||
|
@ -394,42 +395,113 @@ static int TruncateString(char *str, int maxw)
|
|||
*/
|
||||
static int DrawString(int left, int right, int top, char *str, const char *last, TextColour colour, StringAlignment align, bool underline = false, bool truncate = true)
|
||||
{
|
||||
/* We need the outer limits of both left/right */
|
||||
int min_left = INT32_MAX;
|
||||
int max_right = INT32_MIN;
|
||||
|
||||
int initial_left = left;
|
||||
int initial_right = right;
|
||||
int initial_top = top;
|
||||
|
||||
if (truncate) TruncateString(str, right - left);
|
||||
HandleBiDiAndArabicShapes(str, last);
|
||||
|
||||
int w = GetStringBoundingBox(str).width;
|
||||
|
||||
/* right is the right most position to draw on. In this case we want to do
|
||||
* calculations with the width of the string. In comparison right can be
|
||||
* seen as lastof(todraw) and width as lengthof(todraw). They differ by 1.
|
||||
* So most +1/-1 additions are to move from lengthof to 'indices'.
|
||||
/*
|
||||
* To support SETX and SETXY properly with RTL languages we have to
|
||||
* calculate the offsets from the right. To do this we need to split
|
||||
* the string and draw the parts separated by SETX(Y).
|
||||
* So here we split
|
||||
*/
|
||||
switch (align) {
|
||||
case SA_LEFT:
|
||||
/* right + 1 = left + w */
|
||||
right = left + w - 1;
|
||||
break;
|
||||
static SmallVector<char *, 4> setx_offsets;
|
||||
setx_offsets.Clear();
|
||||
*setx_offsets.Append() = str;
|
||||
|
||||
case SA_CENTER:
|
||||
/* The second + 1 is to round to the closest number */
|
||||
left = (right + 1 + left - w + 1) / 2;
|
||||
/* right + 1 = left + w */
|
||||
right = left + w - 1;
|
||||
break;
|
||||
char *loc = str;
|
||||
for (;;) {
|
||||
WChar c;
|
||||
/* We cannot use Utf8Consume as we need the location of the SETX(Y) */
|
||||
size_t len = Utf8Decode(&c, loc);
|
||||
if (c == '\0') break;
|
||||
if (c != SCC_SETX && c != SCC_SETXY) {
|
||||
loc += len;
|
||||
continue;
|
||||
}
|
||||
|
||||
case SA_RIGHT:
|
||||
left = right + 1 - w;
|
||||
break;
|
||||
if (align != SA_LEFT) {
|
||||
DEBUG(grf, 1, "Using SETX and/or SETXY when not aligned to the left. Fixing alignment...");
|
||||
align = SA_LEFT;
|
||||
}
|
||||
|
||||
default:
|
||||
NOT_REACHED();
|
||||
}
|
||||
ReallyDoDrawString(str, left, top, colour, !truncate);
|
||||
if (underline) {
|
||||
GfxFillRect(left, top + 10, right, top + 10, _string_colourremap[1]);
|
||||
/* We add the begin of the string, but don't add it twice */
|
||||
if (loc != str) *setx_offsets.Append() = loc;
|
||||
|
||||
/* Skip the SCC_SETX(Y) ... */
|
||||
loc += len;
|
||||
/* ... skip the x coordinate ... */
|
||||
loc++;
|
||||
/* ... and finally the y coordinate if it exists */
|
||||
if (c == SCC_SETXY) loc++;
|
||||
}
|
||||
|
||||
return align == SA_RIGHT ? left : right;
|
||||
/* In case we have a RTL language we swap the alignment. */
|
||||
if (_dynlang.text_dir == TD_RTL && align != SA_CENTER) align = (StringAlignment)(align ^ 2);
|
||||
|
||||
/* Now draw the parts. This is done in the reverse order so we can give the
|
||||
* BiDi algorithm the room to replace characters. It also simplifies
|
||||
* 'ending' the strings. */
|
||||
for (char **iter = setx_offsets.End(); iter-- != setx_offsets.Begin(); ) {
|
||||
char *to_draw = *iter;
|
||||
WChar c;
|
||||
size_t len = Utf8Decode(&c, to_draw);
|
||||
int offset = 0;
|
||||
|
||||
/* Skip the SETX(Y) and set the appropriate offsets. */
|
||||
if (c == SCC_SETX || c == SCC_SETXY) {
|
||||
*to_draw = '\0';
|
||||
to_draw += len;
|
||||
offset = *to_draw++;
|
||||
if (c == SCC_SETXY) top = initial_top + *to_draw++;
|
||||
}
|
||||
|
||||
HandleBiDiAndArabicShapes(to_draw, last);
|
||||
int w = GetStringBoundingBox(to_draw).width;
|
||||
|
||||
/* right is the right most position to draw on. In this case we want to do
|
||||
* calculations with the width of the string. In comparison right can be
|
||||
* seen as lastof(todraw) and width as lengthof(todraw). They differ by 1.
|
||||
* So most +1/-1 additions are to move from lengthof to 'indices'.
|
||||
*/
|
||||
switch (align) {
|
||||
case SA_LEFT:
|
||||
/* right + 1 = left + w */
|
||||
left = initial_left + offset;
|
||||
right = left + w - 1;
|
||||
break;
|
||||
|
||||
case SA_CENTER:
|
||||
/* The second + 1 is to round to the closest number */
|
||||
left = (initial_right + 1 + initial_left - w + 1) / 2;
|
||||
/* right + 1 = left + w */
|
||||
right = left + w - 1;
|
||||
break;
|
||||
|
||||
case SA_RIGHT:
|
||||
left = initial_right + 1 - w - offset;
|
||||
break;
|
||||
|
||||
default:
|
||||
NOT_REACHED();
|
||||
}
|
||||
|
||||
min_left = min(left, min_left);
|
||||
max_right = max(right, max_right);
|
||||
|
||||
ReallyDoDrawString(to_draw, left, top, colour, !truncate);
|
||||
if (underline) {
|
||||
GfxFillRect(left, top + 10, right, top + 10, _string_colourremap[1]);
|
||||
}
|
||||
}
|
||||
|
||||
return align == SA_RIGHT ? min_left : max_right;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -864,7 +864,7 @@ struct StationViewWindow : public Window {
|
|||
assert(b < endof(string));
|
||||
|
||||
SetDParamStr(0, string);
|
||||
DrawStringMultiLine(this->widget[SVW_ACCEPTLIST].left + 2, this->widget[SVW_ACCEPTLIST].right - 2, this->widget[SVW_ACCEPTLIST].top + 1,this->widget[SVW_ACCEPTLIST].bottom - 1, STR_JUST_RAW_STRING);
|
||||
DrawStringMultiLine(this->widget[SVW_ACCEPTLIST].left + 2, this->widget[SVW_ACCEPTLIST].right - 2, this->widget[SVW_ACCEPTLIST].top + 1, this->widget[SVW_ACCEPTLIST].bottom - 1, STR_JUST_RAW_STRING);
|
||||
} else { // extended window with list of cargo ratings
|
||||
y = this->widget[SVW_RATINGLIST].top + 1;
|
||||
|
||||
|
|
Loading…
Reference in New Issue