Adding an ANSI X3.64 SGR optimizer
This commit is contained in:
parent
853799b4d6
commit
d126c4996a
|
@ -1,3 +1,8 @@
|
||||||
|
2019-12-31 Markus Gans <guru.mail@muenster.de>
|
||||||
|
* The new SGRoptimizer class allows several consecutive parameters
|
||||||
|
from the SGR (Select Graphic Rendition) attributes to be combined
|
||||||
|
into one
|
||||||
|
|
||||||
2019-12-23 Markus Gans <guru.mail@muenster.de>
|
2019-12-23 Markus Gans <guru.mail@muenster.de>
|
||||||
* Correction for height and width alignment in adjustSize()
|
* Correction for height and width alignment in adjustSize()
|
||||||
* Better setSize() implementation in some widgets
|
* Better setSize() implementation in some widgets
|
||||||
|
|
|
@ -127,10 +127,13 @@ Background::Background (finalcut::FWidget* parent)
|
||||||
blue.setValue (0xec);
|
blue.setValue (0xec);
|
||||||
|
|
||||||
// Set the initial palette values
|
// Set the initial palette values
|
||||||
|
if ( finalcut::FTerm::canChangeColorPalette() )
|
||||||
|
{
|
||||||
finalcut::FTerm::setPalette ( finalcut::fc::LightMagenta
|
finalcut::FTerm::setPalette ( finalcut::fc::LightMagenta
|
||||||
, int(red.getValue())
|
, int(red.getValue())
|
||||||
, int(green.getValue())
|
, int(green.getValue())
|
||||||
, int(blue.getValue()) );
|
, int(blue.getValue()) );
|
||||||
|
}
|
||||||
|
|
||||||
// Quit button
|
// Quit button
|
||||||
quit.setGeometry(FPoint(19, 8), FSize(10, 1));
|
quit.setGeometry(FPoint(19, 8), FSize(10, 1));
|
||||||
|
@ -168,6 +171,9 @@ Background::~Background() // destructor
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
void Background::cb_changed (finalcut::FWidget*, FDataPtr)
|
void Background::cb_changed (finalcut::FWidget*, FDataPtr)
|
||||||
{
|
{
|
||||||
|
if ( ! finalcut::FTerm::canChangeColorPalette() )
|
||||||
|
return;
|
||||||
|
|
||||||
finalcut::FTerm::setPalette ( finalcut::fc::LightMagenta
|
finalcut::FTerm::setPalette ( finalcut::fc::LightMagenta
|
||||||
, int(red.getValue())
|
, int(red.getValue())
|
||||||
, int(green.getValue())
|
, int(green.getValue())
|
||||||
|
@ -179,6 +185,9 @@ void Background::cb_changed (finalcut::FWidget*, FDataPtr)
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
void Background::cb_choice (finalcut::FWidget*, FDataPtr)
|
void Background::cb_choice (finalcut::FWidget*, FDataPtr)
|
||||||
{
|
{
|
||||||
|
if ( ! finalcut::FTerm::canChangeColorPalette() )
|
||||||
|
return;
|
||||||
|
|
||||||
uChar r{}, g{}, b{};
|
uChar r{}, g{}, b{};
|
||||||
FDataPtr data_ptr = color_choice.getItemData();
|
FDataPtr data_ptr = color_choice.getItemData();
|
||||||
RGB* rgb = reinterpret_cast<RGB*>(data_ptr);
|
RGB* rgb = reinterpret_cast<RGB*>(data_ptr);
|
||||||
|
@ -202,7 +211,10 @@ void Background::cb_choice (finalcut::FWidget*, FDataPtr)
|
||||||
int main (int argc, char* argv[])
|
int main (int argc, char* argv[])
|
||||||
{
|
{
|
||||||
finalcut::FApplication app(argc, argv);
|
finalcut::FApplication app(argc, argv);
|
||||||
|
|
||||||
|
if ( finalcut::FTerm::canChangeColorPalette() )
|
||||||
app.setBackgroundColor(finalcut::fc::LightMagenta);
|
app.setBackgroundColor(finalcut::fc::LightMagenta);
|
||||||
|
|
||||||
Background dialog(&app);
|
Background dialog(&app);
|
||||||
app.setMainWidget(&dialog);
|
app.setMainWidget(&dialog);
|
||||||
dialog.show();
|
dialog.show();
|
||||||
|
|
|
@ -62,6 +62,7 @@ libfinal_la_SOURCES = \
|
||||||
ftextview.cpp \
|
ftextview.cpp \
|
||||||
fvterm.cpp \
|
fvterm.cpp \
|
||||||
fevent.cpp \
|
fevent.cpp \
|
||||||
|
sgr_optimizer.cpp \
|
||||||
foptiattr.cpp \
|
foptiattr.cpp \
|
||||||
foptimove.cpp \
|
foptimove.cpp \
|
||||||
ftermbuffer.cpp \
|
ftermbuffer.cpp \
|
||||||
|
@ -111,6 +112,7 @@ finalcutinclude_HEADERS = \
|
||||||
include/final/fobject.h \
|
include/final/fobject.h \
|
||||||
include/final/fpoint.h \
|
include/final/fpoint.h \
|
||||||
include/final/fsize.h \
|
include/final/fsize.h \
|
||||||
|
include/final/sgr_optimizer.h \
|
||||||
include/final/foptiattr.h \
|
include/final/foptiattr.h \
|
||||||
include/final/foptimove.h \
|
include/final/foptimove.h \
|
||||||
include/final/ftermbuffer.h \
|
include/final/ftermbuffer.h \
|
||||||
|
|
|
@ -31,6 +31,7 @@ INCLUDE_HEADERS = \
|
||||||
fcheckmenuitem.h \
|
fcheckmenuitem.h \
|
||||||
fmessagebox.h \
|
fmessagebox.h \
|
||||||
ftooltip.h \
|
ftooltip.h \
|
||||||
|
sgr_optimizer.h \
|
||||||
foptiattr.h \
|
foptiattr.h \
|
||||||
foptimove.h \
|
foptimove.h \
|
||||||
ftermbuffer.h \
|
ftermbuffer.h \
|
||||||
|
@ -132,6 +133,7 @@ OBJS = \
|
||||||
ftermopenbsd.o \
|
ftermopenbsd.o \
|
||||||
ftermlinux.o \
|
ftermlinux.o \
|
||||||
fvterm.o \
|
fvterm.o \
|
||||||
|
sgr_optimizer.o \
|
||||||
foptiattr.o \
|
foptiattr.o \
|
||||||
foptimove.o \
|
foptimove.o \
|
||||||
ftermbuffer.o \
|
ftermbuffer.o \
|
||||||
|
|
|
@ -31,6 +31,7 @@ INCLUDE_HEADERS = \
|
||||||
fcheckmenuitem.h \
|
fcheckmenuitem.h \
|
||||||
fmessagebox.h \
|
fmessagebox.h \
|
||||||
ftooltip.h \
|
ftooltip.h \
|
||||||
|
sgr_optimizer.h \
|
||||||
foptiattr.h \
|
foptiattr.h \
|
||||||
foptimove.h \
|
foptimove.h \
|
||||||
ftermbuffer.h \
|
ftermbuffer.h \
|
||||||
|
@ -132,6 +133,7 @@ OBJS = \
|
||||||
ftermopenbsd.o \
|
ftermopenbsd.o \
|
||||||
ftermlinux.o \
|
ftermlinux.o \
|
||||||
fvterm.o \
|
fvterm.o \
|
||||||
|
sgr_optimizer.o \
|
||||||
foptiattr.o \
|
foptiattr.o \
|
||||||
foptimove.o \
|
foptimove.o \
|
||||||
ftermbuffer.o \
|
ftermbuffer.o \
|
||||||
|
|
|
@ -320,6 +320,8 @@ void FApplication::showParameterUsage()
|
||||||
<< " Disable terminal detection\n"
|
<< " Disable terminal detection\n"
|
||||||
<< " --no-color-change "
|
<< " --no-color-change "
|
||||||
<< " Do not redefine the color palette\n"
|
<< " Do not redefine the color palette\n"
|
||||||
|
<< " --no-sgr-optimizer "
|
||||||
|
<< " Do not optimize SGR sequences\n"
|
||||||
<< " --vgafont "
|
<< " --vgafont "
|
||||||
<< " Set the standard vga 8x16 font\n"
|
<< " Set the standard vga 8x16 font\n"
|
||||||
<< " --newfont "
|
<< " --newfont "
|
||||||
|
@ -415,6 +417,7 @@ void FApplication::cmd_options (const int& argc, char* argv[])
|
||||||
{C_STR("no-optimized-cursor"), no_argument, 0, 0 },
|
{C_STR("no-optimized-cursor"), no_argument, 0, 0 },
|
||||||
{C_STR("no-terminal-detection"), no_argument, 0, 0 },
|
{C_STR("no-terminal-detection"), no_argument, 0, 0 },
|
||||||
{C_STR("no-color-change"), no_argument, 0, 0 },
|
{C_STR("no-color-change"), no_argument, 0, 0 },
|
||||||
|
{C_STR("no-sgr-optimizer"), no_argument, 0, 0 },
|
||||||
{C_STR("vgafont"), no_argument, 0, 0 },
|
{C_STR("vgafont"), no_argument, 0, 0 },
|
||||||
{C_STR("newfont"), no_argument, 0, 0 },
|
{C_STR("newfont"), no_argument, 0, 0 },
|
||||||
|
|
||||||
|
@ -469,6 +472,9 @@ void FApplication::cmd_options (const int& argc, char* argv[])
|
||||||
if ( std::strcmp(long_options[idx].name, "no-color-change") == 0 )
|
if ( std::strcmp(long_options[idx].name, "no-color-change") == 0 )
|
||||||
getStartOptions().color_change = false;
|
getStartOptions().color_change = false;
|
||||||
|
|
||||||
|
if ( std::strcmp(long_options[idx].name, "no-sgr-optimizer") == 0 )
|
||||||
|
getStartOptions().sgr_optimizer = false;
|
||||||
|
|
||||||
if ( std::strcmp(long_options[idx].name, "vgafont") == 0 )
|
if ( std::strcmp(long_options[idx].name, "vgafont") == 0 )
|
||||||
getStartOptions().vgafont = true;
|
getStartOptions().vgafont = true;
|
||||||
|
|
||||||
|
@ -819,7 +825,7 @@ void FApplication::closeDropDown()
|
||||||
{
|
{
|
||||||
// Close the open menu
|
// Close the open menu
|
||||||
|
|
||||||
if ( mouse && mouse->isMoved() )
|
if ( ! mouse || (mouse && mouse->isMoved()) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const auto& mouse_position = mouse->getPos();
|
const auto& mouse_position = mouse->getPos();
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
#include "final/fc.h"
|
#include "final/fc.h"
|
||||||
#include "final/foptiattr.h"
|
#include "final/foptiattr.h"
|
||||||
|
#include "final/fstartoptions.h"
|
||||||
|
|
||||||
namespace finalcut
|
namespace finalcut
|
||||||
{
|
{
|
||||||
|
@ -578,6 +579,9 @@ char* FOptiAttr::changeAttribute (FChar*& term, FChar*& next)
|
||||||
changeAttributeSeparately (term, next);
|
changeAttributeSeparately (term, next);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( FStartOptions::getFStartOptions().sgr_optimizer )
|
||||||
|
sgr_optimizer.optimize();
|
||||||
|
|
||||||
return attr_buf;
|
return attr_buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1651,14 +1655,12 @@ inline bool FOptiAttr::switchOff()
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
inline bool FOptiAttr::append_sequence (char seq[])
|
inline bool FOptiAttr::append_sequence (char seq[])
|
||||||
{
|
{
|
||||||
if ( seq )
|
if ( ! seq )
|
||||||
{
|
return false;
|
||||||
|
|
||||||
std::strncat (attr_ptr, seq, sizeof(attr_buf) - std::strlen(attr_ptr));
|
std::strncat (attr_ptr, seq, sizeof(attr_buf) - std::strlen(attr_ptr));
|
||||||
attr_buf[sizeof(attr_buf) - 1] = '\0';
|
attr_buf[sizeof(attr_buf) - 1] = '\0';
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace finalcut
|
} // namespace finalcut
|
||||||
|
|
|
@ -39,6 +39,7 @@ FStartOptions::FStartOptions()
|
||||||
, mouse_support{true}
|
, mouse_support{true}
|
||||||
, terminal_detection{true}
|
, terminal_detection{true}
|
||||||
, color_change{true}
|
, color_change{true}
|
||||||
|
, sgr_optimizer{true}
|
||||||
, vgafont{false}
|
, vgafont{false}
|
||||||
, newfont{false}
|
, newfont{false}
|
||||||
, encoding{fc::UNKNOWN}
|
, encoding{fc::UNKNOWN}
|
||||||
|
|
|
@ -201,9 +201,9 @@ void FTermcapQuirks::linux()
|
||||||
"%?%p4%t;5%;m"
|
"%?%p4%t;5%;m"
|
||||||
"%?%p9%t\016%e\017%;");
|
"%?%p9%t\016%e\017%;");
|
||||||
|
|
||||||
TCAP(fc::t_enter_alt_charset_mode) = C_STR("\016");
|
TCAP(fc::t_enter_alt_charset_mode) = C_STR(SO);
|
||||||
TCAP(fc::t_exit_alt_charset_mode) = C_STR("\017");
|
TCAP(fc::t_exit_alt_charset_mode) = C_STR(SI);
|
||||||
TCAP(fc::t_exit_attribute_mode) = C_STR(CSI "0m\017");
|
TCAP(fc::t_exit_attribute_mode) = C_STR(CSI "0m" SI);
|
||||||
TCAP(fc::t_exit_bold_mode) = C_STR(CSI "22m");
|
TCAP(fc::t_exit_bold_mode) = C_STR(CSI "22m");
|
||||||
TCAP(fc::t_exit_blink_mode) = C_STR(CSI "25m");
|
TCAP(fc::t_exit_blink_mode) = C_STR(CSI "25m");
|
||||||
TCAP(fc::t_exit_reverse_mode) = C_STR(CSI "27m");
|
TCAP(fc::t_exit_reverse_mode) = C_STR(CSI "27m");
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#define USE_FINAL_H
|
#define USE_FINAL_H
|
||||||
|
|
||||||
#include <final/emptyfstring.h>
|
#include <final/emptyfstring.h>
|
||||||
|
#include <final/sgr_optimizer.h>
|
||||||
#include <final/fkey_map.h>
|
#include <final/fkey_map.h>
|
||||||
#include <final/fapplication.h>
|
#include <final/fapplication.h>
|
||||||
#include <final/fbuttongroup.h>
|
#include <final/fbuttongroup.h>
|
||||||
|
|
|
@ -23,9 +23,9 @@
|
||||||
/* Standalone class
|
/* Standalone class
|
||||||
* ════════════════
|
* ════════════════
|
||||||
*
|
*
|
||||||
* ▕▔▔▔▔▔▔▔▔▔▔▔▏
|
* ▕▔▔▔▔▔▔▔▔▔▔▔▏1 1▕▔▔▔▔▔▔▔▔▔▔▔▔▔▔▏
|
||||||
* ▕ FOptiAttr ▏
|
* ▕ FOptiAttr ▏- - - -▕ SGRoptimizer ▏
|
||||||
* ▕▁▁▁▁▁▁▁▁▁▁▁▏
|
* ▕▁▁▁▁▁▁▁▁▁▁▁▏ ▕▁▁▁▁▁▁▁▁▁▁▁▁▁▁▏
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef FOPTIATTR_H
|
#ifndef FOPTIATTR_H
|
||||||
|
@ -59,6 +59,7 @@
|
||||||
#include <algorithm> // need for std::swap
|
#include <algorithm> // need for std::swap
|
||||||
|
|
||||||
#include "final/fstring.h"
|
#include "final/fstring.h"
|
||||||
|
#include "final/sgr_optimizer.h"
|
||||||
|
|
||||||
namespace finalcut
|
namespace finalcut
|
||||||
{
|
{
|
||||||
|
@ -180,6 +181,8 @@ class FOptiAttr final
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Typedefs and Enumerations
|
// Typedefs and Enumerations
|
||||||
|
typedef char attributebuffer[SGRoptimizer::ATTR_BUF_SIZE];
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
char* cap;
|
char* cap;
|
||||||
|
@ -320,10 +323,12 @@ class FOptiAttr final
|
||||||
FChar off{};
|
FChar off{};
|
||||||
FChar reset_byte_mask{};
|
FChar reset_byte_mask{};
|
||||||
|
|
||||||
|
SGRoptimizer sgr_optimizer{attr_buf};
|
||||||
|
|
||||||
int max_color{1};
|
int max_color{1};
|
||||||
int attr_without_color{0};
|
int attr_without_color{0};
|
||||||
char* attr_ptr{attr_buf};
|
char* attr_ptr{attr_buf};
|
||||||
char attr_buf[8192]{'\0'};
|
char attr_buf[SGRoptimizer::ATTR_BUF_SIZE]{'\0'};
|
||||||
bool ansi_default_color{false};
|
bool ansi_default_color{false};
|
||||||
bool alt_equal_pc_charset{false};
|
bool alt_equal_pc_charset{false};
|
||||||
bool monochron{true};
|
bool monochron{true};
|
||||||
|
|
|
@ -78,9 +78,10 @@ class FStartOptions final
|
||||||
uInt8 mouse_support : 1;
|
uInt8 mouse_support : 1;
|
||||||
uInt8 terminal_detection : 1;
|
uInt8 terminal_detection : 1;
|
||||||
uInt8 color_change : 1;
|
uInt8 color_change : 1;
|
||||||
|
uInt8 sgr_optimizer : 1;
|
||||||
uInt8 vgafont : 1;
|
uInt8 vgafont : 1;
|
||||||
uInt8 newfont : 1;
|
uInt8 newfont : 1;
|
||||||
uInt8 : 2; // padding bits
|
uInt8 : 1; // padding bits
|
||||||
fc::encoding encoding;
|
fc::encoding encoding;
|
||||||
|
|
||||||
#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(UNIT_TEST)
|
#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(UNIT_TEST)
|
||||||
|
|
|
@ -0,0 +1,93 @@
|
||||||
|
/***********************************************************************
|
||||||
|
* sgr_optimizer.h - Combines SGR (Select Graphic Rendition) attributes *
|
||||||
|
* *
|
||||||
|
* This file is part of the Final Cut widget toolkit *
|
||||||
|
* *
|
||||||
|
* Copyright 2019 Markus Gans *
|
||||||
|
* *
|
||||||
|
* The 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. *
|
||||||
|
* *
|
||||||
|
* The 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/>. *
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
/* Standalone class
|
||||||
|
* ════════════════
|
||||||
|
*
|
||||||
|
* ▕▔▔▔▔▔▔▔▔▔▔▔▔▔▔▏
|
||||||
|
* ▕ SGRoptimizer ▏
|
||||||
|
* ▕▁▁▁▁▁▁▁▁▁▁▁▁▁▁▏
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SGR_OPTIMIZER_H
|
||||||
|
#define SGR_OPTIMIZER_H
|
||||||
|
|
||||||
|
#if !defined (USE_FINAL_H) && !defined (COMPILE_FINAL_CUT)
|
||||||
|
#error "Only <final/final.h> can be included directly."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace finalcut
|
||||||
|
{
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
// class SGRoptimizer
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
class SGRoptimizer final
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// Constants
|
||||||
|
static constexpr std::size_t ATTR_BUF_SIZE{8192};
|
||||||
|
|
||||||
|
// Typedefs
|
||||||
|
typedef char attributebuffer[ATTR_BUF_SIZE];
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
SGRoptimizer (attributebuffer&);
|
||||||
|
|
||||||
|
// Destructor
|
||||||
|
virtual ~SGRoptimizer();
|
||||||
|
|
||||||
|
// Disable copy constructor
|
||||||
|
SGRoptimizer (const SGRoptimizer&) = delete;
|
||||||
|
|
||||||
|
// Disable assignment operator (=)
|
||||||
|
SGRoptimizer& operator = (const SGRoptimizer&) = delete;
|
||||||
|
|
||||||
|
// Method
|
||||||
|
void optimize();
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Constants
|
||||||
|
static constexpr std::size_t NOT_SET = static_cast<std::size_t>(-1);
|
||||||
|
|
||||||
|
// Methods
|
||||||
|
void findParameter();
|
||||||
|
void combineParameter();
|
||||||
|
|
||||||
|
// Data member
|
||||||
|
attributebuffer& seq;
|
||||||
|
|
||||||
|
struct parameter
|
||||||
|
{
|
||||||
|
std::size_t start;
|
||||||
|
std::size_t end;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<parameter> csi_parameter{};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace finalcut
|
||||||
|
|
||||||
|
#endif // SGR_OPTIMIZER_H
|
|
@ -0,0 +1,156 @@
|
||||||
|
/***********************************************************************
|
||||||
|
* sgr_optimizer.cpp - Combines SGR attributes *
|
||||||
|
* *
|
||||||
|
* This file is part of the Final Cut widget toolkit *
|
||||||
|
* *
|
||||||
|
* Copyright 2019 Markus Gans *
|
||||||
|
* *
|
||||||
|
* The 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. *
|
||||||
|
* *
|
||||||
|
* The 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 <cstring>
|
||||||
|
|
||||||
|
#include "final/fc.h"
|
||||||
|
#include "final/sgr_optimizer.h"
|
||||||
|
|
||||||
|
namespace finalcut
|
||||||
|
{
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
// class SGRoptimizer
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
// constructors and destructor
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
SGRoptimizer::SGRoptimizer (attributebuffer& sequence)
|
||||||
|
: seq(sequence)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
SGRoptimizer::~SGRoptimizer() // destructor
|
||||||
|
{ }
|
||||||
|
|
||||||
|
|
||||||
|
// public methods of SGRoptimizer
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
void SGRoptimizer::optimize()
|
||||||
|
{
|
||||||
|
findParameter();
|
||||||
|
combineParameter();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// private methods of SGRoptimizer
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
void SGRoptimizer::findParameter()
|
||||||
|
{
|
||||||
|
// Find ANSI X3.64 terminal SGR (Select Graphic Rendition) strings
|
||||||
|
|
||||||
|
std::size_t len = std::strlen(seq);
|
||||||
|
csi_parameter.clear();
|
||||||
|
|
||||||
|
if ( len < 6 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::size_t start{NOT_SET};
|
||||||
|
bool esc{false}, csi{false};
|
||||||
|
|
||||||
|
// Find SGR parameter
|
||||||
|
for (std::size_t i = 0; i < len; i++)
|
||||||
|
{
|
||||||
|
if ( csi == true )
|
||||||
|
{
|
||||||
|
if ( start == NOT_SET )
|
||||||
|
start = i;
|
||||||
|
|
||||||
|
if ( (seq[i] >= '0' && seq[i] <= '9') || seq[i] == ';' )
|
||||||
|
continue;
|
||||||
|
else if ( seq[i] == 'm')
|
||||||
|
{
|
||||||
|
csi_parameter.push_back({start, i});
|
||||||
|
}
|
||||||
|
|
||||||
|
esc = csi = false;
|
||||||
|
start = NOT_SET;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( esc && seq[i] == '[' ) // Esc [
|
||||||
|
csi = true;
|
||||||
|
|
||||||
|
if ( seq[i] == ESC[0] ) // Esc
|
||||||
|
esc = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
void SGRoptimizer::combineParameter()
|
||||||
|
{
|
||||||
|
// Combine SGR (Select Graphic Rendition) attributes
|
||||||
|
|
||||||
|
if ( csi_parameter.size() < 2 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
const auto& first = csi_parameter.front();
|
||||||
|
std::size_t count = 1;
|
||||||
|
std::size_t read_pos{};
|
||||||
|
std::size_t write_pos = first.end;
|
||||||
|
|
||||||
|
if ( first.start == first.end ) // Esc [ m
|
||||||
|
{
|
||||||
|
seq[write_pos] = '0';
|
||||||
|
write_pos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
seq[write_pos] = ';';
|
||||||
|
write_pos++;
|
||||||
|
const auto& begin = csi_parameter.cbegin() + 1;
|
||||||
|
const auto& end = csi_parameter.cend();
|
||||||
|
|
||||||
|
for (auto&& p : std::vector<parameter>(begin, end))
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
|
||||||
|
for (read_pos = p.start; read_pos <= p.end; read_pos++)
|
||||||
|
{
|
||||||
|
if ( seq[read_pos] == 'm' )
|
||||||
|
{
|
||||||
|
if ( p.start == p.end ) // Esc [ m
|
||||||
|
{
|
||||||
|
seq[write_pos] = '0';
|
||||||
|
write_pos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( count == csi_parameter.size() )
|
||||||
|
seq[write_pos] = 'm';
|
||||||
|
else
|
||||||
|
seq[write_pos] = ';';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
seq[write_pos] = seq[read_pos];
|
||||||
|
|
||||||
|
write_pos++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while ( seq[write_pos] != '\0' )
|
||||||
|
{
|
||||||
|
seq[write_pos] = seq[read_pos];
|
||||||
|
read_pos++;
|
||||||
|
write_pos++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace finalcut
|
||||||
|
|
|
@ -68,6 +68,7 @@ class FOptiAttrTest : public CPPUNIT_NS::TestFixture
|
||||||
void classNameTest();
|
void classNameTest();
|
||||||
void noArgumentTest();
|
void noArgumentTest();
|
||||||
void vga2ansiTest();
|
void vga2ansiTest();
|
||||||
|
void sgrOptimizerTest();
|
||||||
void fakeReverseTest();
|
void fakeReverseTest();
|
||||||
void ansiTest();
|
void ansiTest();
|
||||||
void vt100Test();
|
void vt100Test();
|
||||||
|
@ -90,6 +91,7 @@ class FOptiAttrTest : public CPPUNIT_NS::TestFixture
|
||||||
CPPUNIT_TEST (classNameTest);
|
CPPUNIT_TEST (classNameTest);
|
||||||
CPPUNIT_TEST (noArgumentTest);
|
CPPUNIT_TEST (noArgumentTest);
|
||||||
CPPUNIT_TEST (vga2ansiTest);
|
CPPUNIT_TEST (vga2ansiTest);
|
||||||
|
CPPUNIT_TEST (sgrOptimizerTest);
|
||||||
CPPUNIT_TEST (fakeReverseTest);
|
CPPUNIT_TEST (fakeReverseTest);
|
||||||
CPPUNIT_TEST (ansiTest);
|
CPPUNIT_TEST (ansiTest);
|
||||||
CPPUNIT_TEST (vt100Test);
|
CPPUNIT_TEST (vt100Test);
|
||||||
|
@ -138,6 +140,149 @@ void FOptiAttrTest::noArgumentTest()
|
||||||
delete ch;
|
delete ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
void FOptiAttrTest::sgrOptimizerTest()
|
||||||
|
{
|
||||||
|
// Test with FOptiAttr
|
||||||
|
// -------------------
|
||||||
|
finalcut::FStartOptions::getFStartOptions().sgr_optimizer = true;
|
||||||
|
finalcut::FOptiAttr oa;
|
||||||
|
oa.setDefaultColorSupport(); // ANSI default color
|
||||||
|
oa.setMaxColor (8);
|
||||||
|
oa.setNoColorVideo (3); // Avoid standout (1) + underline mode (2)
|
||||||
|
oa.set_enter_bold_mode (C_STR(CSI "1m"));
|
||||||
|
oa.set_exit_bold_mode (C_STR(CSI "22m"));
|
||||||
|
oa.set_enter_dim_mode (C_STR(CSI "2m"));
|
||||||
|
oa.set_exit_dim_mode (C_STR(CSI "22m"));
|
||||||
|
oa.set_enter_italics_mode (C_STR(CSI "3m"));
|
||||||
|
oa.set_exit_italics_mode (C_STR(CSI "23m"));
|
||||||
|
oa.set_enter_underline_mode (0);
|
||||||
|
oa.set_exit_underline_mode (0);
|
||||||
|
oa.set_enter_blink_mode (C_STR(CSI "5m"));
|
||||||
|
oa.set_exit_blink_mode (C_STR(CSI "25m"));
|
||||||
|
oa.set_enter_reverse_mode (C_STR(CSI "7m"));
|
||||||
|
oa.set_exit_reverse_mode (C_STR(CSI "27m"));
|
||||||
|
oa.set_enter_standout_mode (0);
|
||||||
|
oa.set_exit_standout_mode (0);
|
||||||
|
oa.set_enter_secure_mode (C_STR(CSI "8m"));
|
||||||
|
oa.set_exit_secure_mode (C_STR(CSI "28m"));
|
||||||
|
oa.set_enter_protected_mode (0);
|
||||||
|
oa.set_exit_protected_mode (C_STR(CSI "0m"));
|
||||||
|
oa.set_enter_crossed_out_mode (C_STR(CSI "9m"));
|
||||||
|
oa.set_exit_crossed_out_mode (C_STR(CSI "29m"));
|
||||||
|
oa.set_enter_dbl_underline_mode (C_STR(CSI "21m"));
|
||||||
|
oa.set_exit_dbl_underline_mode (C_STR(CSI "24m"));
|
||||||
|
oa.set_set_attributes (C_STR(CSI "0;10"
|
||||||
|
"%?%p3%t;7%;"
|
||||||
|
"%?%p4%t;5%;"
|
||||||
|
"%?%p5%t;2%;"
|
||||||
|
"%?%p6%t;1%;"
|
||||||
|
"%?%p7%t;8%;"
|
||||||
|
"%?%p9%t;11%;m"));
|
||||||
|
oa.set_exit_attribute_mode (C_STR(CSI "0m"));
|
||||||
|
oa.set_enter_alt_charset_mode (C_STR(CSI "11m"));
|
||||||
|
oa.set_exit_alt_charset_mode (C_STR(CSI "10m"));
|
||||||
|
oa.set_enter_pc_charset_mode (C_STR(CSI "11m"));
|
||||||
|
oa.set_exit_pc_charset_mode (C_STR(CSI "10m"));
|
||||||
|
oa.set_a_foreground_color (C_STR(CSI "3%p1%dm"));
|
||||||
|
oa.set_a_background_color (C_STR(CSI "4%p1%dm"));
|
||||||
|
oa.set_foreground_color (0);
|
||||||
|
oa.set_background_color (0);
|
||||||
|
oa.set_term_color_pair (0);
|
||||||
|
oa.set_orig_pair (C_STR(CSI "39;49m"));
|
||||||
|
oa.set_orig_orig_colors (0);
|
||||||
|
oa.initialize();
|
||||||
|
|
||||||
|
finalcut::FChar* from = new finalcut::FChar();
|
||||||
|
finalcut::FChar* to = new finalcut::FChar();
|
||||||
|
CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 );
|
||||||
|
|
||||||
|
// Blue text on white background + bold + dim + italic
|
||||||
|
to->fg_color = finalcut::fc::Blue;
|
||||||
|
to->bg_color = finalcut::fc::White;
|
||||||
|
to->attr.bit.bold = true;
|
||||||
|
to->attr.bit.dim = true;
|
||||||
|
to->attr.bit.italic = true;
|
||||||
|
CPPUNIT_ASSERT ( *from != *to );
|
||||||
|
CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to)
|
||||||
|
, C_STR(CSI "0;10;2;1;3;34;47m") );
|
||||||
|
CPPUNIT_ASSERT ( *from == *to );
|
||||||
|
CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 );
|
||||||
|
|
||||||
|
// Yellow text on Black Yellow + bold
|
||||||
|
to->fg_color = finalcut::fc::Yellow;
|
||||||
|
to->bg_color = finalcut::fc::Black;
|
||||||
|
to->attr.bit.bold = true;
|
||||||
|
to->attr.bit.dim = false;
|
||||||
|
to->attr.bit.italic = false;
|
||||||
|
CPPUNIT_ASSERT ( *from != *to );
|
||||||
|
CPPUNIT_ASSERT_CSTRING ( oa.changeAttribute(from, to)
|
||||||
|
, C_STR(CSI "0;10;1;33;40m") );
|
||||||
|
CPPUNIT_ASSERT ( *from == *to );
|
||||||
|
CPPUNIT_ASSERT ( oa.changeAttribute(from, to) == 0 );
|
||||||
|
|
||||||
|
|
||||||
|
// Test only the optimizer
|
||||||
|
// -----------------------
|
||||||
|
char buffer[8192] = { CSI "0;10m" CSI "11m" CSI "36m" CSI "44m" };
|
||||||
|
finalcut::SGRoptimizer sgr_optimizer(buffer);
|
||||||
|
sgr_optimizer.optimize();
|
||||||
|
CPPUNIT_ASSERT_CSTRING ( buffer, C_STR(CSI "0;10;11;36;44m") );
|
||||||
|
|
||||||
|
std::strcpy(buffer, CSI "0;1m" CSI "34m");
|
||||||
|
sgr_optimizer.optimize();
|
||||||
|
CPPUNIT_ASSERT_CSTRING ( buffer, C_STR(CSI "0;1;34m") );
|
||||||
|
|
||||||
|
std::strcpy(buffer, CSI "m" CSI "34m");
|
||||||
|
sgr_optimizer.optimize();
|
||||||
|
CPPUNIT_ASSERT_CSTRING ( buffer, C_STR(CSI "0;34m") );
|
||||||
|
|
||||||
|
std::strcpy(buffer, CSI "1m" CSI "m" CSI "45m");
|
||||||
|
sgr_optimizer.optimize();
|
||||||
|
CPPUNIT_ASSERT_CSTRING ( buffer, C_STR(CSI "1;0;45m") );
|
||||||
|
|
||||||
|
std::strcpy(buffer, CSI "47m");
|
||||||
|
sgr_optimizer.optimize();
|
||||||
|
CPPUNIT_ASSERT_CSTRING ( buffer, C_STR(CSI "47m") );
|
||||||
|
|
||||||
|
std::strcpy(buffer, CSI "47m" CSI "m" CSI "1m");
|
||||||
|
sgr_optimizer.optimize();
|
||||||
|
CPPUNIT_ASSERT_CSTRING ( buffer, C_STR(CSI "47;0;1m") );
|
||||||
|
|
||||||
|
std::strcpy(buffer, CSI "49m" CSI "m" CSI "0m");
|
||||||
|
sgr_optimizer.optimize();
|
||||||
|
CPPUNIT_ASSERT_CSTRING ( buffer, C_STR(CSI "49;0;0m") );
|
||||||
|
|
||||||
|
std::strcpy(buffer, CSI "m" CSI "m" CSI "m");
|
||||||
|
sgr_optimizer.optimize();
|
||||||
|
CPPUNIT_ASSERT_CSTRING ( buffer, C_STR(CSI "0;0;0m") );
|
||||||
|
|
||||||
|
std::strcpy(buffer, CSI "m");
|
||||||
|
sgr_optimizer.optimize();
|
||||||
|
CPPUNIT_ASSERT_CSTRING ( buffer, C_STR(CSI "m") );
|
||||||
|
|
||||||
|
std::strcpy(buffer, CSI "0;10;1;7m" CSI "3m" CSI "39m" CSI "49m");
|
||||||
|
sgr_optimizer.optimize();
|
||||||
|
CPPUNIT_ASSERT_CSTRING ( buffer, C_STR(CSI "0;10;1;7;3;39;49m") );
|
||||||
|
|
||||||
|
std::strcpy(buffer, CSI "m" CSI "38;5;20m" CSI "48;5;229m");
|
||||||
|
sgr_optimizer.optimize();
|
||||||
|
CPPUNIT_ASSERT_CSTRING ( buffer, C_STR(CSI "0;38;5;20;48;5;229m") );
|
||||||
|
|
||||||
|
std::strcpy(buffer, CSI "m" CSI "1m" CSI "2m" CSI "3m" CSI "4m"
|
||||||
|
CSI "5m" CSI "7m" CSI "8m" CSI "9m");
|
||||||
|
sgr_optimizer.optimize();
|
||||||
|
CPPUNIT_ASSERT_CSTRING ( buffer, C_STR(CSI "0;1;2;3;4;5;7;8;9m") );
|
||||||
|
|
||||||
|
std::strcpy(buffer, CSI "0m" CSI "46;36;1m");
|
||||||
|
sgr_optimizer.optimize();
|
||||||
|
CPPUNIT_ASSERT_CSTRING ( buffer, C_STR(CSI "0;46;36;1m") );
|
||||||
|
|
||||||
|
std::strcpy(buffer, CSI "m" CSI "38;2;0;139;139m" CSI "48;2;240;255;240m");
|
||||||
|
sgr_optimizer.optimize();
|
||||||
|
CPPUNIT_ASSERT_CSTRING ( buffer, C_STR(CSI "0;38;2;0;139;139;48;2;240;255;240m") );
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
void FOptiAttrTest::vga2ansiTest()
|
void FOptiAttrTest::vga2ansiTest()
|
||||||
{
|
{
|
||||||
|
@ -163,6 +308,7 @@ void FOptiAttrTest::vga2ansiTest()
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
void FOptiAttrTest::fakeReverseTest()
|
void FOptiAttrTest::fakeReverseTest()
|
||||||
{
|
{
|
||||||
|
finalcut::FStartOptions::getFStartOptions().sgr_optimizer = false;
|
||||||
finalcut::FOptiAttr oa;
|
finalcut::FOptiAttr oa;
|
||||||
oa.setDefaultColorSupport(); // ANSI default color
|
oa.setDefaultColorSupport(); // ANSI default color
|
||||||
oa.setMaxColor (8);
|
oa.setMaxColor (8);
|
||||||
|
@ -251,6 +397,7 @@ void FOptiAttrTest::ansiTest()
|
||||||
{
|
{
|
||||||
// Simulate an ansi terminal
|
// Simulate an ansi terminal
|
||||||
|
|
||||||
|
finalcut::FStartOptions::getFStartOptions().sgr_optimizer = false;
|
||||||
finalcut::FOptiAttr oa;
|
finalcut::FOptiAttr oa;
|
||||||
oa.setDefaultColorSupport(); // ANSI default color
|
oa.setDefaultColorSupport(); // ANSI default color
|
||||||
oa.setMaxColor (8);
|
oa.setMaxColor (8);
|
||||||
|
@ -718,6 +865,7 @@ void FOptiAttrTest::vt100Test()
|
||||||
{
|
{
|
||||||
// Simulate a vt100 terminal
|
// Simulate a vt100 terminal
|
||||||
|
|
||||||
|
finalcut::FStartOptions::getFStartOptions().sgr_optimizer = false;
|
||||||
finalcut::FOptiAttr oa;
|
finalcut::FOptiAttr oa;
|
||||||
oa.unsetDefaultColorSupport(); // No ANSI default color
|
oa.unsetDefaultColorSupport(); // No ANSI default color
|
||||||
oa.setMaxColor (1);
|
oa.setMaxColor (1);
|
||||||
|
@ -1179,6 +1327,7 @@ void FOptiAttrTest::xtermTest()
|
||||||
{
|
{
|
||||||
// Simulate an xterm-256color terminal
|
// Simulate an xterm-256color terminal
|
||||||
|
|
||||||
|
finalcut::FStartOptions::getFStartOptions().sgr_optimizer = false;
|
||||||
finalcut::FOptiAttr oa;
|
finalcut::FOptiAttr oa;
|
||||||
oa.setDefaultColorSupport(); // ANSI default color
|
oa.setDefaultColorSupport(); // ANSI default color
|
||||||
oa.setMaxColor (256);
|
oa.setMaxColor (256);
|
||||||
|
@ -1660,6 +1809,7 @@ void FOptiAttrTest::rxvtTest()
|
||||||
{
|
{
|
||||||
// Simulate an rxvt terminal
|
// Simulate an rxvt terminal
|
||||||
|
|
||||||
|
finalcut::FStartOptions::getFStartOptions().sgr_optimizer = false;
|
||||||
finalcut::FOptiAttr oa;
|
finalcut::FOptiAttr oa;
|
||||||
oa.setDefaultColorSupport(); // ANSI default color
|
oa.setDefaultColorSupport(); // ANSI default color
|
||||||
oa.setMaxColor (8);
|
oa.setMaxColor (8);
|
||||||
|
@ -2131,6 +2281,7 @@ void FOptiAttrTest::linuxTest()
|
||||||
{
|
{
|
||||||
// Simulate a Linux terminal with 16 colors
|
// Simulate a Linux terminal with 16 colors
|
||||||
|
|
||||||
|
finalcut::FStartOptions::getFStartOptions().sgr_optimizer = false;
|
||||||
finalcut::FOptiAttr oa;
|
finalcut::FOptiAttr oa;
|
||||||
oa.setDefaultColorSupport(); // ANSI default color
|
oa.setDefaultColorSupport(); // ANSI default color
|
||||||
oa.setMaxColor (16);
|
oa.setMaxColor (16);
|
||||||
|
@ -2605,6 +2756,7 @@ void FOptiAttrTest::puttyTest()
|
||||||
{
|
{
|
||||||
// Simulate a putty-256color terminal
|
// Simulate a putty-256color terminal
|
||||||
|
|
||||||
|
finalcut::FStartOptions::getFStartOptions().sgr_optimizer = false;
|
||||||
finalcut::FOptiAttr oa;
|
finalcut::FOptiAttr oa;
|
||||||
oa.unsetDefaultColorSupport(); // No ANSI default color
|
oa.unsetDefaultColorSupport(); // No ANSI default color
|
||||||
oa.setMaxColor (256);
|
oa.setMaxColor (256);
|
||||||
|
@ -3087,6 +3239,7 @@ void FOptiAttrTest::teratermTest()
|
||||||
{
|
{
|
||||||
// Simulate a Tera Term terminal
|
// Simulate a Tera Term terminal
|
||||||
|
|
||||||
|
finalcut::FStartOptions::getFStartOptions().sgr_optimizer = false;
|
||||||
finalcut::FOptiAttr oa;
|
finalcut::FOptiAttr oa;
|
||||||
oa.unsetDefaultColorSupport(); // No ANSI default color
|
oa.unsetDefaultColorSupport(); // No ANSI default color
|
||||||
oa.setMaxColor (16);
|
oa.setMaxColor (16);
|
||||||
|
@ -3553,6 +3706,7 @@ void FOptiAttrTest::ibmColorTest()
|
||||||
{
|
{
|
||||||
// Simulate IBM color definitions
|
// Simulate IBM color definitions
|
||||||
|
|
||||||
|
finalcut::FStartOptions::getFStartOptions().sgr_optimizer = false;
|
||||||
finalcut::FOptiAttr oa;
|
finalcut::FOptiAttr oa;
|
||||||
oa.unsetDefaultColorSupport(); // No ANSI default color
|
oa.unsetDefaultColorSupport(); // No ANSI default color
|
||||||
oa.setMaxColor (8);
|
oa.setMaxColor (8);
|
||||||
|
@ -3991,6 +4145,7 @@ void FOptiAttrTest::wyse50Test()
|
||||||
{
|
{
|
||||||
// Simulate an Wyse-50 terminal
|
// Simulate an Wyse-50 terminal
|
||||||
|
|
||||||
|
finalcut::FStartOptions::getFStartOptions().sgr_optimizer = false;
|
||||||
finalcut::FOptiAttr oa;
|
finalcut::FOptiAttr oa;
|
||||||
finalcut::FOptiAttr::termEnv optiattr_env =
|
finalcut::FOptiAttr::termEnv optiattr_env =
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue