Skip to content

Commit c5ac22e

Browse files
committed
Alignment and justification settings for uiwraptext
1 parent fd60d84 commit c5ac22e

4 files changed

Lines changed: 57 additions & 46 deletions

File tree

source/engine/engine.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,10 @@ extern void done_pangocairo();
5959
extern int getcurfontid();
6060
extern void gettextres(int &w, int &h);
6161
extern void draw_text(textinfo info, float left, float top, int a = 255, bool black = false);
62-
extern void prepare_text(const char *str, textinfo &info, int maxwidth, bvec initial_color = bvec(255, 255, 255), int cursor = -1, float outline = 0, bvec outline_color = bvec(0, 0, 0), const char *language = NULL);
62+
extern void prepare_text(const char *str, textinfo &info, int maxwidth, bvec initial_color = bvec(255, 255, 255), int cursor = -1, float outline = 0, bvec outline_color = bvec(0, 0, 0), int align = -1, int justify = 0, const char *language = NULL);
6363
extern void prepare_text_particle(const char *str, textinfo &info, bvec initial_color = bvec(255, 255, 255), float outline = 0, bvec outline_color = bvec(0, 0, 0), const char *language = NULL);
64-
extern int text_visible(const char *str, float hitx, float hity, int maxwidth, const char *language = NULL);
65-
extern void text_pos(const char *str, int cursor, int &cx, int &cy, int maxwidth, const char *language = NULL);
64+
extern int text_visible(const char *str, float hitx, float hity, int maxwidth, int align = -1, int justify = 0, const char *language = NULL);
65+
extern void text_pos(const char *str, int cursor, int &cx, int &cy, int maxwidth, int align = -1, int justify = 0, const char *language = NULL);
6666
extern void reloadfonts();
6767

6868
// texture

source/engine/rendertext.cpp

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,7 @@ static inline void add_text_to_layout(const char *markup, int len, PangoLayout *
391391
}
392392
#undef MARKUP_CASE
393393

394-
static inline PangoLayout *measure_text_internal(const char *str, int len, int maxwidth, bvec initial_color, int &width, int &height, int *map_markup_to_text, int *map_text_to_markup, const char *language)
394+
static inline PangoLayout *measure_text_internal(const char *str, int len, int maxwidth, int align, int justify, bvec initial_color, int &width, int &height, int &offset, int *map_markup_to_text, int *map_text_to_markup, const char *language)
395395
{
396396
// create cairo context
397397
cairo_t *cr = cairo_create(dummy_surface);
@@ -401,7 +401,7 @@ static inline PangoLayout *measure_text_internal(const char *str, int len, int m
401401
PangoLayout *layout = pango_cairo_create_layout(cr);
402402
if(!layout)
403403
{
404-
width = height = 0;
404+
width = height = offset = 0;
405405
cairo_destroy(cr);
406406
return NULL;
407407
}
@@ -410,34 +410,41 @@ static inline PangoLayout *measure_text_internal(const char *str, int len, int m
410410
pango_font_description_set_absolute_size(curfont->desc, fontsize * PANGO_SCALE); // pango 1.8
411411
pango_layout_set_font_description(layout, curfont->desc);
412412

413-
// set maximum length for line wrapping
413+
// line wrapping: set maximum width, alignment and justification
414414
if(maxwidth > 0)
415415
{
416416
pango_layout_set_width(layout, maxwidth * PANGO_SCALE);
417417
pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
418+
pango_layout_set_alignment(layout, align > 0 ? PANGO_ALIGN_RIGHT : align < 0 ? PANGO_ALIGN_LEFT : PANGO_ALIGN_CENTER);
419+
pango_layout_set_justify(layout, justify ? TRUE : FALSE);
418420
}
419421

420422
add_text_to_layout(str, len, layout, initial_color, map_markup_to_text, map_text_to_markup, language);
421423

422424
// get pixel size
423-
pango_layout_get_pixel_size(layout, &width, &height);
425+
PangoRectangle r;
426+
pango_layout_get_extents(layout, NULL, &r);
427+
width = r.width / PANGO_SCALE;
428+
height = r.height / PANGO_SCALE;
429+
offset = -r.x / PANGO_SCALE;
424430

425431
cairo_destroy(cr);
426432
return layout;
427433
}
428-
void measure_text(const char *str, int maxwidth, int &width, int &height, const char *language)
434+
void measure_text(const char *str, int maxwidth, int &width, int &height, int align, int justify, const char *language)
429435
{
430-
PangoLayout *layout = measure_text_internal(str, strlen(str), maxwidth, bvec(0, 0, 0), width, height, NULL, NULL, language);
436+
int _offset;
437+
PangoLayout *layout = measure_text_internal(str, strlen(str), maxwidth, align, justify, bvec(0, 0, 0), width, height, _offset, NULL, NULL, language);
431438
if(layout) g_object_unref(layout);
432439
}
433440

434-
void prepare_text(const char *str, textinfo &info, int maxwidth, bvec initial_color, int cursor, float outline, bvec outline_color, const char *language)
441+
void prepare_text(const char *str, textinfo &info, int maxwidth, bvec initial_color, int cursor, float outline, bvec outline_color, int align, int justify, const char *language)
435442
{
436443
// get dimensions and pango layout
437-
int width, height;
444+
int width, height, offset;
438445
const int len = strlen(str);
439446
int map_markup_to_text[len+1];
440-
PangoLayout *layout = measure_text_internal(str, len, maxwidth, initial_color, width, height, cursor >= 0 ? map_markup_to_text : NULL, NULL, language);
447+
PangoLayout *layout = measure_text_internal(str, len, maxwidth, align, justify, initial_color, width, height, offset, cursor >= 0 ? map_markup_to_text : NULL, NULL, language);
441448
if(!layout) { info = {0, 0, 0}; return; }
442449
if(!width || !height) { g_object_unref(layout); info = {0, 0, 0}; return; }
443450

@@ -446,6 +453,7 @@ void prepare_text(const char *str, textinfo &info, int maxwidth, bvec initial_co
446453
cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
447454
cairo_t *cr = cairo_create(surface);
448455
cairo_set_font_options(cr, options);
456+
cairo_move_to(cr, offset, 0);
449457

450458
// draw text onto the surface
451459
if(outline)
@@ -507,7 +515,7 @@ void prepare_text_particle(const char *str, textinfo &info, bvec initial_color,
507515
info = p.ti;
508516
return;
509517
}
510-
prepare_text(str, p.ti, 0, initial_color, -1, outline, outline_color, language);
518+
prepare_text(str, p.ti, 0, initial_color, -1, outline, outline_color, -1, 0, language);
511519
if(!p.ti.tex) { info = {0, 0, 0}; return; }
512520
if(particle_queue.length() >= 256)
513521
{
@@ -555,10 +563,10 @@ void draw_text(textinfo info, float left, float top, int a, bool black)
555563
gle::end();
556564
// NOTE: `info.tex` is not deleted here!
557565
}
558-
void draw_text(const char *str, float left, float top, int r, int g, int b, int a, const char *language)
566+
void draw_text(const char *str, float left, float top, int r, int g, int b, int a, int maxwidth, int align, int justify, const char *language)
559567
{
560568
textinfo info;
561-
prepare_text(str, info, 0, bvec(r, g, b), -1, 0, bvec(0, 0, 0), language);
569+
prepare_text(str, info, maxwidth, bvec(r, g, b), -1, 0, bvec(0, 0, 0), align, justify, language);
562570
if(!info.tex) return;
563571
draw_text(info, left, top, a);
564572
glDeleteTextures(1, &info.tex);
@@ -587,13 +595,13 @@ void gettextres(int &w, int &h)
587595
}
588596

589597
// used by the text editor
590-
int text_visible(const char *str, float hitx, float hity, int maxwidth, const char *language)
598+
int text_visible(const char *str, float hitx, float hity, int maxwidth, int align, int justify, const char *language)
591599
{
592-
int width, height;
600+
int width, height, _offset;
593601
const int len = strlen(str);
594602
if(!len) return 0;
595603
int map_text_to_markup[len+1];
596-
PangoLayout *layout = measure_text_internal(str, len, maxwidth, bvec(0, 0, 0), width, height, NULL, map_text_to_markup, language);
604+
PangoLayout *layout = measure_text_internal(str, len, maxwidth, align, justify, bvec(0, 0, 0), width, height, _offset, NULL, map_text_to_markup, language);
597605
if(!layout) return len;
598606
if(!width || !height) { g_object_unref(layout); return len; }
599607

@@ -605,13 +613,13 @@ int text_visible(const char *str, float hitx, float hity, int maxwidth, const ch
605613
}
606614

607615
// used by the text editor
608-
void text_pos(const char *str, int cursor, int &cx, int &cy, int maxwidth, const char *language)
616+
void text_pos(const char *str, int cursor, int &cx, int &cy, int maxwidth, int align, int justify, const char *language)
609617
{
610-
int width, height;
618+
int width, height, _offset;
611619
const int len = strlen(str);
612620
if(!len) { cx = cy = 0; return; }
613621
int map_markup_to_text[len+1];
614-
PangoLayout *layout = measure_text_internal(str, len, maxwidth, bvec(0, 0, 0), width, height, map_markup_to_text, NULL, language);
622+
PangoLayout *layout = measure_text_internal(str, len, maxwidth, align, justify, bvec(0, 0, 0), width, height, _offset, map_markup_to_text, NULL, language);
615623
if(!layout) { cx = cy = 0; return; }
616624
if(!width || !height) { g_object_unref(layout); cx = cy = 0; return; }
617625

source/engine/ui.cpp

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1979,20 +1979,21 @@ namespace UI
19791979
textinfo info;
19801980
int fontid, lastchange;
19811981
int fancy; // 0 = none, 1 = shadow, 2 = outline, 3 = shadow+outline
1982+
int align, justify;
19821983
char *language;
19831984
bool changed;
19841985
uint crc; // string hash used for change detection
19851986

19861987
Text() : info({0, 0, 0}), lastchange(0), fancy(0), language(NULL), crc(0) {}
19871988

1988-
void setup(float scale_ = 1, const Color &color_ = Color(255, 255, 255), float wrap_ = -1, int fancy_ = 0, const char *language_ = "")
1989+
void setup(float scale_ = 1, const Color &color_ = Color(255, 255, 255), float wrap_ = -1, int fancy_ = 0, int align_ = -1, int justify_ = 0, const char *language_ = "")
19891990
{
19901991
Object::setup();
19911992
changed = false;
19921993
float newscale = scale_ * uiscale;
19931994

19941995
int curfontid = getcurfontid();
1995-
if(newscale != scale || wrap_ != wrap || fontid != curfontid || fancy_ != fancy || (!language || strcmp(language_, language)) || (color_.r != color.r || color_.g != color.g || color_.b != color.b))
1996+
if(newscale != scale || wrap_ != wrap || fontid != curfontid || fancy_ != fancy || align_ != align || justify_ != justify || (!language || strcmp(language_, language)) || (color_.r != color.r || color_.g != color.g || color_.b != color.b))
19961997
{
19971998
changed = true;
19981999
lastchange = totalmillis;
@@ -2002,6 +2003,8 @@ namespace UI
20022003
color = color_;
20032004
wrap = wrap_;
20042005
fancy = fancy_;
2006+
align = align_;
2007+
justify = justify_;
20052008
SETSTR(language, language_);
20062009
fontid = curfontid;
20072010
}
@@ -2069,7 +2072,7 @@ namespace UI
20692072

20702073
if(!info.tex)
20712074
{
2072-
prepare_text(text, info, int(wrap/k), bvec(color.r, color.g, color.b), -1, fancy >= 2 ? 1.0 : 0, bvec(0, 0, 0), language);
2075+
prepare_text(text, info, int(wrap/k), bvec(color.r, color.g, color.b), -1, fancy >= 2 ? 1.0 : 0, bvec(0, 0, 0), align, justify, language);
20732076
}
20742077
w = max(w, info.w*k);
20752078
h = max(h, info.h*k);
@@ -2083,9 +2086,9 @@ namespace UI
20832086
TextString() : str(NULL) {}
20842087
~TextString() { delete[] str; }
20852088

2086-
void setup(const char *str_, float scale_ = 1, const Color &color_ = Color(255, 255, 255), float wrap_ = -1, int fancy_ = 0, const char *language_ = "")
2089+
void setup(const char *str_, float scale_ = 1, const Color &color_ = Color(255, 255, 255), float wrap_ = -1, int fancy_ = 0, int align_ = -1, int justify_ = 0, const char *language_ = "")
20872090
{
2088-
Text::setup(scale_, color_, wrap_, fancy_, language_);
2091+
Text::setup(scale_, color_, wrap_, fancy_, align_, justify_, language_);
20892092

20902093
SETSTR(str, str_);
20912094
}
@@ -2103,9 +2106,9 @@ namespace UI
21032106

21042107
TextInt() : val(0) { str[0] = '0'; str[1] = '\0'; }
21052108

2106-
void setup(int val_, float scale_ = 1, const Color &color_ = Color(255, 255, 255), float wrap_ = -1, int fancy_ = 0, const char *language_ = "")
2109+
void setup(int val_, float scale_ = 1, const Color &color_ = Color(255, 255, 255), float wrap_ = -1, int fancy_ = 0, int align_ = -1, int justify_ = 0, const char *language_ = "")
21072110
{
2108-
Text::setup(scale_, color_, wrap_, fancy_, language_);
2111+
Text::setup(scale_, color_, wrap_, fancy_, align_, justify_, language_);
21092112

21102113
if(val != val_) { val = val_; intformat(str, val, sizeof(str)); }
21112114
}
@@ -2123,9 +2126,9 @@ namespace UI
21232126

21242127
TextFloat() : val(0) { memcpy(str, "0.0", 4); }
21252128

2126-
void setup(float val_, float scale_ = 1, const Color &color_ = Color(255, 255, 255), float wrap_ = -1, int fancy_ = 0, const char *language_ = "")
2129+
void setup(float val_, float scale_ = 1, const Color &color_ = Color(255, 255, 255), float wrap_ = -1, int fancy_ = 0, int align_ = -1, int justify_ = 0, const char *language_ = "")
21272130
{
2128-
Text::setup(scale_, color_, wrap_, fancy_, language_);
2131+
Text::setup(scale_, color_, wrap_, fancy_, align_, justify_, language_);
21292132

21302133
if(val != val_) { val = val_; floatformat(str, val, sizeof(str)); }
21312134
}
@@ -3541,25 +3544,25 @@ namespace UI
35413544
ICOMMAND(uimodcircle, "ife", (int *c, float *size, uint *children),
35423545
BUILD(Circle, o, o->setup(Color(*c), *size, Circle::MODULATE), children));
35433546

3544-
static inline void buildtext(tagval &t, float scale, float scalemod, const Color &color, float wrap, uint *children, int fancy, const char *language)
3547+
static inline void buildtext(tagval &t, float scale, float scalemod, const Color &color, float wrap, uint *children, int fancy, int align, int justify, const char *language)
35453548
{
35463549
if(scale <= 0) scale = 1;
35473550
scale *= scalemod;
35483551
if(!language) language = "";
35493552
switch(t.type)
35503553
{
35513554
case VAL_INT:
3552-
BUILD(TextInt, o, o->setup(t.i, scale, color, wrap, fancy, language), children);
3555+
BUILD(TextInt, o, o->setup(t.i, scale, color, wrap, fancy, align, justify, language), children);
35533556
break;
35543557
case VAL_FLOAT:
3555-
BUILD(TextFloat, o, o->setup(t.f, scale, color, wrap, fancy, language), children);
3558+
BUILD(TextFloat, o, o->setup(t.f, scale, color, wrap, fancy, align, justify, language), children);
35563559
break;
35573560
case VAL_CSTR:
35583561
case VAL_MACRO:
35593562
case VAL_STR:
35603563
if(t.s[0])
35613564
{
3562-
BUILD(TextString, o, o->setup(t.s, scale, color, wrap, fancy, language), children);
3565+
BUILD(TextString, o, o->setup(t.s, scale, color, wrap, fancy, align, justify, language), children);
35633566
break;
35643567
}
35653568
// fall-through
@@ -3570,34 +3573,34 @@ namespace UI
35703573
}
35713574

35723575
ICOMMAND(uicolortext, "tifise", (tagval *text, int *c, float *scale, int *fancy, const char *language, uint *children),
3573-
buildtext(*text, *scale, uitextscale, Color(*c), -1, children, *fancy, language));
3576+
buildtext(*text, *scale, uitextscale, Color(*c), -1, children, *fancy, -1, 0, language));
35743577

35753578
ICOMMAND(uitext, "tfise", (tagval *text, float *scale, int *fancy, const char *language, uint *children),
3576-
buildtext(*text, *scale, uitextscale, Color(255, 255, 255), -1, children, *fancy, language));
3579+
buildtext(*text, *scale, uitextscale, Color(255, 255, 255), -1, children, *fancy, -1, 0, language));
35773580

35783581
ICOMMAND(uitextfill, "ffe", (float *minw, float *minh, uint *children),
35793582
BUILD(Filler, o, o->setup(*minw * uitextscale*0.5f, *minh * uitextscale), children));
35803583

3581-
ICOMMAND(uiwrapcolortext, "tfifse", (tagval *text, float *wrap, int *c, float *scale, int *fancy, const char *language, uint *children),
3582-
buildtext(*text, *scale, uitextscale, Color(*c), *wrap, children, *fancy, language));
3584+
ICOMMAND(uiwrapcolortext, "tfifiiise", (tagval *text, float *wrap, int *c, float *scale, int *fancy, int *align, int *justify, const char *language, uint *children),
3585+
buildtext(*text, *scale, uitextscale, Color(*c), *wrap, children, *fancy, *align, *justify, language));
35833586

3584-
ICOMMAND(uiwraptext, "tffse", (tagval *text, float *wrap, float *scale, int *fancy, const char *language, uint *children),
3585-
buildtext(*text, *scale, uitextscale, Color(255, 255, 255), *wrap, children, *fancy, language));
3587+
ICOMMAND(uiwraptext, "tffiiise", (tagval *text, float *wrap, float *scale, int *fancy, int *align, int *justify, const char *language, uint *children),
3588+
buildtext(*text, *scale, uitextscale, Color(255, 255, 255), *wrap, children, *fancy, *align, *justify, language));
35863589

35873590
ICOMMAND(uicolorcontext, "tife", (tagval *text, int *c, float *scale, uint *children),
3588-
buildtext(*text, *scale, FONTH*uicontextscale, Color(*c), -1, children, 0, ""));
3591+
buildtext(*text, *scale, FONTH*uicontextscale, Color(*c), -1, children, 0, -1, 0, ""));
35893592

35903593
ICOMMAND(uicontext, "tfe", (tagval *text, float *scale, uint *children),
3591-
buildtext(*text, *scale, FONTH*uicontextscale, Color(255, 255, 255), -1, children, 0, ""));
3594+
buildtext(*text, *scale, FONTH*uicontextscale, Color(255, 255, 255), -1, children, 0, -1, 0, ""));
35923595

35933596
ICOMMAND(uicontextfill, "ffe", (float *minw, float *minh, uint *children),
35943597
BUILD(Filler, o, o->setup(*minw * FONTH*uicontextscale*0.5f, *minh * FONTH*uicontextscale), children));
35953598

35963599
ICOMMAND(uiwrapcolorcontext, "tfife", (tagval *text, float *wrap, int *c, float *scale, uint *children),
3597-
buildtext(*text, *scale, FONTH*uicontextscale, Color(*c), *wrap, children, 0, ""));
3600+
buildtext(*text, *scale, FONTH*uicontextscale, Color(*c), *wrap, children, 0, -1, 0, ""));
35983601

35993602
ICOMMAND(uiwrapcontext, "tffe", (tagval *text, float *wrap, float *scale, uint *children),
3600-
buildtext(*text, *scale, FONTH*uicontextscale, Color(255, 255, 255), *wrap, children, 0, ""));
3603+
buildtext(*text, *scale, FONTH*uicontextscale, Color(255, 255, 255), *wrap, children, 0, -1, 0, ""));
36013604

36023605
ICOMMAND(uitexteditor, "siifsie", (char *name, int *length, int *height, float *scale, char *initval, int *mode, uint *children),
36033606
BUILD(TextEditor, o, o->setup(name, *length, *height, (*scale <= 0 ? 1 : *scale) * uitextscale, initval, *mode <= 0 ? EDITORFOREVER : *mode), children));

source/shared/iengine.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -256,9 +256,9 @@ extern bool setfont(const char *name);
256256
static inline void setfontsize(float size) { fontsize = size; }
257257
extern void pushfont();
258258
extern bool popfont();
259-
extern void draw_text(const char *str, float left, float top, int r = 255, int g = 255, int b = 255, int a = 255, const char *language = NULL);
259+
extern void draw_text(const char *str, float left, float top, int r = 255, int g = 255, int b = 255, int a = 255, int maxwidth = 0, int align = -1, int justify = 0, const char *language = NULL);
260260
extern void draw_textf(const char *fstr, float left, float top, ...) PRINTFARGS(1, 4);
261-
extern void measure_text(const char *str, int maxwidth, int &width, int &height, const char *language = NULL);
261+
extern void measure_text(const char *str, int maxwidth, int &width, int &height, int align = -1, int justify = 0, const char *language = NULL);
262262

263263
// texture
264264

0 commit comments

Comments
 (0)