Added support for combined unicode characters
This commit is contained in:
parent
5b789e4110
commit
baa0c60c79
15
.travis.yml
15
.travis.yml
|
@ -154,3 +154,18 @@ jobs:
|
||||||
- autoreconf -v --install --force
|
- autoreconf -v --install --force
|
||||||
- ./configure --prefix=/usr
|
- ./configure --prefix=/usr
|
||||||
- make -j10
|
- make -j10
|
||||||
|
|
||||||
|
#
|
||||||
|
# FreeBSD
|
||||||
|
#
|
||||||
|
- os: freebsd
|
||||||
|
env:
|
||||||
|
- TEST="FreeBSD"
|
||||||
|
before_install:
|
||||||
|
- uname -a
|
||||||
|
- g++ --version
|
||||||
|
script:
|
||||||
|
- autoreconf -v --install --force
|
||||||
|
- ./configure --prefix=/usr
|
||||||
|
- make -j10
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
|
2021-02-09 Markus Gans <guru.mail@muenster.de>
|
||||||
|
* Added support for combined unicode characters
|
||||||
|
* Added a unit test for the FTermBuffera class
|
||||||
|
* Added a unit test for the FTterm functions
|
||||||
|
|
||||||
2020-12-31 Markus Gans <guru.mail@muenster.de>
|
2020-12-31 Markus Gans <guru.mail@muenster.de>
|
||||||
* Refactoring to scaled enumerations
|
* Refactoring to scoped enumerations
|
||||||
|
|
||||||
2020-11-18 Markus Gans <guru.mail@muenster.de>
|
2020-11-18 Markus Gans <guru.mail@muenster.de>
|
||||||
* The terminal update rate is now limited to 60 Hz
|
* The terminal update rate is now limited to 60 Hz
|
||||||
|
|
|
@ -330,32 +330,32 @@ types and send them to other objects and widgets.
|
||||||
|
|
||||||
### Available event types ###
|
### Available event types ###
|
||||||
```cpp
|
```cpp
|
||||||
enum events
|
enum class Event
|
||||||
{
|
{
|
||||||
None_Event, // invalid event
|
None, // invalid event
|
||||||
KeyPress_Event, // key pressed
|
KeyPress, // key pressed
|
||||||
KeyUp_Event, // key released
|
KeyUp, // key released
|
||||||
KeyDown_Event, // key pressed
|
KeyDown, // key pressed
|
||||||
MouseDown_Event, // mouse button pressed
|
MouseDown, // mouse button pressed
|
||||||
MouseUp_Event, // mouse button released
|
MouseUp, // mouse button released
|
||||||
MouseDoubleClick_Event, // mouse button double click
|
MouseDoubleClick, // mouse button double click
|
||||||
MouseWheel_Event, // mouse wheel rolled
|
MouseWheel, // mouse wheel rolled
|
||||||
MouseMove_Event, // mouse move
|
MouseMove, // mouse move
|
||||||
FocusIn_Event, // focus in
|
FocusIn, // focus in
|
||||||
FocusOut_Event, // focus out
|
FocusOut, // focus out
|
||||||
ChildFocusIn_Event, // child focus in
|
ChildFocusIn, // child focus in
|
||||||
ChildFocusOut_Event, // child focus out
|
ChildFocusOut, // child focus out
|
||||||
WindowActive_Event, // activate window
|
WindowActive, // activate window
|
||||||
WindowInactive_Event, // deactivate window
|
WindowInactive, // deactivate window
|
||||||
WindowRaised_Event, // raise window
|
WindowRaised, // raise window
|
||||||
WindowLowered_Event, // lower window
|
WindowLowered, // lower window
|
||||||
Accelerator_Event, // keyboard accelerator
|
Accelerator, // keyboard accelerator
|
||||||
Resize_Event, // terminal resize
|
Resize, // terminal resize
|
||||||
Show_Event, // widget is shown
|
Show, // widget is shown
|
||||||
Hide_Event, // widget is hidden
|
Hide, // widget is hidden
|
||||||
Close_Event, // widget close
|
Close, // widget close
|
||||||
Timer_Event, // timer event occur
|
Timer, // timer event occur
|
||||||
User_Event // user defined event
|
User // user defined event
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -1337,15 +1337,15 @@ requires it. You can controll this behavior by the two methods
|
||||||
`setHorizontalScrollBarMode()` and `setVerticalScrollBarMode()`.
|
`setHorizontalScrollBarMode()` and `setVerticalScrollBarMode()`.
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
setHorizontalScrollBarMode (fc::scrollBarMode);
|
setHorizontalScrollBarMode (finalcut::ScrollBarMode);
|
||||||
setVerticalScrollBarMode (fc::scrollBarMode);
|
setVerticalScrollBarMode (finalcut::ScrollBarMode);
|
||||||
```
|
```
|
||||||
|
|
||||||
You pass the scroll bar visibility mode as a value of the enum type
|
You pass the scroll bar visibility mode as a value of the enum type
|
||||||
`fc::scrollBarMode`.
|
`finalcut::ScrollBarMode`.
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
enum scrollBarMode
|
enum class ScrollBarMode
|
||||||
{
|
{
|
||||||
Auto = 0, // Shows a scroll bar when area is larger than viewport
|
Auto = 0, // Shows a scroll bar when area is larger than viewport
|
||||||
Hidden = 1, // Never shows a scroll bar
|
Hidden = 1, // Never shows a scroll bar
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* *
|
* *
|
||||||
* This file is part of the FINAL CUT widget toolkit *
|
* This file is part of the FINAL CUT widget toolkit *
|
||||||
* *
|
* *
|
||||||
* Copyright 2012-2020 Markus Gans *
|
* Copyright 2012-2021 Markus Gans *
|
||||||
* *
|
* *
|
||||||
* FINAL CUT is free software; you can redistribute it and/or modify *
|
* FINAL CUT is free software; you can redistribute it and/or modify *
|
||||||
* it under the terms of the GNU Lesser General Public License as *
|
* it under the terms of the GNU Lesser General Public License as *
|
||||||
|
@ -26,7 +26,6 @@
|
||||||
|
|
||||||
#include <final/final.h>
|
#include <final/final.h>
|
||||||
|
|
||||||
namespace fc = finalcut::fc;
|
|
||||||
using finalcut::FColorPair;
|
using finalcut::FColorPair;
|
||||||
using finalcut::FColor;
|
using finalcut::FColor;
|
||||||
using finalcut::FRect;
|
using finalcut::FRect;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* *
|
* *
|
||||||
* This file is part of the FINAL CUT widget toolkit *
|
* This file is part of the FINAL CUT widget toolkit *
|
||||||
* *
|
* *
|
||||||
* Copyright 2017-2020 Markus Gans *
|
* Copyright 2017-2021 Markus Gans *
|
||||||
* *
|
* *
|
||||||
* FINAL CUT is free software; you can redistribute it and/or modify *
|
* FINAL CUT is free software; you can redistribute it and/or modify *
|
||||||
* it under the terms of the GNU Lesser General Public License as *
|
* it under the terms of the GNU Lesser General Public License as *
|
||||||
|
@ -28,7 +28,6 @@
|
||||||
|
|
||||||
#include <final/final.h>
|
#include <final/final.h>
|
||||||
|
|
||||||
namespace fc = finalcut::fc;
|
|
||||||
using finalcut::FPoint;
|
using finalcut::FPoint;
|
||||||
using finalcut::FRect;
|
using finalcut::FRect;
|
||||||
using finalcut::FSize;
|
using finalcut::FSize;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* *
|
* *
|
||||||
* This file is part of the FINAL CUT widget toolkit *
|
* This file is part of the FINAL CUT widget toolkit *
|
||||||
* *
|
* *
|
||||||
* Copyright 2017-2020 Markus Gans *
|
* Copyright 2017-2021 Markus Gans *
|
||||||
* *
|
* *
|
||||||
* FINAL CUT is free software; you can redistribute it and/or modify *
|
* FINAL CUT is free software; you can redistribute it and/or modify *
|
||||||
* it under the terms of the GNU Lesser General Public License as *
|
* it under the terms of the GNU Lesser General Public License as *
|
||||||
|
@ -28,7 +28,6 @@
|
||||||
|
|
||||||
#include <final/final.h>
|
#include <final/final.h>
|
||||||
|
|
||||||
namespace fc = finalcut::fc;
|
|
||||||
using finalcut::FPoint;
|
using finalcut::FPoint;
|
||||||
using finalcut::FSize;
|
using finalcut::FSize;
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* *
|
* *
|
||||||
* This file is part of the FINAL CUT widget toolkit *
|
* This file is part of the FINAL CUT widget toolkit *
|
||||||
* *
|
* *
|
||||||
* Copyright 2015-2020 Markus Gans *
|
* Copyright 2015-2021 Markus Gans *
|
||||||
* *
|
* *
|
||||||
* FINAL CUT is free software; you can redistribute it and/or modify *
|
* FINAL CUT is free software; you can redistribute it and/or modify *
|
||||||
* it under the terms of the GNU Lesser General Public License as *
|
* it under the terms of the GNU Lesser General Public License as *
|
||||||
|
@ -22,7 +22,6 @@
|
||||||
|
|
||||||
#include <final/final.h>
|
#include <final/final.h>
|
||||||
|
|
||||||
namespace fc = finalcut::fc;
|
|
||||||
using finalcut::FColor;
|
using finalcut::FColor;
|
||||||
using finalcut::FPoint;
|
using finalcut::FPoint;
|
||||||
using finalcut::FSize;
|
using finalcut::FSize;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* *
|
* *
|
||||||
* This file is part of the FINAL CUT widget toolkit *
|
* This file is part of the FINAL CUT widget toolkit *
|
||||||
* *
|
* *
|
||||||
* Copyright 2017-2020 Markus Gans *
|
* Copyright 2017-2021 Markus Gans *
|
||||||
* *
|
* *
|
||||||
* FINAL CUT is free software; you can redistribute it and/or modify *
|
* FINAL CUT is free software; you can redistribute it and/or modify *
|
||||||
* it under the terms of the GNU Lesser General Public License as *
|
* it under the terms of the GNU Lesser General Public License as *
|
||||||
|
@ -22,7 +22,6 @@
|
||||||
|
|
||||||
#include <final/final.h>
|
#include <final/final.h>
|
||||||
|
|
||||||
namespace fc = finalcut::fc;
|
|
||||||
using finalcut::FColorPair;
|
using finalcut::FColorPair;
|
||||||
using finalcut::FColor;
|
using finalcut::FColor;
|
||||||
using finalcut::FRect;
|
using finalcut::FRect;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* *
|
* *
|
||||||
* This file is part of the FINAL CUT widget toolkit *
|
* This file is part of the FINAL CUT widget toolkit *
|
||||||
* *
|
* *
|
||||||
* Copyright 2020 Markus Gans *
|
* Copyright 2020-2021 Markus Gans *
|
||||||
* *
|
* *
|
||||||
* FINAL CUT is free software; you can redistribute it and/or modify *
|
* FINAL CUT is free software; you can redistribute it and/or modify *
|
||||||
* it under the terms of the GNU Lesser General Public License as *
|
* it under the terms of the GNU Lesser General Public License as *
|
||||||
|
@ -28,7 +28,6 @@
|
||||||
|
|
||||||
#include <final/final.h>
|
#include <final/final.h>
|
||||||
|
|
||||||
namespace fc = finalcut::fc;
|
|
||||||
using std::chrono::duration_cast;
|
using std::chrono::duration_cast;
|
||||||
using std::chrono::milliseconds;
|
using std::chrono::milliseconds;
|
||||||
using std::chrono::system_clock;
|
using std::chrono::system_clock;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* *
|
* *
|
||||||
* This file is part of the FINAL CUT widget toolkit *
|
* This file is part of the FINAL CUT widget toolkit *
|
||||||
* *
|
* *
|
||||||
* Copyright 2017-2020 Markus Gans *
|
* Copyright 2017-2021 Markus Gans *
|
||||||
* *
|
* *
|
||||||
* FINAL CUT is free software; you can redistribute it and/or modify *
|
* FINAL CUT is free software; you can redistribute it and/or modify *
|
||||||
* it under the terms of the GNU Lesser General Public License as *
|
* it under the terms of the GNU Lesser General Public License as *
|
||||||
|
@ -22,7 +22,6 @@
|
||||||
|
|
||||||
#include <final/final.h>
|
#include <final/final.h>
|
||||||
|
|
||||||
namespace fc = finalcut::fc;
|
|
||||||
using finalcut::FPoint;
|
using finalcut::FPoint;
|
||||||
using finalcut::FSize;
|
using finalcut::FSize;
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* *
|
* *
|
||||||
* This file is part of the FINAL CUT widget toolkit *
|
* This file is part of the FINAL CUT widget toolkit *
|
||||||
* *
|
* *
|
||||||
* Copyright 2015-2020 Markus Gans *
|
* Copyright 2015-2021 Markus Gans *
|
||||||
* *
|
* *
|
||||||
* FINAL CUT is free software; you can redistribute it and/or modify *
|
* FINAL CUT is free software; you can redistribute it and/or modify *
|
||||||
* it under the terms of the GNU Lesser General Public License as *
|
* it under the terms of the GNU Lesser General Public License as *
|
||||||
|
@ -24,7 +24,6 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <final/final.h>
|
#include <final/final.h>
|
||||||
|
|
||||||
namespace fc = finalcut::fc;
|
|
||||||
using finalcut::FPoint;
|
using finalcut::FPoint;
|
||||||
using finalcut::FSize;
|
using finalcut::FSize;
|
||||||
using finalcut::FColorPair;
|
using finalcut::FColorPair;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* *
|
* *
|
||||||
* This file is part of the FINAL CUT widget toolkit *
|
* This file is part of the FINAL CUT widget toolkit *
|
||||||
* *
|
* *
|
||||||
* Copyright 2017-2020 Markus Gans *
|
* Copyright 2017-2021 Markus Gans *
|
||||||
* *
|
* *
|
||||||
* FINAL CUT is free software; you can redistribute it and/or modify *
|
* FINAL CUT is free software; you can redistribute it and/or modify *
|
||||||
* it under the terms of the GNU Lesser General Public License as *
|
* it under the terms of the GNU Lesser General Public License as *
|
||||||
|
@ -27,7 +27,6 @@
|
||||||
|
|
||||||
#include <final/final.h>
|
#include <final/final.h>
|
||||||
|
|
||||||
namespace fc = finalcut::fc;
|
|
||||||
using finalcut::Termcap;
|
using finalcut::Termcap;
|
||||||
|
|
||||||
// Function prototype
|
// Function prototype
|
||||||
|
@ -239,7 +238,7 @@ void debug (const finalcut::FApplication& TermApp)
|
||||||
std::cout << "`------------------- debug -------------------\r\n";
|
std::cout << "`------------------- debug -------------------\r\n";
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
void debug (finalcut::FApplication&)
|
void debug (const finalcut::FApplication&)
|
||||||
{
|
{
|
||||||
// FINAL CUT was compiled without debug option
|
// FINAL CUT was compiled without debug option
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* *
|
* *
|
||||||
* This file is part of the FINAL CUT widget toolkit *
|
* This file is part of the FINAL CUT widget toolkit *
|
||||||
* *
|
* *
|
||||||
* Copyright 2014-2020 Markus Gans *
|
* Copyright 2014-2021 Markus Gans *
|
||||||
* *
|
* *
|
||||||
* FINAL CUT is free software; you can redistribute it and/or modify *
|
* FINAL CUT is free software; you can redistribute it and/or modify *
|
||||||
* it under the terms of the GNU Lesser General Public License as *
|
* it under the terms of the GNU Lesser General Public License as *
|
||||||
|
@ -22,8 +22,6 @@
|
||||||
|
|
||||||
#include <final/final.h>
|
#include <final/final.h>
|
||||||
|
|
||||||
namespace fc = finalcut::fc;
|
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
// class Timer
|
// class Timer
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* *
|
* *
|
||||||
* This file is part of the FINAL CUT widget toolkit *
|
* This file is part of the FINAL CUT widget toolkit *
|
||||||
* *
|
* *
|
||||||
* Copyright 2016-2020 Markus Gans *
|
* Copyright 2016-2021 Markus Gans *
|
||||||
* *
|
* *
|
||||||
* FINAL CUT is free software; you can redistribute it and/or modify *
|
* FINAL CUT is free software; you can redistribute it and/or modify *
|
||||||
* it under the terms of the GNU Lesser General Public License as *
|
* it under the terms of the GNU Lesser General Public License as *
|
||||||
|
@ -22,7 +22,6 @@
|
||||||
|
|
||||||
#include <final/final.h>
|
#include <final/final.h>
|
||||||
|
|
||||||
namespace fc = finalcut::fc;
|
|
||||||
using finalcut::FColorPair;
|
using finalcut::FColorPair;
|
||||||
using finalcut::FColor;
|
using finalcut::FColor;
|
||||||
using finalcut::FPoint;
|
using finalcut::FPoint;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* *
|
* *
|
||||||
* This file is part of the FINAL CUT widget toolkit *
|
* This file is part of the FINAL CUT widget toolkit *
|
||||||
* *
|
* *
|
||||||
* Copyright 2017-2020 Markus Gans *
|
* Copyright 2017-2021 Markus Gans *
|
||||||
* *
|
* *
|
||||||
* FINAL CUT is free software; you can redistribute it and/or modify *
|
* FINAL CUT is free software; you can redistribute it and/or modify *
|
||||||
* it under the terms of the GNU Lesser General Public License as *
|
* it under the terms of the GNU Lesser General Public License as *
|
||||||
|
@ -27,7 +27,6 @@
|
||||||
|
|
||||||
#include <final/final.h>
|
#include <final/final.h>
|
||||||
|
|
||||||
namespace fc = finalcut::fc;
|
|
||||||
using finalcut::FPoint;
|
using finalcut::FPoint;
|
||||||
using finalcut::FSize;
|
using finalcut::FSize;
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* *
|
* *
|
||||||
* This file is part of the FINAL CUT widget toolkit *
|
* This file is part of the FINAL CUT widget toolkit *
|
||||||
* *
|
* *
|
||||||
* Copyright 2016-2020 Markus Gans *
|
* Copyright 2016-2021 Markus Gans *
|
||||||
* *
|
* *
|
||||||
* FINAL CUT is free software; you can redistribute it and/or modify *
|
* FINAL CUT is free software; you can redistribute it and/or modify *
|
||||||
* it under the terms of the GNU Lesser General Public License as *
|
* it under the terms of the GNU Lesser General Public License as *
|
||||||
|
@ -25,7 +25,6 @@
|
||||||
|
|
||||||
#include <final/final.h>
|
#include <final/final.h>
|
||||||
|
|
||||||
namespace fc = finalcut::fc;
|
|
||||||
using finalcut::FPoint;
|
using finalcut::FPoint;
|
||||||
using finalcut::FSize;
|
using finalcut::FSize;
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* *
|
* *
|
||||||
* This file is part of the FINAL CUT widget toolkit *
|
* This file is part of the FINAL CUT widget toolkit *
|
||||||
* *
|
* *
|
||||||
* Copyright 2014-2020 Markus Gans *
|
* Copyright 2014-2021 Markus Gans *
|
||||||
* *
|
* *
|
||||||
* FINAL CUT is free software; you can redistribute it and/or modify *
|
* FINAL CUT is free software; you can redistribute it and/or modify *
|
||||||
* it under the terms of the GNU Lesser General Public License as *
|
* it under the terms of the GNU Lesser General Public License as *
|
||||||
|
@ -252,26 +252,16 @@ void FLabel::setHotkeyAccelerator()
|
||||||
std::size_t FLabel::getAlignOffset (const std::size_t length) const
|
std::size_t FLabel::getAlignOffset (const std::size_t length) const
|
||||||
{
|
{
|
||||||
const std::size_t width(getWidth());
|
const std::size_t width(getWidth());
|
||||||
assert ( alignment == Align::Left
|
|
||||||
|| alignment == Align::Center
|
|
||||||
|| alignment == Align::Right );
|
|
||||||
|
|
||||||
switch ( alignment )
|
if ( alignment == Align::Center )
|
||||||
{
|
{
|
||||||
case Align::Left:
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case Align::Center:
|
|
||||||
if ( length < width )
|
if ( length < width )
|
||||||
return (width - length) / 2;
|
return (width - length) / 2;
|
||||||
else
|
}
|
||||||
return 0;
|
else if ( alignment == Align::Right )
|
||||||
|
{
|
||||||
case Align::Right:
|
|
||||||
if ( length < width )
|
if ( length < width )
|
||||||
return width - length;
|
return width - length;
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* *
|
* *
|
||||||
* This file is part of the FINAL CUT widget toolkit *
|
* This file is part of the FINAL CUT widget toolkit *
|
||||||
* *
|
* *
|
||||||
* Copyright 2012-2020 Markus Gans *
|
* Copyright 2012-2021 Markus Gans *
|
||||||
* *
|
* *
|
||||||
* FINAL CUT is free software; you can redistribute it and/or modify *
|
* FINAL CUT is free software; you can redistribute it and/or modify *
|
||||||
* it under the terms of the GNU Lesser General Public License as *
|
* it under the terms of the GNU Lesser General Public License as *
|
||||||
|
@ -938,21 +938,52 @@ void FLineEdit::adjustTextOffset()
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
inline void FLineEdit::cursorLeft()
|
inline void FLineEdit::cursorLeft()
|
||||||
{
|
{
|
||||||
if ( cursor_pos > 0 )
|
auto prev_char_len = getPrevCharLength(text, cursor_pos);
|
||||||
cursor_pos--;
|
|
||||||
|
|
||||||
|
if ( prev_char_len < 0 )
|
||||||
|
{
|
||||||
|
const auto pos = searchLeftCharBegin(text, cursor_pos);
|
||||||
|
|
||||||
|
if ( pos != NOT_FOUND )
|
||||||
|
{
|
||||||
|
cursor_pos = pos;
|
||||||
adjustTextOffset();
|
adjustTextOffset();
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( cursor_pos >= std::size_t(prev_char_len) )
|
||||||
|
{
|
||||||
|
cursor_pos -= std::size_t(prev_char_len);
|
||||||
|
adjustTextOffset();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
inline void FLineEdit::cursorRight()
|
inline void FLineEdit::cursorRight()
|
||||||
{
|
{
|
||||||
const auto& len = text.getLength();
|
const auto len = text.getLength();
|
||||||
|
const auto char_len = getCharLength(text, cursor_pos);
|
||||||
|
|
||||||
if ( cursor_pos < len )
|
if ( char_len < 0 )
|
||||||
cursor_pos++;
|
{
|
||||||
|
const auto pos = searchRightCharBegin(text, cursor_pos);
|
||||||
|
|
||||||
|
if ( pos != NOT_FOUND )
|
||||||
|
{
|
||||||
|
cursor_pos = pos;
|
||||||
adjustTextOffset();
|
adjustTextOffset();
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( cursor_pos + std::size_t(char_len) <= len )
|
||||||
|
{
|
||||||
|
cursor_pos += std::size_t(char_len);
|
||||||
|
adjustTextOffset();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
@ -981,10 +1012,15 @@ inline void FLineEdit::deleteCurrentCharacter()
|
||||||
// Delete key functionality
|
// Delete key functionality
|
||||||
|
|
||||||
const auto& len = text.getLength();
|
const auto& len = text.getLength();
|
||||||
|
const auto char_len = getCharLength(text, cursor_pos);
|
||||||
|
|
||||||
if ( len > 0 && cursor_pos < len )
|
if ( char_len < 0 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ( len >= std::size_t(char_len)
|
||||||
|
&& cursor_pos <= len - std::size_t(char_len) )
|
||||||
{
|
{
|
||||||
text.remove(cursor_pos, 1);
|
text.remove(cursor_pos, std::size_t(char_len));
|
||||||
print_text = ( isPasswordField() ) ? getPasswordText() : text;
|
print_text = ( isPasswordField() ) ? getPasswordText() : text;
|
||||||
processChanged();
|
processChanged();
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* *
|
* *
|
||||||
* This file is part of the FINAL CUT widget toolkit *
|
* This file is part of the FINAL CUT widget toolkit *
|
||||||
* *
|
* *
|
||||||
* Copyright 2017-2020 Markus Gans *
|
* Copyright 2017-2021 Markus Gans *
|
||||||
* *
|
* *
|
||||||
* FINAL CUT is free software; you can redistribute it and/or modify *
|
* FINAL CUT is free software; you can redistribute it and/or modify *
|
||||||
* it under the terms of the GNU Lesser General Public License as *
|
* it under the terms of the GNU Lesser General Public License as *
|
||||||
|
@ -1479,26 +1479,15 @@ std::size_t FListView::getAlignOffset ( const Align align
|
||||||
, const std::size_t column_width
|
, const std::size_t column_width
|
||||||
, const std::size_t width ) const
|
, const std::size_t width ) const
|
||||||
{
|
{
|
||||||
assert ( align == Align::Left
|
if ( align == Align::Center )
|
||||||
|| align == Align::Center
|
|
||||||
|| align == Align::Right );
|
|
||||||
|
|
||||||
switch ( align )
|
|
||||||
{
|
{
|
||||||
case Align::Left:
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case Align::Center:
|
|
||||||
if ( column_width < width )
|
if ( column_width < width )
|
||||||
return (width - column_width) / 2;
|
return (width - column_width) / 2;
|
||||||
else
|
}
|
||||||
return 0;
|
else if ( align == Align::Right )
|
||||||
|
{
|
||||||
case Align::Right:
|
|
||||||
if ( column_width < width )
|
if ( column_width < width )
|
||||||
return width - column_width;
|
return width - column_width;
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1603,15 +1592,9 @@ void FListView::drawHeadlines()
|
||||||
|
|
||||||
while ( iter != header.end() )
|
while ( iter != header.end() )
|
||||||
{
|
{
|
||||||
const auto& text = iter->name;
|
if ( ! iter->name.isEmpty() )
|
||||||
|
|
||||||
if ( text.isNull() || text.isEmpty() )
|
|
||||||
{
|
|
||||||
++iter;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
drawHeadlineLabel(iter); // Draw into FTermBuffer object
|
drawHeadlineLabel(iter); // Draw into FTermBuffer object
|
||||||
|
|
||||||
++iter;
|
++iter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* *
|
* *
|
||||||
* This file is part of the FINAL CUT widget toolkit *
|
* This file is part of the FINAL CUT widget toolkit *
|
||||||
* *
|
* *
|
||||||
* Copyright 2016-2020 Markus Gans *
|
* Copyright 2016-2021 Markus Gans *
|
||||||
* *
|
* *
|
||||||
* FINAL CUT is free software; you can redistribute it and/or modify *
|
* FINAL CUT is free software; you can redistribute it and/or modify *
|
||||||
* it under the terms of the GNU Lesser General Public License as *
|
* it under the terms of the GNU Lesser General Public License as *
|
||||||
|
@ -1386,13 +1386,13 @@ inline void FOptiAttr::change_current_color ( const FChar& term
|
||||||
|
|
||||||
if ( term.fg_color != fg || frev )
|
if ( term.fg_color != fg || frev )
|
||||||
{
|
{
|
||||||
color_str = FTermcap::encodeParameter(AF, ansi_fg, 0, 0, 0, 0, 0, 0, 0, 0);
|
color_str = FTermcap::encodeParameter(AF, uInt16(ansi_fg), 0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
append_sequence (color_str);
|
append_sequence (color_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( term.bg_color != bg || frev )
|
if ( term.bg_color != bg || frev )
|
||||||
{
|
{
|
||||||
color_str = FTermcap::encodeParameter(AB, ansi_bg, 0, 0, 0, 0, 0, 0, 0, 0);
|
color_str = FTermcap::encodeParameter(AB, uInt16(ansi_bg), 0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
append_sequence (color_str);
|
append_sequence (color_str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1400,13 +1400,13 @@ inline void FOptiAttr::change_current_color ( const FChar& term
|
||||||
{
|
{
|
||||||
if ( term.fg_color != fg || frev )
|
if ( term.fg_color != fg || frev )
|
||||||
{
|
{
|
||||||
color_str = FTermcap::encodeParameter(Sf, fg, 0, 0, 0, 0, 0, 0, 0, 0);
|
color_str = FTermcap::encodeParameter(Sf, uInt16(fg), 0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
append_sequence (color_str);
|
append_sequence (color_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( term.bg_color != bg || frev )
|
if ( term.bg_color != bg || frev )
|
||||||
{
|
{
|
||||||
color_str = FTermcap::encodeParameter(Sb, bg, 0, 0, 0, 0, 0, 0, 0, 0);
|
color_str = FTermcap::encodeParameter(Sb, uInt16(bg), 0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
append_sequence (color_str);
|
append_sequence (color_str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1414,7 +1414,7 @@ inline void FOptiAttr::change_current_color ( const FChar& term
|
||||||
{
|
{
|
||||||
fg = vga2ansi(fg);
|
fg = vga2ansi(fg);
|
||||||
bg = vga2ansi(bg);
|
bg = vga2ansi(bg);
|
||||||
color_str = FTermcap::encodeParameter(sp, fg, bg, 0, 0, 0, 0, 0, 0, 0);
|
color_str = FTermcap::encodeParameter(sp, uInt16(fg), uInt16(bg), 0, 0, 0, 0, 0, 0, 0);
|
||||||
append_sequence (color_str);
|
append_sequence (color_str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
* *
|
* *
|
||||||
* This file is part of the FINAL CUT widget toolkit *
|
* This file is part of the FINAL CUT widget toolkit *
|
||||||
* *
|
* *
|
||||||
* Copyright 2017-2020 Markus Gans *
|
* Copyright 2017-2021 Markus Gans *
|
||||||
* *
|
* *
|
||||||
* FINAL CUT is free software; you can redistribute it and/or modify *
|
* FINAL CUT is free software; you can redistribute it and/or modify *
|
||||||
* it under the terms of the GNU Lesser General Public License as *
|
* it under the terms of the GNU Lesser General Public License as *
|
||||||
|
@ -799,52 +799,40 @@ void FScrollView::calculateScrollbarPos() const
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
void FScrollView::setHorizontalScrollBarVisibility() const
|
void FScrollView::setHorizontalScrollBarVisibility() const
|
||||||
{
|
{
|
||||||
assert ( h_mode == ScrollBarMode::Auto
|
if ( h_mode == ScrollBarMode::Auto )
|
||||||
|| h_mode == ScrollBarMode::Hidden
|
|
||||||
|| h_mode == ScrollBarMode::Scroll );
|
|
||||||
|
|
||||||
switch ( h_mode )
|
|
||||||
{
|
{
|
||||||
case ScrollBarMode::Auto:
|
|
||||||
if ( getScrollWidth() > getViewportWidth() )
|
if ( getScrollWidth() > getViewportWidth() )
|
||||||
hbar->show();
|
hbar->show();
|
||||||
else
|
else
|
||||||
hbar->hide();
|
hbar->hide();
|
||||||
break;
|
}
|
||||||
|
else if ( h_mode == ScrollBarMode::Hidden )
|
||||||
case ScrollBarMode::Hidden:
|
{
|
||||||
hbar->hide();
|
hbar->hide();
|
||||||
break;
|
}
|
||||||
|
else if ( h_mode == ScrollBarMode::Scroll )
|
||||||
case ScrollBarMode::Scroll:
|
{
|
||||||
hbar->show();
|
hbar->show();
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
void FScrollView::setVerticalScrollBarVisibility() const
|
void FScrollView::setVerticalScrollBarVisibility() const
|
||||||
{
|
{
|
||||||
assert ( v_mode == ScrollBarMode::Auto
|
if ( v_mode == ScrollBarMode::Auto )
|
||||||
|| v_mode == ScrollBarMode::Hidden
|
|
||||||
|| v_mode == ScrollBarMode::Scroll );
|
|
||||||
|
|
||||||
switch ( v_mode )
|
|
||||||
{
|
{
|
||||||
case ScrollBarMode::Auto:
|
|
||||||
if ( getScrollHeight() > getViewportHeight() )
|
if ( getScrollHeight() > getViewportHeight() )
|
||||||
vbar->show();
|
vbar->show();
|
||||||
else
|
else
|
||||||
vbar->hide();
|
vbar->hide();
|
||||||
break;
|
}
|
||||||
|
else if ( v_mode == ScrollBarMode::Hidden )
|
||||||
case ScrollBarMode::Hidden:
|
{
|
||||||
vbar->hide();
|
vbar->hide();
|
||||||
break;
|
}
|
||||||
|
else if ( v_mode == ScrollBarMode::Scroll )
|
||||||
case ScrollBarMode::Scroll:
|
{
|
||||||
vbar->show();
|
vbar->show();
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* *
|
* *
|
||||||
* This file is part of the FINAL CUT widget toolkit *
|
* This file is part of the FINAL CUT widget toolkit *
|
||||||
* *
|
* *
|
||||||
* Copyright 2012-2020 Markus Gans *
|
* Copyright 2012-2021 Markus Gans *
|
||||||
* *
|
* *
|
||||||
* FINAL CUT is free software; you can redistribute it and/or modify *
|
* FINAL CUT is free software; you can redistribute it and/or modify *
|
||||||
* it under the terms of the GNU Lesser General Public License as *
|
* it under the terms of the GNU Lesser General Public License as *
|
||||||
|
@ -745,7 +745,7 @@ FStringList FString::split (const FString& delimiter) const
|
||||||
|
|
||||||
while ( token )
|
while ( token )
|
||||||
{
|
{
|
||||||
string_list.push_back (FString{token});
|
string_list.emplace_back(token);
|
||||||
token = _extractToken (&rest, nullptr, delimiter.wc_str());
|
token = _extractToken (&rest, nullptr, delimiter.wc_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* *
|
* *
|
||||||
* This file is part of the FINAL CUT widget toolkit *
|
* This file is part of the FINAL CUT widget toolkit *
|
||||||
* *
|
* *
|
||||||
* Copyright 2012-2020 Markus Gans *
|
* Copyright 2012-2021 Markus Gans *
|
||||||
* *
|
* *
|
||||||
* FINAL CUT is free software; you can redistribute it and/or modify *
|
* FINAL CUT is free software; you can redistribute it and/or modify *
|
||||||
* it under the terms of the GNU Lesser General Public License as *
|
* it under the terms of the GNU Lesser General Public License as *
|
||||||
|
@ -903,9 +903,9 @@ void FTerm::setPalette (FColor index, int r, int g, int b)
|
||||||
const int bb = (b * 1001) / 256;
|
const int bb = (b * 1001) / 256;
|
||||||
|
|
||||||
if ( Ic )
|
if ( Ic )
|
||||||
color_str = FTermcap::encodeParameter(Ic, index, rr, gg, bb, 0, 0, 0, 0, 0);
|
color_str = FTermcap::encodeParameter(Ic, uInt16(index), rr, gg, bb, 0, 0, 0, 0, 0);
|
||||||
else if ( Ip )
|
else if ( Ip )
|
||||||
color_str = FTermcap::encodeParameter(Ip, index, 0, 0, 0, rr, gg, bb, 0, 0);
|
color_str = FTermcap::encodeParameter(Ip, uInt16(index), 0, 0, 0, rr, gg, bb, 0, 0);
|
||||||
|
|
||||||
if ( color_str )
|
if ( color_str )
|
||||||
{
|
{
|
||||||
|
@ -1949,7 +1949,7 @@ void FTerm::enableMouse()
|
||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
if ( isLinuxTerm() && openConsole() == 0 )
|
if ( isLinuxTerm() && openConsole() == 0 )
|
||||||
{
|
{
|
||||||
if ( FTerm::getFTermLinux()->isLinuxConsole() )
|
if ( FTermLinux::isLinuxConsole() )
|
||||||
gpm_mouse = true;
|
gpm_mouse = true;
|
||||||
|
|
||||||
closeConsole();
|
closeConsole();
|
||||||
|
@ -2364,6 +2364,7 @@ void FTerm::finishOSspecifics() const
|
||||||
const auto& freebsd_console = FTerm::getFTermFreeBSD();
|
const auto& freebsd_console = FTerm::getFTermFreeBSD();
|
||||||
freebsd_console->finish();
|
freebsd_console->finish();
|
||||||
#elif defined(__NetBSD__) || defined(__OpenBSD__) || defined(UNIT_TEST)
|
#elif defined(__NetBSD__) || defined(__OpenBSD__) || defined(UNIT_TEST)
|
||||||
|
const auto& openbsd_console = FTerm::getFTermOpenBSD();
|
||||||
openbsd_console->finish();
|
openbsd_console->finish();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,9 @@ enum class FullWidthSupport
|
||||||
Yes = 1
|
Yes = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Constant
|
||||||
|
constexpr std::size_t NOT_FOUND = static_cast<std::size_t>(-1);
|
||||||
|
|
||||||
// global state
|
// global state
|
||||||
static FullWidthSupport has_fullwidth_support = FullWidthSupport::Unknown;
|
static FullWidthSupport has_fullwidth_support = FullWidthSupport::Unknown;
|
||||||
|
|
||||||
|
@ -407,7 +410,11 @@ FString getColumnSubString ( const FString& str
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ( col_num + width <= col_len )
|
if ( col_first == col_pos && width == 0 && num == 0 )
|
||||||
|
{
|
||||||
|
first++;
|
||||||
|
}
|
||||||
|
else if ( col_num + width <= col_len )
|
||||||
{
|
{
|
||||||
col_num += width;
|
col_num += width;
|
||||||
num++;
|
num++;
|
||||||
|
@ -418,6 +425,8 @@ FString getColumnSubString ( const FString& str
|
||||||
num++;
|
num++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -447,7 +456,7 @@ std::size_t getLengthFromColumnWidth ( const FString& str
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
std::size_t getColumnWidth (const FString& s, std::size_t pos)
|
std::size_t getColumnWidth (const FString& s, std::size_t end_pos)
|
||||||
{
|
{
|
||||||
if ( s.isEmpty() )
|
if ( s.isEmpty() )
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -455,10 +464,10 @@ std::size_t getColumnWidth (const FString& s, std::size_t pos)
|
||||||
std::size_t column_width{0};
|
std::size_t column_width{0};
|
||||||
const auto length = s.getLength();
|
const auto length = s.getLength();
|
||||||
|
|
||||||
if ( pos > length )
|
if ( end_pos > length )
|
||||||
pos = length;
|
end_pos = length;
|
||||||
|
|
||||||
for (std::size_t i{0}; i < pos; i++)
|
for (std::size_t i{0}; i < end_pos; i++)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -501,17 +510,40 @@ std::size_t getColumnWidth (const wchar_t wchar)
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
column_width = wcwidth(wchar);
|
||||||
|
|
||||||
if ( (wchar >= UniChar::NF_rev_left_arrow2 && wchar <= UniChar::NF_check_mark)
|
if ( (wchar >= UniChar::NF_rev_left_arrow2 && wchar <= UniChar::NF_check_mark)
|
||||||
|| ! hasFullWidthSupports() )
|
|| ! hasFullWidthSupports() )
|
||||||
column_width = 1;
|
{
|
||||||
else
|
column_width = std::min(column_width, 1);
|
||||||
column_width = wcwidth(wchar);
|
}
|
||||||
|
|
||||||
return ( column_width == -1 ) ? 0 : std::size_t(column_width);
|
return ( column_width == -1 ) ? 0 : std::size_t(column_width);
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
std::size_t getColumnWidth (FChar& term_char)
|
std::size_t getColumnWidth (const FChar& term_char)
|
||||||
|
{
|
||||||
|
return std::size_t(term_char.attr.bit.char_width);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
std::size_t getColumnWidth (const FTermBuffer& tbuf)
|
||||||
|
{
|
||||||
|
return ( tbuf.isEmpty() )
|
||||||
|
? 0
|
||||||
|
: std::accumulate ( std::next(tbuf.begin())
|
||||||
|
, tbuf.end()
|
||||||
|
, tbuf.front().attr.bit.char_width
|
||||||
|
, [] (std::size_t s, const FChar& c)
|
||||||
|
{
|
||||||
|
return s + c.attr.bit.char_width;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
void addColumnWidth (FChar& term_char)
|
||||||
{
|
{
|
||||||
const std::size_t char_width = getColumnWidth(term_char.ch[0]);
|
const std::size_t char_width = getColumnWidth(term_char.ch[0]);
|
||||||
|
|
||||||
|
@ -522,21 +554,117 @@ std::size_t getColumnWidth (FChar& term_char)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
term_char.attr.bit.char_width = char_width & 0x03;
|
term_char.attr.bit.char_width = char_width & 0x03;
|
||||||
|
|
||||||
return char_width;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
std::size_t getColumnWidth (const FTermBuffer& tb)
|
inline int isWhitespace (const wchar_t ch) noexcept
|
||||||
{
|
{
|
||||||
return std::accumulate ( std::next(tb.begin())
|
return std::iswspace(static_cast<wint_t>(ch));
|
||||||
, tb.end()
|
}
|
||||||
, tb.front().attr.bit.char_width
|
|
||||||
, [] (std::size_t s, const FChar& c)
|
//----------------------------------------------------------------------
|
||||||
|
int getCharLength (const FString& string, std::size_t pos)
|
||||||
|
{
|
||||||
|
// Gets the number of characters of the combined character
|
||||||
|
// at string position pos
|
||||||
|
|
||||||
|
const std::size_t len = string.getLength();
|
||||||
|
std::size_t n = pos;
|
||||||
|
const auto& ch = string[n];
|
||||||
|
std::size_t char_width = getColumnWidth(ch);
|
||||||
|
|
||||||
|
if ( isWhitespace(ch) )
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if ( char_width == 0 || n >= len )
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
do
|
||||||
{
|
{
|
||||||
return s + c.attr.bit.char_width;
|
n++;
|
||||||
|
char_width = getColumnWidth(string[n]);
|
||||||
}
|
}
|
||||||
);
|
while ( n < len && char_width == 0 && ! isWhitespace(string[n]) );
|
||||||
|
|
||||||
|
return int(n - pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
int getPrevCharLength (const FString& string, std::size_t pos)
|
||||||
|
{
|
||||||
|
// Gets the number of characters of the previous combined character
|
||||||
|
// at string position pos
|
||||||
|
|
||||||
|
const std::size_t len = string.getLength();
|
||||||
|
std::size_t n = pos;
|
||||||
|
const auto& ch = string[n];
|
||||||
|
std::size_t char_width = getColumnWidth(ch);
|
||||||
|
|
||||||
|
if ( (char_width == 0 || n == 0 || n >= len) && ! isWhitespace(ch) )
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
n--;
|
||||||
|
char_width = getColumnWidth(string[n]);
|
||||||
|
}
|
||||||
|
while ( n > 0 && char_width == 0 && ! isWhitespace(string[n]) );
|
||||||
|
|
||||||
|
if ( char_width == 0 )
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return int(pos - n);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
std::size_t searchLeftCharBegin (const FString& string, std::size_t pos)
|
||||||
|
{
|
||||||
|
// Search for the next character position to the left of string position pos
|
||||||
|
|
||||||
|
std::size_t n = pos;
|
||||||
|
|
||||||
|
if ( n == 0 )
|
||||||
|
return NOT_FOUND;
|
||||||
|
|
||||||
|
std::size_t char_width{0};
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
n--;
|
||||||
|
char_width = getColumnWidth(string[n]);
|
||||||
|
}
|
||||||
|
while ( n > 0 && char_width == 0 && ! isWhitespace(string[n]) );
|
||||||
|
|
||||||
|
if ( n == 0 && char_width == 0 )
|
||||||
|
return NOT_FOUND;
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
std::size_t searchRightCharBegin (const FString& string, std::size_t pos)
|
||||||
|
{
|
||||||
|
// Search for the next character position to the right of string position pos
|
||||||
|
|
||||||
|
const std::size_t len = string.getLength();
|
||||||
|
std::size_t n = pos;
|
||||||
|
|
||||||
|
if ( n >= len )
|
||||||
|
return NOT_FOUND;
|
||||||
|
|
||||||
|
std::size_t char_width{0};
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
n++;
|
||||||
|
char_width = getColumnWidth(string[n]);
|
||||||
|
}
|
||||||
|
while ( n < len && char_width == 0 && ! isWhitespace(string[n]) );
|
||||||
|
|
||||||
|
if ( n == len && char_width == 0 )
|
||||||
|
return NOT_FOUND;
|
||||||
|
|
||||||
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
@ -581,7 +709,7 @@ FPoint readCursorPos()
|
||||||
if ( pos > 4 )
|
if ( pos > 4 )
|
||||||
{
|
{
|
||||||
constexpr auto parse = "\033[%4d;%4dR";
|
constexpr auto parse = "\033[%4d;%4dR";
|
||||||
std::sscanf(temp.data(), parse, &x, &y);
|
std::sscanf(temp.data(), parse, &y, &x );
|
||||||
}
|
}
|
||||||
|
|
||||||
return FPoint{x, y};
|
return FPoint{x, y};
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* *
|
* *
|
||||||
* This file is part of the FINAL CUT widget toolkit *
|
* This file is part of the FINAL CUT widget toolkit *
|
||||||
* *
|
* *
|
||||||
* Copyright 2017-2020 Markus Gans *
|
* Copyright 2017-2021 Markus Gans *
|
||||||
* *
|
* *
|
||||||
* FINAL CUT is free software; you can redistribute it and/or modify *
|
* FINAL CUT is free software; you can redistribute it and/or modify *
|
||||||
* it under the terms of the GNU Lesser General Public License as *
|
* it under the terms of the GNU Lesser General Public License as *
|
||||||
|
@ -47,12 +47,17 @@ FString FTermBuffer::toString() const
|
||||||
{
|
{
|
||||||
std::wstring wide_string{};
|
std::wstring wide_string{};
|
||||||
wide_string.reserve(data.size());
|
wide_string.reserve(data.size());
|
||||||
std::transform ( data.begin()
|
std::for_each ( data.begin()
|
||||||
, data.end()
|
, data.end()
|
||||||
, std::back_inserter(wide_string)
|
, [&wide_string] (const FChar& fchar)
|
||||||
, [] (const FChar& fchar)
|
|
||||||
{
|
{
|
||||||
return fchar.ch[0];
|
for (auto&& ch : fchar.ch)
|
||||||
|
{
|
||||||
|
if ( ch == L'\0' )
|
||||||
|
return;
|
||||||
|
else
|
||||||
|
wide_string.push_back(ch);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
return wide_string;
|
return wide_string;
|
||||||
|
@ -62,19 +67,41 @@ FString FTermBuffer::toString() const
|
||||||
int FTermBuffer::write (const FString& string)
|
int FTermBuffer::write (const FString& string)
|
||||||
{
|
{
|
||||||
assert ( ! string.isNull() );
|
assert ( ! string.isNull() );
|
||||||
const auto len = int(string.getLength());
|
data.reserve(data.size() + string.getLength());
|
||||||
|
const auto last = string.end();
|
||||||
|
auto begin = string.begin();
|
||||||
|
auto iter = begin;
|
||||||
|
int char_width{0};
|
||||||
|
|
||||||
for (auto&& c : string)
|
for (auto&& ch : string)
|
||||||
{
|
{
|
||||||
FChar nc{FVTerm::getAttribute()}; // next character
|
auto width = getColumnWidth(ch);
|
||||||
nc.ch[0] = c;
|
auto wspace = std::iswspace(wint_t(ch));
|
||||||
nc.attr.byte[2] = 0;
|
|
||||||
nc.attr.byte[3] = 0;
|
if ( width == 0 && ! wspace ) // zero-width character
|
||||||
getColumnWidth(nc); // add column width
|
{
|
||||||
data.emplace_back(nc);
|
if ( iter == begin)
|
||||||
|
++begin;
|
||||||
|
|
||||||
|
++iter;
|
||||||
|
}
|
||||||
|
else if ( iter != begin )
|
||||||
|
add(begin, iter, char_width);
|
||||||
|
|
||||||
|
if ( iter == begin && (width > 0 || is7bit(ch)) ) // 1st char
|
||||||
|
++iter;
|
||||||
|
|
||||||
|
if ( width > 0 )
|
||||||
|
char_width += width;
|
||||||
|
|
||||||
|
if ( wspace )
|
||||||
|
add(begin, iter, char_width);
|
||||||
}
|
}
|
||||||
|
|
||||||
return len;
|
if ( iter == last )
|
||||||
|
add(begin, iter, char_width);
|
||||||
|
|
||||||
|
return int(string.getLength());
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
@ -82,7 +109,7 @@ int FTermBuffer::write (wchar_t ch)
|
||||||
{
|
{
|
||||||
FChar nc{FVTerm::getAttribute()}; // next character
|
FChar nc{FVTerm::getAttribute()}; // next character
|
||||||
nc.ch[0] = ch;
|
nc.ch[0] = ch;
|
||||||
getColumnWidth(nc); // add column width
|
addColumnWidth(nc); // add column width
|
||||||
nc.attr.bit.no_changes = false;
|
nc.attr.bit.no_changes = false;
|
||||||
nc.attr.bit.printed = false;
|
nc.attr.bit.printed = false;
|
||||||
data.emplace_back(nc);
|
data.emplace_back(nc);
|
||||||
|
@ -96,34 +123,23 @@ void FTermBuffer::write (const FStyle& style) const
|
||||||
|
|
||||||
if ( attr == Style::None )
|
if ( attr == Style::None )
|
||||||
FVTerm::setNormal();
|
FVTerm::setNormal();
|
||||||
else if ( (attr & Style::Bold) != Style::None )
|
else
|
||||||
FVTerm::setBold();
|
{
|
||||||
else if ( (attr & Style::Dim) != Style::None )
|
if ( (attr & Style::Bold) != Style::None ) FVTerm::setBold();
|
||||||
FVTerm::setDim();
|
if ( (attr & Style::Dim) != Style::None ) FVTerm::setDim();
|
||||||
else if ( (attr & Style::Italic) != Style::None )
|
if ( (attr & Style::Italic) != Style::None ) FVTerm::setItalic();
|
||||||
FVTerm::setItalic();
|
if ( (attr & Style::Underline) != Style::None ) FVTerm::setUnderline();
|
||||||
else if ( (attr & Style::Underline) != Style::None )
|
if ( (attr & Style::Blink) != Style::None ) FVTerm::setBlink();
|
||||||
FVTerm::setUnderline();
|
if ( (attr & Style::Reverse) != Style::None ) FVTerm::setReverse();
|
||||||
else if ( (attr & Style::Blink) != Style::None )
|
if ( (attr & Style::Standout) != Style::None ) FVTerm::setStandout();
|
||||||
FVTerm::setBlink();
|
if ( (attr & Style::Invisible) != Style::None ) FVTerm::setInvisible();
|
||||||
else if ( (attr & Style::Reverse) != Style::None )
|
if ( (attr & Style::Protected) != Style::None ) FVTerm::setProtected();
|
||||||
FVTerm::setReverse();
|
if ( (attr & Style::CrossedOut) != Style::None ) FVTerm::setCrossedOut();
|
||||||
else if ( (attr & Style::Standout) != Style::None )
|
if ( (attr & Style::DoubleUnderline) != Style::None ) FVTerm::setDoubleUnderline();
|
||||||
FVTerm::setStandout();
|
if ( (attr & Style::Transparent) != Style::None ) FVTerm::setTransparent();
|
||||||
else if ( (attr & Style::Invisible) != Style::None )
|
if ( (attr & Style::ColorOverlay) != Style::None ) FVTerm::setColorOverlay();
|
||||||
FVTerm::setInvisible();
|
if ( (attr & Style::InheritBackground) != Style::None ) FVTerm::setInheritBackground();
|
||||||
else if ( (attr & Style::Protected) != Style::None )
|
}
|
||||||
FVTerm::setProtected();
|
|
||||||
else if ( (attr & Style::CrossedOut) != Style::None )
|
|
||||||
FVTerm::setCrossedOut();
|
|
||||||
else if ( (attr & Style::DoubleUnderline) != Style::None )
|
|
||||||
FVTerm::setDoubleUnderline();
|
|
||||||
else if ( (attr & Style::Transparent) != Style::None )
|
|
||||||
FVTerm::setTransparent();
|
|
||||||
else if ( (attr & Style::ColorOverlay) != Style::None )
|
|
||||||
FVTerm::setColorOverlay();
|
|
||||||
else if ( (attr & Style::InheritBackground) != Style::None )
|
|
||||||
FVTerm::setInheritBackground();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
@ -133,6 +149,34 @@ void FTermBuffer::write (const FColorPair& pair) const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// private methods of FTermBuffer
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
void FTermBuffer::add ( FString::const_iterator& begin
|
||||||
|
, FString::const_iterator& end
|
||||||
|
, int& char_width )
|
||||||
|
{
|
||||||
|
if ( begin == end )
|
||||||
|
return;
|
||||||
|
|
||||||
|
FChar nc{FVTerm::getAttribute()}; // next character
|
||||||
|
nc.attr.byte[2] = 0;
|
||||||
|
nc.attr.byte[3] = 0;
|
||||||
|
|
||||||
|
if ( char_width == 2 && FTerm::getEncoding() != Encoding::UTF8 )
|
||||||
|
{
|
||||||
|
nc.ch[0] = '.';
|
||||||
|
nc.attr.bit.char_width = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
nc.attr.bit.char_width = char_width & 0x03;
|
||||||
|
|
||||||
|
std::copy(begin, std::min(end, begin + UNICODE_MAX), nc.ch.begin());
|
||||||
|
data.emplace_back(nc);
|
||||||
|
begin = end;
|
||||||
|
char_width = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// FTermBuffer non-member operators
|
// FTermBuffer non-member operators
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
FTermBuffer::FCharVector& operator << ( FTermBuffer::FCharVector& termString
|
FTermBuffer::FCharVector& operator << ( FTermBuffer::FCharVector& termString
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* *
|
* *
|
||||||
* This file is part of the FINAL CUT widget toolkit *
|
* This file is part of the FINAL CUT widget toolkit *
|
||||||
* *
|
* *
|
||||||
* Copyright 2015-2020 Markus Gans *
|
* Copyright 2015-2021 Markus Gans *
|
||||||
* *
|
* *
|
||||||
* FINAL CUT is free software; you can redistribute it and/or modify *
|
* FINAL CUT is free software; you can redistribute it and/or modify *
|
||||||
* it under the terms of the GNU Lesser General Public License as *
|
* it under the terms of the GNU Lesser General Public License as *
|
||||||
|
@ -92,14 +92,14 @@ void FTermcap::termcap()
|
||||||
#else
|
#else
|
||||||
const char* termtype = fterm_data->getTermType();
|
const char* termtype = fterm_data->getTermType();
|
||||||
#endif
|
#endif
|
||||||
terminals.push_back(termtype); // available terminal type
|
terminals.emplace_back(termtype); // available terminal type
|
||||||
|
|
||||||
if ( color256 ) // 1st fallback if not found
|
if ( color256 ) // 1st fallback if not found
|
||||||
terminals.push_back("xterm-256color");
|
terminals.emplace_back("xterm-256color");
|
||||||
|
|
||||||
terminals.push_back("xterm"); // 2nd fallback if not found
|
terminals.emplace_back("xterm"); // 2nd fallback if not found
|
||||||
terminals.push_back("ansi"); // 3rd fallback if not found
|
terminals.emplace_back("ansi"); // 3rd fallback if not found
|
||||||
terminals.push_back("vt100"); // 4th fallback if not found
|
terminals.emplace_back("vt100"); // 4th fallback if not found
|
||||||
auto iter = terminals.begin();
|
auto iter = terminals.begin();
|
||||||
|
|
||||||
while ( iter != terminals.end() )
|
while ( iter != terminals.end() )
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* *
|
* *
|
||||||
* This file is part of the FINAL CUT widget toolkit *
|
* This file is part of the FINAL CUT widget toolkit *
|
||||||
* *
|
* *
|
||||||
* Copyright 2018-2020 Markus Gans *
|
* Copyright 2018-2021 Markus Gans *
|
||||||
* *
|
* *
|
||||||
* FINAL CUT is free software; you can redistribute it and/or modify *
|
* FINAL CUT is free software; you can redistribute it and/or modify *
|
||||||
* it under the terms of the GNU Lesser General Public License as *
|
* it under the terms of the GNU Lesser General Public License as *
|
||||||
|
@ -241,7 +241,7 @@ void FTermLinux::initCharMap() const
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
void FTermLinux::finish()
|
void FTermLinux::finish() const
|
||||||
{
|
{
|
||||||
if ( FTerm::isLinuxTerm() )
|
if ( FTerm::isLinuxTerm() )
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* *
|
* *
|
||||||
* This file is part of the FINAL CUT widget toolkit *
|
* This file is part of the FINAL CUT widget toolkit *
|
||||||
* *
|
* *
|
||||||
* Copyright 2014-2020 Markus Gans *
|
* Copyright 2014-2021 Markus Gans *
|
||||||
* *
|
* *
|
||||||
* FINAL CUT is free software; you can redistribute it and/or modify *
|
* FINAL CUT is free software; you can redistribute it and/or modify *
|
||||||
* it under the terms of the GNU Lesser General Public License as *
|
* it under the terms of the GNU Lesser General Public License as *
|
||||||
|
@ -29,6 +29,7 @@
|
||||||
#include "final/fstring.h"
|
#include "final/fstring.h"
|
||||||
#include "final/fscrollbar.h"
|
#include "final/fscrollbar.h"
|
||||||
#include "final/fstatusbar.h"
|
#include "final/fstatusbar.h"
|
||||||
|
#include "final/ftermbuffer.h"
|
||||||
#include "final/ftextview.h"
|
#include "final/ftextview.h"
|
||||||
#include "final/fwidgetcolors.h"
|
#include "final/fwidgetcolors.h"
|
||||||
|
|
||||||
|
@ -224,7 +225,6 @@ void FTextView::insert (const FString& str, int pos)
|
||||||
else
|
else
|
||||||
s = FString{str}.rtrim().expandTabs(FTerm::getTabstop());
|
s = FString{str}.rtrim().expandTabs(FTerm::getTabstop());
|
||||||
|
|
||||||
|
|
||||||
auto text_split = s.split("\r\n");
|
auto text_split = s.split("\r\n");
|
||||||
|
|
||||||
for (auto&& line : text_split) // Line loop
|
for (auto&& line : text_split) // Line loop
|
||||||
|
@ -641,19 +641,17 @@ void FTextView::drawText()
|
||||||
const std::size_t pos = std::size_t(xoffset) + 1;
|
const std::size_t pos = std::size_t(xoffset) + 1;
|
||||||
const auto text_width = getTextWidth();
|
const auto text_width = getTextWidth();
|
||||||
const FString line(getColumnSubString(data[n], pos, text_width));
|
const FString line(getColumnSubString(data[n], pos, text_width));
|
||||||
const auto column_width = getColumnWidth(line);
|
|
||||||
std::size_t trailing_whitespace{0};
|
std::size_t trailing_whitespace{0};
|
||||||
print() << FPoint{2, 2 - nf_offset + int(y)};
|
print() << FPoint{2, 2 - nf_offset + int(y)};
|
||||||
|
FTermBuffer line_buffer{};
|
||||||
|
line_buffer.write(line);
|
||||||
|
|
||||||
for (auto&& ch : line) // Column loop
|
for (auto&& fchar : line_buffer) // Column loop
|
||||||
{
|
if ( ! isPrintable(fchar.ch[0]) )
|
||||||
if ( getColumnWidth(ch) == 0 )
|
fchar.ch[0] = L'.';
|
||||||
continue;
|
|
||||||
else if ( isPrintable(ch) )
|
print(line_buffer);
|
||||||
print (ch);
|
const auto column_width = getColumnWidth(line);
|
||||||
else
|
|
||||||
print ('.');
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( column_width <= text_width )
|
if ( column_width <= text_width )
|
||||||
trailing_whitespace = text_width - column_width;
|
trailing_whitespace = text_width - column_width;
|
||||||
|
@ -693,7 +691,7 @@ inline bool FTextView::isPrintable (wchar_t ch) const
|
||||||
const bool utf8 = ( FTerm::getEncoding() == Encoding::UTF8 ) ? true : false;
|
const bool utf8 = ( FTerm::getEncoding() == Encoding::UTF8 ) ? true : false;
|
||||||
|
|
||||||
if ( (utf8 && std::iswprint(std::wint_t(ch)))
|
if ( (utf8 && std::iswprint(std::wint_t(ch)))
|
||||||
|| (!utf8 && std::isprint(char(ch))) )
|
|| (! utf8 && std::isprint(char(ch))) )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
107
src/fvterm.cpp
107
src/fvterm.cpp
|
@ -3,7 +3,7 @@
|
||||||
* *
|
* *
|
||||||
* This file is part of the FINAL CUT widget toolkit *
|
* This file is part of the FINAL CUT widget toolkit *
|
||||||
* *
|
* *
|
||||||
* Copyright 2016-2020 Markus Gans *
|
* Copyright 2016-2021 Markus Gans *
|
||||||
* *
|
* *
|
||||||
* FINAL CUT is free software; you can redistribute it and/or modify *
|
* FINAL CUT is free software; you can redistribute it and/or modify *
|
||||||
* it under the terms of the GNU Lesser General Public License as *
|
* it under the terms of the GNU Lesser General Public License as *
|
||||||
|
@ -40,8 +40,10 @@
|
||||||
#include "final/fstyle.h"
|
#include "final/fstyle.h"
|
||||||
#include "final/fsystem.h"
|
#include "final/fsystem.h"
|
||||||
#include "final/fterm.h"
|
#include "final/fterm.h"
|
||||||
#include "final/ftermdata.h"
|
|
||||||
#include "final/ftermbuffer.h"
|
#include "final/ftermbuffer.h"
|
||||||
|
#include "final/ftermdata.h"
|
||||||
|
#include "final/ftermdetection.h"
|
||||||
|
#include "final/ftermfreebsd.h"
|
||||||
#include "final/ftermcap.h"
|
#include "final/ftermcap.h"
|
||||||
#include "final/ftypes.h"
|
#include "final/ftypes.h"
|
||||||
#include "final/fvterm.h"
|
#include "final/fvterm.h"
|
||||||
|
@ -53,6 +55,7 @@ namespace finalcut
|
||||||
|
|
||||||
// static class attributes
|
// static class attributes
|
||||||
bool FVTerm::draw_completed{false};
|
bool FVTerm::draw_completed{false};
|
||||||
|
bool FVTerm::combined_char_support{false};
|
||||||
bool FVTerm::no_terminal_updates{false};
|
bool FVTerm::no_terminal_updates{false};
|
||||||
bool FVTerm::cursor_hideable{false};
|
bool FVTerm::cursor_hideable{false};
|
||||||
bool FVTerm::force_terminal_update{false};
|
bool FVTerm::force_terminal_update{false};
|
||||||
|
@ -490,10 +493,11 @@ int FVTerm::print (FTermArea* area, FChar& term_char)
|
||||||
|
|
||||||
const int ax = area->cursor_x - 1;
|
const int ax = area->cursor_x - 1;
|
||||||
const int ay = area->cursor_y - 1;
|
const int ay = area->cursor_y - 1;
|
||||||
std::size_t char_width = term_char.attr.bit.char_width;
|
|
||||||
|
|
||||||
if ( char_width == 0 )
|
if ( term_char.attr.bit.char_width == 0 )
|
||||||
char_width = getColumnWidth(term_char); // add column width
|
addColumnWidth(term_char); // add column width
|
||||||
|
|
||||||
|
auto char_width = term_char.attr.bit.char_width;
|
||||||
|
|
||||||
if ( char_width == 0 && ! term_char.attr.bit.fullwidth_padding )
|
if ( char_width == 0 && ! term_char.attr.bit.fullwidth_padding )
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -535,34 +539,23 @@ void FVTerm::print (const FStyle& style)
|
||||||
|
|
||||||
if ( attr == Style::None )
|
if ( attr == Style::None )
|
||||||
setNormal();
|
setNormal();
|
||||||
else if ( (attr & Style::Bold) != Style::None )
|
else
|
||||||
setBold();
|
{
|
||||||
else if ( (attr & Style::Dim) != Style::None )
|
if ( (attr & Style::Bold) != Style::None ) setBold();
|
||||||
setDim();
|
if ( (attr & Style::Dim) != Style::None ) setDim();
|
||||||
else if ( (attr & Style::Italic) != Style::None )
|
if ( (attr & Style::Italic) != Style::None ) setItalic();
|
||||||
setItalic();
|
if ( (attr & Style::Underline) != Style::None ) setUnderline();
|
||||||
else if ( (attr & Style::Underline) != Style::None )
|
if ( (attr & Style::Blink) != Style::None ) setBlink();
|
||||||
setUnderline();
|
if ( (attr & Style::Reverse) != Style::None ) setReverse();
|
||||||
else if ( (attr & Style::Blink) != Style::None )
|
if ( (attr & Style::Standout) != Style::None ) setStandout();
|
||||||
setBlink();
|
if ( (attr & Style::Invisible) != Style::None ) setInvisible();
|
||||||
else if ( (attr & Style::Reverse) != Style::None )
|
if ( (attr & Style::Protected) != Style::None ) setProtected();
|
||||||
setReverse();
|
if ( (attr & Style::CrossedOut) != Style::None ) setCrossedOut();
|
||||||
else if ( (attr & Style::Standout) != Style::None )
|
if ( (attr & Style::DoubleUnderline) != Style::None ) setDoubleUnderline();
|
||||||
setStandout();
|
if ( (attr & Style::Transparent) != Style::None ) setTransparent();
|
||||||
else if ( (attr & Style::Invisible) != Style::None )
|
if ( (attr & Style::ColorOverlay) != Style::None ) setColorOverlay();
|
||||||
setInvisible();
|
if ( (attr & Style::InheritBackground) != Style::None ) setInheritBackground();
|
||||||
else if ( (attr & Style::Protected) != Style::None )
|
}
|
||||||
setProtected();
|
|
||||||
else if ( (attr & Style::CrossedOut) != Style::None )
|
|
||||||
setCrossedOut();
|
|
||||||
else if ( (attr & Style::DoubleUnderline) != Style::None )
|
|
||||||
setDoubleUnderline();
|
|
||||||
else if ( (attr & Style::Transparent) != Style::None )
|
|
||||||
setTransparent();
|
|
||||||
else if ( (attr & Style::ColorOverlay) != Style::None )
|
|
||||||
setColorOverlay();
|
|
||||||
else if ( (attr & Style::InheritBackground) != Style::None )
|
|
||||||
setInheritBackground();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
@ -1285,6 +1278,9 @@ void FVTerm::initTerminal()
|
||||||
|
|
||||||
// Initialize character lengths
|
// Initialize character lengths
|
||||||
init_characterLengths();
|
init_characterLengths();
|
||||||
|
|
||||||
|
// Check for support for combined characters
|
||||||
|
init_combined_character();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1884,6 +1880,31 @@ void FVTerm::init_characterLengths()
|
||||||
if ( clr_eol_length == 0 )
|
if ( clr_eol_length == 0 )
|
||||||
clr_eol_length = INT_MAX;
|
clr_eol_length = INT_MAX;
|
||||||
}
|
}
|
||||||
|
#include <unistd.h>
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
void FVTerm::init_combined_character()
|
||||||
|
{
|
||||||
|
#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(UNIT_TEST)
|
||||||
|
if ( FTermFreeBSD::isFreeBSDConsole() )
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if ( FTerm::getEncoding() != Encoding::UTF8 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
const auto& term_detection = FTerm::getFTermDetection();
|
||||||
|
|
||||||
|
if ( term_detection->isCygwinTerminal() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ( term_detection->isXTerminal()
|
||||||
|
|| term_detection->isUrxvtTerminal()
|
||||||
|
|| term_detection->isMinttyTerm()
|
||||||
|
|| term_detection->isPuttyTerminal() )
|
||||||
|
{
|
||||||
|
combined_char_support = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
void FVTerm::finish()
|
void FVTerm::finish()
|
||||||
|
@ -2006,7 +2027,7 @@ void FVTerm::getAreaCharacter ( const FPoint& pos, const FTermArea* area
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
bool FVTerm::clearTerm (int fillchar) const
|
bool FVTerm::clearTerm (wchar_t fillchar) const
|
||||||
{
|
{
|
||||||
// Clear the real terminal and put cursor at home
|
// Clear the real terminal and put cursor at home
|
||||||
|
|
||||||
|
@ -2018,7 +2039,7 @@ bool FVTerm::clearTerm (int fillchar) const
|
||||||
appendAttributes (next_attribute);
|
appendAttributes (next_attribute);
|
||||||
|
|
||||||
if ( ! ( (cl || cd || cb) && (normal || ut) )
|
if ( ! ( (cl || cd || cb) && (normal || ut) )
|
||||||
|| fillchar != ' ' )
|
|| fillchar != L' ' )
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2570,7 +2591,7 @@ FVTerm::PrintState FVTerm::repeatCharacter (uInt& x, uInt xmax, uInt y) const
|
||||||
const uInt start_pos = x;
|
const uInt start_pos = x;
|
||||||
|
|
||||||
if ( repetitions > repeat_char_length
|
if ( repetitions > repeat_char_length
|
||||||
&& print_char.ch[0] < 128 )
|
&& is7bit(print_char.ch[0]) && print_char.ch[1] == L'\0' )
|
||||||
{
|
{
|
||||||
newFontChanges (print_char);
|
newFontChanges (print_char);
|
||||||
charsetChanges (print_char);
|
charsetChanges (print_char);
|
||||||
|
@ -2917,7 +2938,9 @@ inline void FVTerm::newFontChanges (FChar& next_char)
|
||||||
inline void FVTerm::charsetChanges (FChar& next_char)
|
inline void FVTerm::charsetChanges (FChar& next_char)
|
||||||
{
|
{
|
||||||
const wchar_t& ch = next_char.ch[0];
|
const wchar_t& ch = next_char.ch[0];
|
||||||
next_char.encoded_char[0] = ch;
|
std::copy( next_char.ch.begin()
|
||||||
|
, next_char.ch.end()
|
||||||
|
, next_char.encoded_char.begin() );
|
||||||
|
|
||||||
if ( FTerm::getEncoding() == Encoding::UTF8 )
|
if ( FTerm::getEncoding() == Encoding::UTF8 )
|
||||||
return;
|
return;
|
||||||
|
@ -2979,7 +3002,15 @@ inline void FVTerm::appendChar (FChar& next_char) const
|
||||||
charsetChanges (next_char);
|
charsetChanges (next_char);
|
||||||
appendAttributes (next_char);
|
appendAttributes (next_char);
|
||||||
characterFilter (next_char);
|
characterFilter (next_char);
|
||||||
appendOutputBuffer (next_char.encoded_char[0]);
|
|
||||||
|
for (auto&& ch : next_char.encoded_char)
|
||||||
|
{
|
||||||
|
if ( ch != L'\0')
|
||||||
|
appendOutputBuffer(ch);
|
||||||
|
|
||||||
|
if ( ! combined_char_support )
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
|
|
@ -801,7 +801,7 @@ enum class FKey : uInt32
|
||||||
|
|
||||||
struct FKeyHash
|
struct FKeyHash
|
||||||
{
|
{
|
||||||
std::size_t operator () (const FKey& p) const
|
std::size_t operator () (const FKey& p) const noexcept
|
||||||
{
|
{
|
||||||
return std::hash<uInt32>()(uInt32(p));
|
return std::hash<uInt32>()(uInt32(p));
|
||||||
}
|
}
|
||||||
|
|
|
@ -170,6 +170,7 @@ class FLineEdit : public FWidget
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
static constexpr auto NOT_SET = static_cast<std::size_t>(-1);
|
static constexpr auto NOT_SET = static_cast<std::size_t>(-1);
|
||||||
|
static constexpr auto NOT_FOUND = static_cast<std::size_t>(-1);
|
||||||
|
|
||||||
// Methods
|
// Methods
|
||||||
void init();
|
void init();
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* *
|
* *
|
||||||
* This file is part of the FINAL CUT widget toolkit *
|
* This file is part of the FINAL CUT widget toolkit *
|
||||||
* *
|
* *
|
||||||
* Copyright 2012-2020 Markus Gans *
|
* Copyright 2012-2021 Markus Gans *
|
||||||
* *
|
* *
|
||||||
* FINAL CUT is free software; you can redistribute it and/or modify *
|
* FINAL CUT is free software; you can redistribute it and/or modify *
|
||||||
* it under the terms of the GNU Lesser General Public License as *
|
* it under the terms of the GNU Lesser General Public License as *
|
||||||
|
@ -167,21 +167,21 @@ class FString
|
||||||
virtual FString getClassName() const;
|
virtual FString getClassName() const;
|
||||||
|
|
||||||
// inquiries
|
// inquiries
|
||||||
bool isNull() const;
|
bool isNull() const noexcept;
|
||||||
bool isEmpty() const;
|
bool isEmpty() const noexcept;
|
||||||
|
|
||||||
// Methods
|
// Methods
|
||||||
std::size_t getLength() const;
|
std::size_t getLength() const noexcept;
|
||||||
std::size_t capacity() const;
|
std::size_t capacity() const noexcept;
|
||||||
|
|
||||||
iterator begin();
|
iterator begin() noexcept;
|
||||||
iterator end();
|
iterator end() noexcept;
|
||||||
const_iterator begin() const;
|
const_iterator begin() const noexcept;
|
||||||
const_iterator end() const;
|
const_iterator end() const noexcept;
|
||||||
reference front();
|
reference front() noexcept;
|
||||||
reference back() ;
|
reference back() noexcept;
|
||||||
const_reference front() const;
|
const_reference front() const noexcept;
|
||||||
const_reference back() const;
|
const_reference back() const noexcept;
|
||||||
|
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
FString& sprintf (const FString&, Args&&...);
|
FString& sprintf (const FString&, Args&&...);
|
||||||
|
@ -371,60 +371,60 @@ inline FString FString::getClassName() const
|
||||||
{ return "FString"; }
|
{ return "FString"; }
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
inline bool FString::isNull() const
|
inline bool FString::isNull() const noexcept
|
||||||
{ return ( bufsize == 0 || (bufsize > 0 && ! string) ); }
|
{ return ( bufsize == 0 || (bufsize > 0 && ! string) ); }
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
inline bool FString::isEmpty() const
|
inline bool FString::isEmpty() const noexcept
|
||||||
{ return ( length == 0 || (length > 0 && string[0] == L'\0') ); }
|
{ return ( length == 0 || (length > 0 && string[0] == L'\0') ); }
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
inline std::size_t FString::getLength() const
|
inline std::size_t FString::getLength() const noexcept
|
||||||
{ return length; }
|
{ return length; }
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
inline std::size_t FString::capacity() const
|
inline std::size_t FString::capacity() const noexcept
|
||||||
{ return ( length > 0 ) ? bufsize - 1 : 0; }
|
{ return ( length > 0 ) ? bufsize - 1 : 0; }
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
inline FString::iterator FString::begin()
|
inline FString::iterator FString::begin() noexcept
|
||||||
{ return string; }
|
{ return string; }
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
inline FString::iterator FString::end()
|
inline FString::iterator FString::end() noexcept
|
||||||
{ return string + length; }
|
{ return string + length; }
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
inline FString::const_iterator FString::begin() const
|
inline FString::const_iterator FString::begin() const noexcept
|
||||||
{ return string; }
|
{ return string; }
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
inline FString::const_iterator FString::end() const
|
inline FString::const_iterator FString::end() const noexcept
|
||||||
{ return string + length; }
|
{ return string + length; }
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
inline FString::reference FString::front()
|
inline FString::reference FString::front() noexcept
|
||||||
{
|
{
|
||||||
assert ( ! isEmpty() );
|
assert ( ! isEmpty() );
|
||||||
return (*this)[0];
|
return (*this)[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
inline FString::reference FString::back()
|
inline FString::reference FString::back() noexcept
|
||||||
{
|
{
|
||||||
assert( ! isEmpty() );
|
assert( ! isEmpty() );
|
||||||
return (*this)[length - 1];
|
return (*this)[length - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
inline FString::const_reference FString::front() const
|
inline FString::const_reference FString::front() const noexcept
|
||||||
{
|
{
|
||||||
assert ( ! isEmpty() );
|
assert ( ! isEmpty() );
|
||||||
return (*this)[0];
|
return (*this)[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
inline FString::const_reference FString::back() const
|
inline FString::const_reference FString::back() const noexcept
|
||||||
{
|
{
|
||||||
assert( ! isEmpty() );
|
assert( ! isEmpty() );
|
||||||
return (*this)[length - 1];
|
return (*this)[length - 1];
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* *
|
* *
|
||||||
* This file is part of the FINAL CUT widget toolkit *
|
* This file is part of the FINAL CUT widget toolkit *
|
||||||
* *
|
* *
|
||||||
* Copyright 2012-2020 Markus Gans *
|
* Copyright 2012-2021 Markus Gans *
|
||||||
* *
|
* *
|
||||||
* FINAL CUT is free software; you can redistribute it and/or modify *
|
* FINAL CUT is free software; you can redistribute it and/or modify *
|
||||||
* it under the terms of the GNU Lesser General Public License as *
|
* it under the terms of the GNU Lesser General Public License as *
|
||||||
|
@ -381,10 +381,23 @@ std::size_t getLengthFromColumnWidth (const FString&, std::size_t);
|
||||||
std::size_t getColumnWidth (const FString&, std::size_t);
|
std::size_t getColumnWidth (const FString&, std::size_t);
|
||||||
std::size_t getColumnWidth (const FString&);
|
std::size_t getColumnWidth (const FString&);
|
||||||
std::size_t getColumnWidth (const wchar_t);
|
std::size_t getColumnWidth (const wchar_t);
|
||||||
std::size_t getColumnWidth (FChar&);
|
std::size_t getColumnWidth (const FChar&);
|
||||||
std::size_t getColumnWidth (const FTermBuffer&);
|
std::size_t getColumnWidth (const FTermBuffer&);
|
||||||
|
void addColumnWidth (FChar&);
|
||||||
|
int getCharLength (const FString&, std::size_t);
|
||||||
|
int getPrevCharLength (const FString&, std::size_t);
|
||||||
|
std::size_t searchLeftCharBegin (const FString&, std::size_t);
|
||||||
|
std::size_t searchRightCharBegin (const FString&, std::size_t);
|
||||||
FPoint readCursorPos();
|
FPoint readCursorPos();
|
||||||
|
|
||||||
|
// Check for 7-bit ASCII
|
||||||
|
template<typename CharT>
|
||||||
|
inline bool is7bit (CharT ch)
|
||||||
|
{
|
||||||
|
using char_type = typename std::make_unsigned<CharT>::type;
|
||||||
|
return static_cast<char_type>(ch) < 128;
|
||||||
|
}
|
||||||
|
|
||||||
// FTerm inline functions
|
// FTerm inline functions
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
inline FString FTerm::getClassName()
|
inline FString FTerm::getClassName()
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* *
|
* *
|
||||||
* This file is part of the FINAL CUT widget toolkit *
|
* This file is part of the FINAL CUT widget toolkit *
|
||||||
* *
|
* *
|
||||||
* Copyright 2017-2020 Markus Gans *
|
* Copyright 2017-2021 Markus Gans *
|
||||||
* *
|
* *
|
||||||
* FINAL CUT is free software; you can redistribute it and/or modify *
|
* FINAL CUT is free software; you can redistribute it and/or modify *
|
||||||
* it under the terms of the GNU Lesser General Public License as *
|
* it under the terms of the GNU Lesser General Public License as *
|
||||||
|
@ -110,6 +110,9 @@ class FTermBuffer
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FCharVector data{};
|
FCharVector data{};
|
||||||
|
void add ( FString::const_iterator&
|
||||||
|
, FString::const_iterator&
|
||||||
|
, int& );
|
||||||
|
|
||||||
// Non-member operators
|
// Non-member operators
|
||||||
friend FCharVector& operator << ( FCharVector&
|
friend FCharVector& operator << ( FCharVector&
|
||||||
|
|
|
@ -109,7 +109,7 @@ class FTermLinux final
|
||||||
// Methods
|
// Methods
|
||||||
void init();
|
void init();
|
||||||
void initCharMap() const;
|
void initCharMap() const;
|
||||||
void finish();
|
void finish() const;
|
||||||
bool loadVGAFont();
|
bool loadVGAFont();
|
||||||
bool loadNewFont();
|
bool loadNewFont();
|
||||||
bool loadOldFont();
|
bool loadOldFont();
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* *
|
* *
|
||||||
* This file is part of the FINAL CUT widget toolkit *
|
* This file is part of the FINAL CUT widget toolkit *
|
||||||
* *
|
* *
|
||||||
* Copyright 2017-2020 Markus Gans *
|
* Copyright 2017-2021 Markus Gans *
|
||||||
* *
|
* *
|
||||||
* FINAL CUT is free software; you can redistribute it and/or modify *
|
* FINAL CUT is free software; you can redistribute it and/or modify *
|
||||||
* it under the terms of the GNU Lesser General Public License as *
|
* it under the terms of the GNU Lesser General Public License as *
|
||||||
|
@ -157,7 +157,7 @@ union attribute
|
||||||
uInt8 byte[4];
|
uInt8 byte[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
static constexpr uInt UNICODE_MAX = 5;
|
static constexpr std::size_t UNICODE_MAX = 5;
|
||||||
|
|
||||||
using FUnicode = std::array<wchar_t, UNICODE_MAX>;
|
using FUnicode = std::array<wchar_t, UNICODE_MAX>;
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* *
|
* *
|
||||||
* This file is part of the FINAL CUT widget toolkit *
|
* This file is part of the FINAL CUT widget toolkit *
|
||||||
* *
|
* *
|
||||||
* Copyright 2016-2020 Markus Gans *
|
* Copyright 2016-2021 Markus Gans *
|
||||||
* *
|
* *
|
||||||
* FINAL CUT is free software; you can redistribute it and/or modify *
|
* FINAL CUT is free software; you can redistribute it and/or modify *
|
||||||
* it under the terms of the GNU Lesser General Public License as *
|
* it under the terms of the GNU Lesser General Public License as *
|
||||||
|
@ -339,7 +339,7 @@ class FVTerm
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
// Buffer size for character output on the terminal
|
// Buffer size for character output on the terminal
|
||||||
static constexpr uInt TERMINAL_OUTPUT_BUFFER_SIZE = 131072;
|
static constexpr std::size_t TERMINAL_OUTPUT_BUFFER_SIZE = 131072;
|
||||||
|
|
||||||
// Methods
|
// Methods
|
||||||
void resetTextAreaToDefault ( const FTermArea*
|
void resetTextAreaToDefault ( const FTermArea*
|
||||||
|
@ -371,13 +371,14 @@ class FVTerm
|
||||||
static FChar getOverlappedCharacter (const FPoint&, const FTermArea*);
|
static FChar getOverlappedCharacter (const FPoint&, const FTermArea*);
|
||||||
void init();
|
void init();
|
||||||
static void init_characterLengths();
|
static void init_characterLengths();
|
||||||
|
static void init_combined_character();
|
||||||
void finish();
|
void finish();
|
||||||
static void putAreaLine (const FChar&, FChar&, std::size_t);
|
static void putAreaLine (const FChar&, FChar&, std::size_t);
|
||||||
static void putAreaCharacter ( const FPoint&, const FTermArea*
|
static void putAreaCharacter ( const FPoint&, const FTermArea*
|
||||||
, const FChar&, FChar& );
|
, const FChar&, FChar& );
|
||||||
static void getAreaCharacter ( const FPoint&, const FTermArea*
|
static void getAreaCharacter ( const FPoint&, const FTermArea*
|
||||||
, FChar*& );
|
, FChar*& );
|
||||||
bool clearTerm (int = ' ') const;
|
bool clearTerm (wchar_t = L' ') const;
|
||||||
bool clearFullArea (const FTermArea*, FChar&) const;
|
bool clearFullArea (const FTermArea*, FChar&) const;
|
||||||
static void clearAreaWithShadow (const FTermArea*, const FChar&);
|
static void clearAreaWithShadow (const FTermArea*, const FChar&);
|
||||||
static bool canClearToEOL (uInt, uInt);
|
static bool canClearToEOL (uInt, uInt);
|
||||||
|
@ -439,6 +440,7 @@ class FVTerm
|
||||||
static timeval time_last_flush;
|
static timeval time_last_flush;
|
||||||
static timeval last_term_size_check;
|
static timeval last_term_size_check;
|
||||||
static bool draw_completed;
|
static bool draw_completed;
|
||||||
|
static bool combined_char_support;
|
||||||
static bool no_terminal_updates;
|
static bool no_terminal_updates;
|
||||||
static bool force_terminal_update;
|
static bool force_terminal_update;
|
||||||
static uInt64 flush_wait;
|
static uInt64 flush_wait;
|
||||||
|
|
|
@ -12,7 +12,9 @@ noinst_PROGRAMS = \
|
||||||
fdata_test \
|
fdata_test \
|
||||||
fmouse_test \
|
fmouse_test \
|
||||||
fkeyboard_test \
|
fkeyboard_test \
|
||||||
|
fterm_functions_test \
|
||||||
ftermdata_test \
|
ftermdata_test \
|
||||||
|
ftermbuffer_test \
|
||||||
ftermdetection_test \
|
ftermdetection_test \
|
||||||
ftermcapquirks_test \
|
ftermcapquirks_test \
|
||||||
ftermlinux_test \
|
ftermlinux_test \
|
||||||
|
@ -34,7 +36,9 @@ fcallback_test_SOURCES = fcallback-test.cpp
|
||||||
fdata_test_SOURCES = fdata-test.cpp
|
fdata_test_SOURCES = fdata-test.cpp
|
||||||
fmouse_test_SOURCES = fmouse-test.cpp
|
fmouse_test_SOURCES = fmouse-test.cpp
|
||||||
fkeyboard_test_SOURCES = fkeyboard-test.cpp
|
fkeyboard_test_SOURCES = fkeyboard-test.cpp
|
||||||
|
fterm_functions_test_SOURCES = fterm_functions-test.cpp
|
||||||
ftermdata_test_SOURCES = ftermdata-test.cpp
|
ftermdata_test_SOURCES = ftermdata-test.cpp
|
||||||
|
ftermbuffer_test_SOURCES = ftermbuffer-test.cpp
|
||||||
ftermdetection_test_SOURCES = ftermdetection-test.cpp
|
ftermdetection_test_SOURCES = ftermdetection-test.cpp
|
||||||
ftermcapquirks_test_SOURCES = ftermcapquirks-test.cpp
|
ftermcapquirks_test_SOURCES = ftermcapquirks-test.cpp
|
||||||
ftermlinux_test_SOURCES = ftermlinux-test.cpp
|
ftermlinux_test_SOURCES = ftermlinux-test.cpp
|
||||||
|
@ -56,7 +60,9 @@ TESTS = fobject_test \
|
||||||
fdata_test \
|
fdata_test \
|
||||||
fmouse_test \
|
fmouse_test \
|
||||||
fkeyboard_test \
|
fkeyboard_test \
|
||||||
|
fterm_functions_test \
|
||||||
ftermdata_test \
|
ftermdata_test \
|
||||||
|
ftermbuffer_test \
|
||||||
ftermdetection_test \
|
ftermdetection_test \
|
||||||
ftermcapquirks_test \
|
ftermcapquirks_test \
|
||||||
ftermlinux_test \
|
ftermlinux_test \
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,848 @@
|
||||||
|
/***********************************************************************
|
||||||
|
* ftermbuffer-test.cpp - FTermBuffer unit tests *
|
||||||
|
* *
|
||||||
|
* This file is part of the FINAL CUT widget toolkit *
|
||||||
|
* *
|
||||||
|
* Copyright 2021 Markus Gans *
|
||||||
|
* *
|
||||||
|
* FINAL CUT is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU Lesser General Public License as *
|
||||||
|
* published by the Free Software Foundation; either version 3 of *
|
||||||
|
* the License, or (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* FINAL CUT 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 Lesser General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU Lesser General Public *
|
||||||
|
* License along with this program. If not, see *
|
||||||
|
* <http://www.gnu.org/licenses/>. *
|
||||||
|
***********************************************************************/
|
||||||
|
#include <wchar.h>
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
#include <cppunit/BriefTestProgressListener.h>
|
||||||
|
#include <cppunit/CompilerOutputter.h>
|
||||||
|
#include <cppunit/extensions/HelperMacros.h>
|
||||||
|
#include <cppunit/TestFixture.h>
|
||||||
|
#include <cppunit/TestResult.h>
|
||||||
|
#include <cppunit/TestResultCollector.h>
|
||||||
|
#include <cppunit/TestRunner.h>
|
||||||
|
|
||||||
|
#include <final/final.h>
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
// class FTermBufferTest
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
class FTermBufferTest : public CPPUNIT_NS::TestFixture
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FTermBufferTest()
|
||||||
|
{
|
||||||
|
std::setlocale (LC_CTYPE, "en_US.UTF-8");
|
||||||
|
fwide(stdout, 1); // Makes stream wide-character oriented
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void classNameTest();
|
||||||
|
void noArgumentTest();
|
||||||
|
void writeTest();
|
||||||
|
void streamTest();
|
||||||
|
void combiningCharacterTest();
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Adds code needed to register the test suite
|
||||||
|
CPPUNIT_TEST_SUITE (FTermBufferTest);
|
||||||
|
|
||||||
|
// Add a methods to the test suite
|
||||||
|
CPPUNIT_TEST (classNameTest);
|
||||||
|
CPPUNIT_TEST (noArgumentTest);
|
||||||
|
CPPUNIT_TEST (writeTest);
|
||||||
|
CPPUNIT_TEST (streamTest);
|
||||||
|
CPPUNIT_TEST (combiningCharacterTest);
|
||||||
|
|
||||||
|
// End of test suite definition
|
||||||
|
CPPUNIT_TEST_SUITE_END();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
void FTermBufferTest::classNameTest()
|
||||||
|
{
|
||||||
|
const finalcut::FTermBuffer s;
|
||||||
|
const finalcut::FString& classname = s.getClassName();
|
||||||
|
CPPUNIT_ASSERT ( classname == "FTermBuffer" );
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
void FTermBufferTest::noArgumentTest()
|
||||||
|
{
|
||||||
|
const finalcut::FTermBuffer term_buf{};
|
||||||
|
CPPUNIT_ASSERT ( term_buf.isEmpty() );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getLength() == 0 );
|
||||||
|
std::vector<finalcut::FChar> data{};
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer() == data );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer().size() == 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.begin() == term_buf.end() );
|
||||||
|
CPPUNIT_ASSERT ( finalcut::UNICODE_MAX == 5 );
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
void FTermBufferTest::writeTest()
|
||||||
|
{
|
||||||
|
const auto& data = finalcut::FTerm::getFTermData();
|
||||||
|
data->setTermEncoding (finalcut::Encoding::UTF8);
|
||||||
|
finalcut::FTermBuffer term_buf{};
|
||||||
|
|
||||||
|
// Write wchar_t
|
||||||
|
const wchar_t wch{L'\U0000263a'}; // ☺
|
||||||
|
term_buf.write(wch);
|
||||||
|
CPPUNIT_ASSERT ( ! term_buf.isEmpty() );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getLength() == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer().size() == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.begin() + 1 == term_buf.end() );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().ch[0] == L'☺' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().ch[2] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().ch[3] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().ch[4] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().encoded_char[0] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().encoded_char[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().encoded_char[2] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().encoded_char[3] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().encoded_char[4] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().fg_color == 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().bg_color == 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().attr.byte[0] == 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().attr.byte[1] == 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().attr.byte[2] != 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().attr.byte[3] == 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().attr.bit.char_width == 1 );
|
||||||
|
term_buf.front().attr.bit.char_width = 0;
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().attr.byte[2] == 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.toString() == finalcut::FString(wch) );
|
||||||
|
|
||||||
|
// Clear after write
|
||||||
|
term_buf.clear();
|
||||||
|
CPPUNIT_ASSERT ( term_buf.isEmpty() );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getLength() == 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer().size() == 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.begin() == term_buf.end() );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.toString() == finalcut::FString() );
|
||||||
|
|
||||||
|
// Write char
|
||||||
|
const char ch{'@'};
|
||||||
|
term_buf.write(ch);
|
||||||
|
CPPUNIT_ASSERT ( ! term_buf.isEmpty() );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getLength() == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer().size() == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.begin() + 1 == term_buf.end() );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().ch[0] == L'@' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().ch[2] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().ch[3] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().ch[4] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().encoded_char[0] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().encoded_char[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().encoded_char[2] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().encoded_char[3] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().encoded_char[4] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().fg_color == 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().bg_color == 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().attr.byte[0] == 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().attr.byte[1] == 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().attr.byte[2] != 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().attr.byte[3] == 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().attr.bit.char_width == 1 );
|
||||||
|
term_buf.front().attr.bit.char_width = 0;
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().attr.byte[2] == 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.toString() == finalcut::FString(ch) );
|
||||||
|
|
||||||
|
// Write FString
|
||||||
|
const finalcut::FString str = "abc…xyz";
|
||||||
|
term_buf.clear();
|
||||||
|
term_buf.write(str);
|
||||||
|
CPPUNIT_ASSERT ( ! term_buf.isEmpty() );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getLength() == 7 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer().size() == 7 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.begin() + 7 == term_buf.end() );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[0].ch[0] == L'a' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[1].ch[0] == L'b' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[2].ch[0] == L'c' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[3].ch[0] == L'…' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[4].ch[0] == L'x' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[5].ch[0] == L'y' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[6].ch[0] == L'z' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[0].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[1].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[2].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[3].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[4].attr.bit.char_width == 2 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[5].attr.bit.char_width == 2 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[6].attr.bit.char_width == 2 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.toString() == str );
|
||||||
|
|
||||||
|
for (std::size_t i{0}; i < 7; i++)
|
||||||
|
{
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].ch[2] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].ch[3] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].ch[4] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].encoded_char[0] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].encoded_char[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].encoded_char[2] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].encoded_char[3] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].encoded_char[4] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].fg_color == 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].bg_color == 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].attr.byte[0] == 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].attr.byte[1] == 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].attr.byte[2] != 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].attr.byte[3] == 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write formatted output
|
||||||
|
term_buf.clear();
|
||||||
|
term_buf.writef ("%'.2f%C", 0.25 * 7.0, L'£');
|
||||||
|
CPPUNIT_ASSERT ( ! term_buf.isEmpty() );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getLength() == 5 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer().size() == 5 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.begin() + 5 == term_buf.end() );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[0].ch[0] == L'1' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[1].ch[0] == L'.' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[2].ch[0] == L'7' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[3].ch[0] == L'5' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[4].ch[0] == L'£' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.toString() == "1.75£" );
|
||||||
|
|
||||||
|
for (std::size_t i{0}; i < 5; i++)
|
||||||
|
{
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].ch[2] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].ch[3] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].ch[4] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].encoded_char[0] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].encoded_char[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].encoded_char[2] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].encoded_char[3] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].encoded_char[4] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].fg_color == 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].bg_color == 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].attr.byte[0] == 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].attr.byte[1] == 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].attr.byte[2] != 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].attr.byte[3] == 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].attr.bit.char_width == 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write with color
|
||||||
|
term_buf.clear();
|
||||||
|
finalcut::FVTerm::setColor(finalcut::FColor::Default, finalcut::FColor::Default);
|
||||||
|
term_buf.write (L'♥');
|
||||||
|
auto color_pair = finalcut::FColorPair(finalcut::FColor::DarkRed, finalcut::FColor::Yellow4);
|
||||||
|
term_buf.write (color_pair);
|
||||||
|
term_buf.write (L'☺');
|
||||||
|
finalcut::FVTerm::setNormal();
|
||||||
|
term_buf.write ("♪");
|
||||||
|
color_pair = finalcut::FColorPair(finalcut::FColor::Black, finalcut::FColor::White);
|
||||||
|
term_buf.write (color_pair);
|
||||||
|
term_buf.write ("↑");
|
||||||
|
CPPUNIT_ASSERT ( ! term_buf.isEmpty() );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getLength() == 4 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer().size() == 4 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.begin() + 4 == term_buf.end() );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[0].ch[0] == L'♥' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[1].ch[0] == L'☺' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[2].ch[0] == L'♪' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[3].ch[0] == L'↑' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[0].fg_color == finalcut::FColor::Default );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[0].bg_color == finalcut::FColor::Default );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[1].fg_color == finalcut::FColor::DarkRed );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[1].bg_color == finalcut::FColor::Yellow4 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[2].fg_color == finalcut::FColor::Default );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[2].bg_color == finalcut::FColor::Default );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[3].fg_color == finalcut::FColor::Black );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[3].bg_color == finalcut::FColor::White );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.toString() == "♥☺♪↑" );
|
||||||
|
|
||||||
|
for (std::size_t i{0}; i < 4; i++)
|
||||||
|
{
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].ch[2] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].ch[3] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].ch[4] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].encoded_char[0] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].encoded_char[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].encoded_char[2] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].encoded_char[3] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].encoded_char[4] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].attr.byte[0] == 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].attr.byte[1] == 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].attr.byte[2] != 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].attr.byte[3] == 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].attr.bit.char_width == 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write with style
|
||||||
|
term_buf.clear();
|
||||||
|
auto style = finalcut::FStyle(finalcut::Style::Italic | finalcut::Style::Reverse);
|
||||||
|
term_buf.write (style);
|
||||||
|
CPPUNIT_ASSERT ( uInt(style.getStyle()) == uInt(finalcut::FVTerm::getAttribute().attr.byte[0]) );
|
||||||
|
term_buf.write (L'☕');
|
||||||
|
term_buf.write ( finalcut::FStyle(finalcut::Style::None) ); // Reset style
|
||||||
|
style = finalcut::FStyle(finalcut::Style::Bold | finalcut::Style::Underline);
|
||||||
|
term_buf.write (style);
|
||||||
|
term_buf.write (L'⛄');
|
||||||
|
term_buf.write ( finalcut::FStyle(finalcut::Style::Transparent) );
|
||||||
|
term_buf.write (L'🧸');
|
||||||
|
term_buf.write ( finalcut::FStyle(finalcut::Style::None) ); // Reset style
|
||||||
|
term_buf.write (L'🦡');
|
||||||
|
CPPUNIT_ASSERT ( ! term_buf.isEmpty() );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getLength() == 4 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer().size() == 4 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.begin() + 4 == term_buf.end() );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[0].ch[0] == L'☕' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[0].attr.bit.italic == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[0].attr.bit.reverse == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[0].attr.byte[0] != 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[0].attr.byte[1] == 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[1].ch[0] == L'⛄' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[1].attr.bit.bold == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[1].attr.bit.underline == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[1].attr.byte[0] != 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[1].attr.byte[1] == 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[2].ch[0] == L'🧸' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[2].attr.bit.bold == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[2].attr.bit.underline == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[2].attr.bit.transparent == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[2].attr.byte[0] != 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[2].attr.byte[1] != 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[3].ch[0] == L'🦡' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[3].attr.bit.bold == 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[3].attr.bit.underline == 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[3].attr.bit.transparent == 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[3].attr.byte[0] == 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[3].attr.byte[1] == 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.toString() == "☕⛄🧸🦡" );
|
||||||
|
|
||||||
|
for (std::size_t i{0}; i < 3; i++)
|
||||||
|
{
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].ch[2] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].ch[3] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].ch[4] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].encoded_char[0] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].encoded_char[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].encoded_char[2] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].encoded_char[3] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].encoded_char[4] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].attr.byte[2] != 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].attr.byte[3] == 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].attr.bit.char_width == 2 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
void FTermBufferTest::streamTest()
|
||||||
|
{
|
||||||
|
const auto& data = finalcut::FTerm::getFTermData();
|
||||||
|
data->setTermEncoding (finalcut::Encoding::UTF8);
|
||||||
|
finalcut::FTermBuffer::FCharVector fchar_vec = { finalcut::FChar{} };
|
||||||
|
CPPUNIT_ASSERT ( fchar_vec.size() == 1 );
|
||||||
|
fchar_vec.front().ch[0] = L'🥨';
|
||||||
|
fchar_vec.front().fg_color = finalcut::FColor::White;
|
||||||
|
fchar_vec.front().bg_color = finalcut::FColor::Cyan;
|
||||||
|
finalcut::addColumnWidth(fchar_vec.front());
|
||||||
|
finalcut::FTermBuffer term_buf{};
|
||||||
|
term_buf.write() << L'a'
|
||||||
|
<< finalcut::FColorPair{finalcut::FColor::Yellow, finalcut::FColor::Blue}
|
||||||
|
<< 1
|
||||||
|
<< finalcut::FColorPair{finalcut::FColor::Cyan, finalcut::FColor::White}
|
||||||
|
<< finalcut::FStyle(finalcut::Style::Dim)
|
||||||
|
<< finalcut::UniChar::NF_Bullet
|
||||||
|
<< finalcut::FStyle(finalcut::Style::Blink)
|
||||||
|
<< fchar_vec
|
||||||
|
<< std::string("🧭")
|
||||||
|
<< finalcut::FStyle(finalcut::Style::None)
|
||||||
|
<< finalcut::FStyle(finalcut::Style::DoubleUnderline)
|
||||||
|
<< finalcut::FColorPair{finalcut::FColor::Black, finalcut::FColor::White}
|
||||||
|
<< std::wstring(L"🚴");
|
||||||
|
|
||||||
|
CPPUNIT_ASSERT ( ! term_buf.isEmpty() );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getLength() == 6 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer().size() == 6 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.begin() + 6 == term_buf.end() );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[0].ch[0] == L'a' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[0].fg_color == finalcut::FColor::Default );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[0].bg_color == finalcut::FColor::Default );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[0].attr.byte[0] == 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[0].attr.byte[1] == 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[0].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[1].ch[0] == L'1' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[1].fg_color == finalcut::FColor::Yellow );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[1].bg_color == finalcut::FColor::Blue );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[1].attr.byte[0] == 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[1].attr.byte[1] == 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[1].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[2].ch[0] == L'\U0000e1f9' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[2].fg_color == finalcut::FColor::Cyan );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[2].bg_color == finalcut::FColor::White );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[2].attr.bit.dim == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[2].attr.byte[0] != 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[2].attr.byte[1] == 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[2].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[3].ch[0] == L'🥨' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[3].fg_color == finalcut::FColor::White );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[3].bg_color == finalcut::FColor::Cyan );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[3].attr.byte[0] == 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[3].attr.byte[1] == 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[3].attr.bit.char_width == 2 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[4].ch[0] == L'🧭' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[4].fg_color == finalcut::FColor::Cyan );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[4].bg_color == finalcut::FColor::White );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[4].attr.bit.dim == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[4].attr.bit.blink == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[4].attr.byte[0] != 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[4].attr.byte[1] == 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[4].attr.bit.char_width == 2 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[5].ch[0] == L'🚴' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[5].fg_color == finalcut::FColor::Black );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[5].bg_color == finalcut::FColor::White );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[5].attr.bit.dbl_underline == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[5].attr.byte[0] == 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[5].attr.byte[1] != 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[5].attr.bit.char_width == 2 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.toString() == "a1\U0000e1f9🥨🧭🚴" );
|
||||||
|
|
||||||
|
for (std::size_t i{0}; i < 6; i++)
|
||||||
|
{
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].ch[2] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].ch[3] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].ch[4] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].encoded_char[0] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].encoded_char[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].encoded_char[2] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].encoded_char[3] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].encoded_char[4] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].attr.byte[2] != 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[i].attr.byte[3] == 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
void FTermBufferTest::combiningCharacterTest()
|
||||||
|
{
|
||||||
|
const auto& data = finalcut::FTerm::getFTermData();
|
||||||
|
data->setTermEncoding (finalcut::Encoding::UTF8);
|
||||||
|
finalcut::FTermBuffer term_buf{};
|
||||||
|
// Skip leading zero-width characters
|
||||||
|
std::wstring combining = L"\U00000323\U00000300\U0000ff2f\n"; // [] [] O [NL]
|
||||||
|
term_buf.write(combining);
|
||||||
|
CPPUNIT_ASSERT ( ! term_buf.isEmpty() );
|
||||||
|
CPPUNIT_ASSERT ( combining.length() == 4 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[0]) == 0 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[1]) == 0 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[2]) == 2 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[3]) == -1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getLength() == 2 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer().size() == 2 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.begin() != term_buf.end() );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().ch[0] == L'O' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().ch[2] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().ch[3] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().ch[4] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().attr.bit.char_width == 2 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.back().ch[0] == L'\012' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.back().ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.back().ch[2] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.back().ch[3] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.back().ch[4] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.back().attr.bit.char_width == 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.toString() != combining );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.toString() == L"O\012" );
|
||||||
|
|
||||||
|
// Characters with separate and with combined diacritical marks
|
||||||
|
combining = L"u\U00000300=\U000000f9"; // u ` = ù
|
||||||
|
term_buf.clear();
|
||||||
|
term_buf.write(combining);
|
||||||
|
CPPUNIT_ASSERT ( ! term_buf.isEmpty() );
|
||||||
|
CPPUNIT_ASSERT ( combining.length() == 4 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[0]) == 1 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[1]) == 0 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[2]) == 1 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[3]) == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getLength() == 3 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer().size() == 3 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.begin() != term_buf.end() );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().ch[0] == L'u' );
|
||||||
|
CPPUNIT_ASSERT ( int(term_buf.front().ch[1]) == 0x300 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().ch[2] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[0].ch[0] == L'u' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[0].ch[1] == L'\U00000300' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[0].ch[2] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[1].ch[0] == L'=' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[1].ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[2].ch[0] == L'ù' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[2].ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[0].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[1].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[2].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.back().ch[0] == L'ù' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.back().ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.toString() == combining );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.toString() == L"ù=ù" );
|
||||||
|
|
||||||
|
combining = L"o\U0000031b\U00000323=\U00001ee3"; // o ̛ ̣ = ợ
|
||||||
|
term_buf.clear();
|
||||||
|
term_buf.write(combining);
|
||||||
|
CPPUNIT_ASSERT ( combining.length() == 5 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[0]) == 1 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[1]) == 0 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[2]) == 0 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[3]) == 1 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[4]) == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getLength() == 3 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer().size() == 3 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.begin() != term_buf.end() );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().ch[0] == L'o' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().ch[1] == L'\U0000031b' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().ch[2] == L'\U00000323' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().ch[3] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[0].ch[0] == L'o' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[0].ch[1] == L'\U0000031b' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[0].ch[2] == L'\U00000323' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[0].ch[3] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[1].ch[0] == L'=' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[1].ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[2].ch[0] == L'ợ' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[2].ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[0].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[1].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[2].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.back().ch[0] == L'ợ' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.back().ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.toString() == combining );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.toString() == L"ợ=ợ" );
|
||||||
|
|
||||||
|
// Too many combination characters
|
||||||
|
combining = L"v" \
|
||||||
|
L"\U00000300\U0000032e\U00000368" \
|
||||||
|
L"\U00000364\U00000348\U0000034b"; // v ̀ ̮ ͨ ͤ ͈ ͋
|
||||||
|
term_buf.clear();
|
||||||
|
term_buf << combining;
|
||||||
|
CPPUNIT_ASSERT ( combining.length() == 7 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[0]) == 1 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[1]) == 0 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[2]) == 0 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[3]) == 0 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[4]) == 0 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[5]) == 0 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[6]) == 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getLength() == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer().size() == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.begin() != term_buf.end() );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front() == term_buf.back() );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().ch[0] == L'v' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().ch[1] == L'\U00000300' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().ch[2] == L'\U0000032e' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().ch[3] == L'\U00000368' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().ch[4] == L'\U00000364' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[0].ch[0] == L'v' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[0].ch[1] == L'\U00000300' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[0].ch[2] == L'\U0000032e' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[0].ch[3] == L'\U00000368' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[0].ch[4] == L'\U00000364' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[0].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.back().ch[0] == L'v' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.back().ch[1] == L'\U00000300' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.back().ch[2] == L'\U0000032e' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.back().ch[3] == L'\U00000368' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.back().ch[4] == L'\U00000364' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.toString() != combining );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.toString() == L"v̮̀ͨͤ" );
|
||||||
|
|
||||||
|
// Ignore trailing uncombined zero-width characters
|
||||||
|
combining = L"a\t\U00000300\U00000323"; // a [Tab] [] []
|
||||||
|
term_buf.clear();
|
||||||
|
term_buf.write(combining);
|
||||||
|
CPPUNIT_ASSERT ( combining.length() == 4 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[0]) == 1 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[1]) == -1 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[2]) == 0 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[3]) == 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getLength() == 2 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer().size() == 2 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.begin() != term_buf.end() );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().ch[0] == L'a' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[0].ch[0] == L'a' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[0].ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[1].ch[0] == L'\t' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[1].ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[0].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[1].attr.bit.char_width == 0 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.back().ch[0] == L'\t' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.back().ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.toString() != combining );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.toString() == L"a\t" );
|
||||||
|
|
||||||
|
// Thai (ISO 10646-1 - UCS implementation level 2)
|
||||||
|
combining = L"๏ แผ่นดินฮั่นเสื่อมโทรมแสนสังเวช";
|
||||||
|
term_buf.clear();
|
||||||
|
term_buf.write(combining);
|
||||||
|
CPPUNIT_ASSERT ( combining.length() == 32 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[0]) == 1 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[1]) == 1 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[2]) == 1 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[3]) == 1 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[4]) == 0 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[5]) == 1 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[6]) == 1 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[7]) == 0 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[8]) == 1 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[9]) == 1 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[10]) == 0 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[11]) == 0 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[12]) == 1 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[13]) == 1 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[14]) == 1 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[15]) == 0 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[16]) == 0 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[17]) == 1 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[18]) == 1 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[19]) == 1 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[20]) == 1 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[21]) == 1 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[22]) == 1 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[23]) == 1 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[24]) == 1 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[25]) == 1 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[26]) == 1 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[27]) == 0 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[28]) == 1 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[29]) == 1 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[30]) == 1 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[31]) == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getLength() == 25 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer().size() == 25 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.begin() != term_buf.end() );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().ch[0] == L'๏' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[0].ch[0] == L'\U00000e4f' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[0].ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[1].ch[0] == L' ' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[1].ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[2].ch[0] == L'\U00000e41' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[2].ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[3].ch[0] == L'\U00000e1c' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[3].ch[1] == L'\U00000e48' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[3].ch[2] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[4].ch[0] == L'\U00000e19' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[4].ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[5].ch[0] == L'\U00000e14' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[5].ch[1] == L'\U00000e34' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[5].ch[2] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[6].ch[0] == L'\U00000e19' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[6].ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[7].ch[0] == L'\U00000e2e' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[7].ch[1] == L'\U00000e31' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[7].ch[2] == L'\U00000e48' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[7].ch[3] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[8].ch[0] == L'\U00000e19' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[8].ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[9].ch[0] == L'\U00000e40' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[9].ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[10].ch[0] == L'\U00000e2a' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[10].ch[1] == L'\U00000e37' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[10].ch[2] == L'\U00000e48' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[10].ch[3] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[11].ch[0] == L'\U00000e2d' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[11].ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[12].ch[0] == L'\U00000e21' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[12].ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[13].ch[0] == L'\U00000e42' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[13].ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[14].ch[0] == L'\U00000e17' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[14].ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[15].ch[0] == L'\U00000e23' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[15].ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[16].ch[0] == L'\U00000e21' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[16].ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[17].ch[0] == L'\U00000e41' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[17].ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[18].ch[0] == L'\U00000e2a' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[18].ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[19].ch[0] == L'\U00000e19' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[19].ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[20].ch[0] == L'\U00000e2a' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[20].ch[1] == L'\U00000e31' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[20].ch[2] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[21].ch[0] == L'\U00000e07' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[21].ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[22].ch[0] == L'\U00000e40' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[22].ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[23].ch[0] == L'\U00000e27' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[23].ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[24].ch[0] == L'\U00000e0a' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[24].ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[0].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[1].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[2].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[3].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[4].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[5].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[6].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[7].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[8].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[9].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[10].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[11].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[12].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[13].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[14].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[15].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[16].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[17].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[18].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[19].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[20].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[21].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[22].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[23].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[24].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.back().ch[0] == L'ช' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.back().ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.toString() == combining );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.toString() == L"๏ แผ่นดินฮั่นเสื่อมโทรมแสนสังเวช" );
|
||||||
|
|
||||||
|
// Devanagari script (ISO 10646-1 - UCS implementation level 2)
|
||||||
|
combining = L"पन्ह पन्ह त्र र्च कृकृ ड्ड न्ह";
|
||||||
|
term_buf.clear();
|
||||||
|
term_buf.write(combining);
|
||||||
|
CPPUNIT_ASSERT ( combining.length() == 30 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[0]) == 1 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[1]) == 1 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[2]) == 0 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[3]) == 1 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[4]) == 1 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[5]) == 1 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[6]) == 1 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[7]) == 0 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[8]) == 1 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[9]) == 1 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[10]) == 1 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[11]) == 0 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[12]) == 1 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[13]) == 1 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[14]) == 1 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[15]) == 0 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[16]) == 1 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[17]) == 1 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[18]) == 1 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[19]) == 0 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[20]) == 1 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[21]) == 0 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[22]) == 1 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[23]) == 1 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[24]) == 0 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[25]) == 1 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[26]) == 1 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[27]) == 1 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[28]) == 0 );
|
||||||
|
CPPUNIT_ASSERT ( wcwidth(combining[29]) == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getLength() == 22 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer().size() == 22 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.begin() != term_buf.end() );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().ch[0] == L'\U0000092a' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.front().ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[0].ch[0] == L'\U0000092a' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[0].ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[1].ch[0] == L'\U00000928' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[1].ch[1] == L'\U0000094d' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[1].ch[2] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[2].ch[0] == L'\U00000939' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[2].ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[3].ch[0] == L' ' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[3].ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[4].ch[0] == L'\U0000092a' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[4].ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[5].ch[0] == L'\U00000928' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[5].ch[1] == L'\U0000094d' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[5].ch[2] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[6].ch[0] == L'\U00000939' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[6].ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[7].ch[0] == L' ' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[7].ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[8].ch[0] == L'\U00000924' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[8].ch[1] == L'\U0000094d' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[8].ch[2] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[9].ch[0] == L'\U00000930' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[9].ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[10].ch[0] == L' ' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[10].ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[11].ch[0] == L'\U00000930' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[11].ch[1] == L'\U0000094d' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[11].ch[2] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[12].ch[0] == L'\U0000091a' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[12].ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[13].ch[0] == L' ' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[13].ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[14].ch[0] == L'\U00000915' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[14].ch[1] == L'\U00000943' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[14].ch[2] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[15].ch[0] == L'\U00000915' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[15].ch[1] == L'\U00000943' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[15].ch[2] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[16].ch[0] == L' ' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[16].ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[17].ch[0] == L'\U00000921' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[17].ch[1] == L'\U0000094d' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[17].ch[2] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[18].ch[0] == L'\U00000921' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[18].ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[19].ch[0] == L' ' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[19].ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[20].ch[0] == L'\U00000928' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[20].ch[1] == L'\U0000094d' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[20].ch[2] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[21].ch[0] == L'\U00000939' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[21].ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[0].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[1].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[2].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[3].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[4].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[5].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[6].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[7].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[8].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[9].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[10].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[11].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[12].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[13].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[14].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[15].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[16].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[17].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[18].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[19].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[20].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.getBuffer()[21].attr.bit.char_width == 1 );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.back().ch[0] == L'\U00000939' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.back().ch[1] == L'\0' );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.toString() == combining );
|
||||||
|
CPPUNIT_ASSERT ( term_buf.toString() == L"पन्ह पन्ह त्र र्च कृकृ ड्ड न्ह" );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Put the test suite in the registry
|
||||||
|
CPPUNIT_TEST_SUITE_REGISTRATION (FTermBufferTest);
|
||||||
|
|
||||||
|
// The general unit test main part
|
||||||
|
#include <main-test.inc>
|
Loading…
Reference in New Issue