@@ -414,25 +414,73 @@ static void LEDMeterMode_draw(Meter* this, int x, int y, int w) {
414414 RichString_begin (out );
415415 Meter_displayBuffer (this , & out );
416416
417- int len = RichString_sizeVal (out );
418- for (int i = 0 ; i < len ; i ++ ) {
419- int c = RichString_getCharVal (out , i );
420- if (c >= '0' && c <= '9' ) {
421- if (xx > x + w - 4 )
422- break ;
417+ #ifdef HAVE_LIBNCURSESW
418+ // If the character takes zero columns, include the character in the
419+ // substring if the working encoding is UTF-8, and ignore it otherwise.
420+ // In Unicode, combining characters are always placed after the base
421+ // character, but some legacy 8-bit encodings instead place combining
422+ // characters before the base character.
423+ const bool isUnicode = CRT_utf8 ;
424+ #else
425+ const bool isUnicode = false;
426+ #endif
423427
424- LEDMeterMode_drawDigit (xx , y , c - '0' );
425- xx += 4 ;
426- } else {
427- if (xx > x + w - 1 )
428+ size_t len = RichString_sizeVal (out );
429+ size_t charPos = 0 ;
430+ while (charPos < len ) {
431+ #ifdef HAVE_LIBNCURSESW
432+ wchar_t c = 0 ;
433+ #else
434+ int c = 0 ;
435+ #endif
436+
437+ int subWidth = 0 ;
438+ size_t breakPos = charPos ;
439+ size_t startPos = charPos ;
440+ while (charPos < len && (xx + subWidth < x + w || isUnicode )) {
441+ assert (xx + subWidth <= x + w );
442+
443+ c = RichString_getCharVal (out , charPos );
444+ assert (c != 0 );
445+ if (c >= '0' && c <= '9' )
428446 break ;
447+
429448#ifdef HAVE_LIBNCURSESW
430- const cchar_t wc = { . chars = { c , '\0' }, . attr = 0 }; /* use LED_COLOR from attrset() */
431- mvadd_wch ( yText , xx , & wc );
449+ int cw = wcwidth ( c );
450+ assert ( cw >= 0 );
432451#else
433- mvaddch (yText , xx , c );
452+ assert (isprint (c ));
453+ const int cw = 1 ;
434454#endif
435- xx += 1 ;
455+
456+ if ((unsigned int )cw > (unsigned int )(x + w - (xx + subWidth ))) {
457+ charPos = len ;
458+ break ;
459+ }
460+
461+ charPos ++ ;
462+
463+ if (cw <= 0 && !isUnicode )
464+ continue ;
465+
466+ subWidth += cw ;
467+ breakPos = charPos ;
468+ }
469+
470+ if (breakPos > startPos ) {
471+ RichString_setAttrn (& out , CRT_colors [LED_COLOR ], startPos , breakPos - startPos );
472+ RichString_printoffnVal (out , yText , xx , startPos , breakPos - startPos );
473+ xx += subWidth ;
474+ }
475+
476+ if (c >= '0' && c <= '9' ) {
477+ const int cw = 4 ;
478+ if (cw > x + w - xx )
479+ break ;
480+
481+ LEDMeterMode_drawDigit (xx , y , c - '0' );
482+ xx += cw ;
483+ charPos ++ ;
436484 }
437485 }
438486 RichString_delete (& out );
0 commit comments