Adding an ANSI X3.64 SGR optimizer

This commit is contained in:
Markus Gans 2019-12-31 06:32:51 +01:00
parent 853799b4d6
commit d126c4996a
15 changed files with 604 additions and 161 deletions

View File

@ -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

View File

@ -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
finalcut::FTerm::setPalette ( finalcut::fc::LightMagenta if ( finalcut::FTerm::canChangeColorPalette() )
, int(red.getValue()) {
, int(green.getValue()) finalcut::FTerm::setPalette ( finalcut::fc::LightMagenta
, int(blue.getValue()) ); , int(red.getValue())
, int(green.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);
app.setBackgroundColor(finalcut::fc::LightMagenta);
if ( finalcut::FTerm::canChangeColorPalette() )
app.setBackgroundColor(finalcut::fc::LightMagenta);
Background dialog(&app); Background dialog(&app);
app.setMainWidget(&dialog); app.setMainWidget(&dialog);
dialog.show(); dialog.show();

View File

@ -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 \

View File

@ -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 \

View File

@ -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 \

View File

@ -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();

View File

@ -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 )
{
std::strncat (attr_ptr, seq, sizeof(attr_buf) - std::strlen(attr_ptr));
attr_buf[sizeof(attr_buf) - 1] = '\0';
return true;
}
else
return false; return false;
std::strncat (attr_ptr, seq, sizeof(attr_buf) - std::strlen(attr_ptr));
attr_buf[sizeof(attr_buf) - 1] = '\0';
return true;
} }
} // namespace finalcut } // namespace finalcut

View File

@ -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}

View File

@ -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");

View File

@ -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>

View File

@ -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
{ {
@ -129,46 +130,46 @@ class FOptiAttr final
const FString getClassName() const; const FString getClassName() const;
// Mutators // Mutators
void setTermEnvironment (termEnv&); void setTermEnvironment (termEnv&);
void setMaxColor (const int&); void setMaxColor (const int&);
void setNoColorVideo (int); void setNoColorVideo (int);
void setDefaultColorSupport(); void setDefaultColorSupport();
void unsetDefaultColorSupport(); void unsetDefaultColorSupport();
void set_enter_bold_mode (char[]); void set_enter_bold_mode (char[]);
void set_exit_bold_mode (char[]); void set_exit_bold_mode (char[]);
void set_enter_dim_mode (char[]); void set_enter_dim_mode (char[]);
void set_exit_dim_mode (char[]); void set_exit_dim_mode (char[]);
void set_enter_italics_mode (char[]); void set_enter_italics_mode (char[]);
void set_exit_italics_mode (char[]); void set_exit_italics_mode (char[]);
void set_enter_underline_mode (char[]); void set_enter_underline_mode (char[]);
void set_exit_underline_mode (char[]); void set_exit_underline_mode (char[]);
void set_enter_blink_mode (char[]); void set_enter_blink_mode (char[]);
void set_exit_blink_mode (char[]); void set_exit_blink_mode (char[]);
void set_enter_reverse_mode (char[]); void set_enter_reverse_mode (char[]);
void set_exit_reverse_mode (char[]); void set_exit_reverse_mode (char[]);
void set_enter_secure_mode (char[]); void set_enter_secure_mode (char[]);
void set_exit_secure_mode (char[]); void set_exit_secure_mode (char[]);
void set_enter_protected_mode (char[]); void set_enter_protected_mode (char[]);
void set_exit_protected_mode (char[]); void set_exit_protected_mode (char[]);
void set_enter_crossed_out_mode (char[]); void set_enter_crossed_out_mode (char[]);
void set_exit_crossed_out_mode (char[]); void set_exit_crossed_out_mode (char[]);
void set_enter_dbl_underline_mode (char[]); void set_enter_dbl_underline_mode (char[]);
void set_exit_dbl_underline_mode (char[]); void set_exit_dbl_underline_mode (char[]);
void set_enter_standout_mode (char[]); void set_enter_standout_mode (char[]);
void set_exit_standout_mode (char[]); void set_exit_standout_mode (char[]);
void set_set_attributes (char[]); void set_set_attributes (char[]);
void set_exit_attribute_mode (char[]); void set_exit_attribute_mode (char[]);
void set_enter_alt_charset_mode (char[]); void set_enter_alt_charset_mode (char[]);
void set_exit_alt_charset_mode (char[]); void set_exit_alt_charset_mode (char[]);
void set_enter_pc_charset_mode (char[]); void set_enter_pc_charset_mode (char[]);
void set_exit_pc_charset_mode (char[]); void set_exit_pc_charset_mode (char[]);
void set_a_foreground_color (char[]); void set_a_foreground_color (char[]);
void set_a_background_color (char[]); void set_a_background_color (char[]);
void set_foreground_color (char[]); void set_foreground_color (char[]);
void set_background_color (char[]); void set_background_color (char[]);
void set_term_color_pair (char[]); void set_term_color_pair (char[]);
void set_orig_pair (char[]); void set_orig_pair (char[]);
void set_orig_orig_colors (char[]); void set_orig_orig_colors (char[]);
// Inquiry // Inquiry
static bool isNormal (FChar*&); static bool isNormal (FChar*&);
@ -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;
@ -219,115 +222,117 @@ class FOptiAttr final
}; };
// Mutators // Mutators
bool setTermBold (FChar*&); bool setTermBold (FChar*&);
bool unsetTermBold (FChar*&); bool unsetTermBold (FChar*&);
bool setTermDim (FChar*&); bool setTermDim (FChar*&);
bool unsetTermDim (FChar*&); bool unsetTermDim (FChar*&);
bool setTermItalic (FChar*&); bool setTermItalic (FChar*&);
bool unsetTermItalic (FChar*&); bool unsetTermItalic (FChar*&);
bool setTermUnderline (FChar*&); bool setTermUnderline (FChar*&);
bool unsetTermUnderline (FChar*&); bool unsetTermUnderline (FChar*&);
bool setTermBlink (FChar*&); bool setTermBlink (FChar*&);
bool unsetTermBlink (FChar*&); bool unsetTermBlink (FChar*&);
bool setTermReverse (FChar*&); bool setTermReverse (FChar*&);
bool unsetTermReverse (FChar*&); bool unsetTermReverse (FChar*&);
bool setTermStandout (FChar*&); bool setTermStandout (FChar*&);
bool unsetTermStandout (FChar*&); bool unsetTermStandout (FChar*&);
bool setTermInvisible (FChar*&); bool setTermInvisible (FChar*&);
bool unsetTermInvisible (FChar*&); bool unsetTermInvisible (FChar*&);
bool setTermProtected (FChar*&); bool setTermProtected (FChar*&);
bool unsetTermProtected (FChar*&); bool unsetTermProtected (FChar*&);
bool setTermCrossedOut (FChar*&); bool setTermCrossedOut (FChar*&);
bool unsetTermCrossedOut (FChar*&); bool unsetTermCrossedOut (FChar*&);
bool setTermDoubleUnderline (FChar*&); bool setTermDoubleUnderline (FChar*&);
bool unsetTermDoubleUnderline (FChar*&); bool unsetTermDoubleUnderline (FChar*&);
bool setTermAttributes ( FChar*& bool setTermAttributes ( FChar*&
, bool, bool, bool , bool, bool, bool
, bool, bool, bool , bool, bool, bool
, bool, bool, bool ); , bool, bool, bool );
bool unsetTermAttributes (FChar*&); bool unsetTermAttributes (FChar*&);
bool setTermAltCharset (FChar*&); bool setTermAltCharset (FChar*&);
bool unsetTermAltCharset (FChar*&); bool unsetTermAltCharset (FChar*&);
bool setTermPCcharset (FChar*&); bool setTermPCcharset (FChar*&);
bool unsetTermPCcharset (FChar*&); bool unsetTermPCcharset (FChar*&);
bool setTermDefaultColor (FChar*&); bool setTermDefaultColor (FChar*&);
void setAttributesOn (FChar*&); void setAttributesOn (FChar*&);
void setAttributesOff (FChar*&); void setAttributesOff (FChar*&);
// Inquiries // Inquiries
static bool hasColor (FChar*&); static bool hasColor (FChar*&);
static bool hasAttribute (FChar*&); static bool hasAttribute (FChar*&);
static bool hasNoAttribute (FChar*&); static bool hasNoAttribute (FChar*&);
// Methods // Methods
bool hasColorChanged (FChar*&, FChar*&); bool hasColorChanged (FChar*&, FChar*&);
void resetColor (FChar*&); void resetColor (FChar*&);
void prevent_no_color_video_attributes (FChar*&, bool = false); void prevent_no_color_video_attributes (FChar*&, bool = false);
void deactivateAttributes (FChar*&, FChar*&); void deactivateAttributes (FChar*&, FChar*&);
void changeAttributeSGR (FChar*&, FChar*&); void changeAttributeSGR (FChar*&, FChar*&);
void changeAttributeSeparately (FChar*&, FChar*&); void changeAttributeSeparately (FChar*&, FChar*&);
void change_color (FChar*&, FChar*&); void change_color (FChar*&, FChar*&);
void change_to_default_color (FChar*&, FChar*&, FColor&, FColor&); void change_to_default_color (FChar*&, FChar*&, FColor&, FColor&);
void change_current_color (FChar*&, FColor, FColor); void change_current_color (FChar*&, FColor, FColor);
void resetAttribute (FChar*&); void resetAttribute (FChar*&);
void reset (FChar*&); void reset (FChar*&);
bool caused_reset_attributes (char[], uChar = all_tests); bool caused_reset_attributes (char[], uChar = all_tests);
bool hasCharsetEquivalence(); bool hasCharsetEquivalence();
void detectSwitchOn (FChar*&, FChar*&); void detectSwitchOn (FChar*&, FChar*&);
void detectSwitchOff (FChar*&, FChar*&); void detectSwitchOff (FChar*&, FChar*&);
bool switchOn(); bool switchOn();
bool switchOff(); bool switchOff();
bool append_sequence (char[]); bool append_sequence (char[]);
// Data members // Data members
capability F_enter_bold_mode{}; capability F_enter_bold_mode{};
capability F_exit_bold_mode{}; capability F_exit_bold_mode{};
capability F_enter_dim_mode{}; capability F_enter_dim_mode{};
capability F_exit_dim_mode{}; capability F_exit_dim_mode{};
capability F_enter_italics_mode{}; capability F_enter_italics_mode{};
capability F_exit_italics_mode{}; capability F_exit_italics_mode{};
capability F_enter_underline_mode{}; capability F_enter_underline_mode{};
capability F_exit_underline_mode{}; capability F_exit_underline_mode{};
capability F_enter_blink_mode{}; capability F_enter_blink_mode{};
capability F_exit_blink_mode{}; capability F_exit_blink_mode{};
capability F_enter_reverse_mode{}; capability F_enter_reverse_mode{};
capability F_exit_reverse_mode{}; capability F_exit_reverse_mode{};
capability F_enter_standout_mode{}; capability F_enter_standout_mode{};
capability F_exit_standout_mode{}; capability F_exit_standout_mode{};
capability F_enter_secure_mode{}; capability F_enter_secure_mode{};
capability F_exit_secure_mode{}; capability F_exit_secure_mode{};
capability F_enter_protected_mode{}; capability F_enter_protected_mode{};
capability F_exit_protected_mode{}; capability F_exit_protected_mode{};
capability F_enter_crossed_out_mode{}; capability F_enter_crossed_out_mode{};
capability F_exit_crossed_out_mode{}; capability F_exit_crossed_out_mode{};
capability F_enter_dbl_underline_mode{}; capability F_enter_dbl_underline_mode{};
capability F_exit_dbl_underline_mode{}; capability F_exit_dbl_underline_mode{};
capability F_set_attributes{}; capability F_set_attributes{};
capability F_exit_attribute_mode{}; capability F_exit_attribute_mode{};
capability F_enter_alt_charset_mode{}; capability F_enter_alt_charset_mode{};
capability F_exit_alt_charset_mode{}; capability F_exit_alt_charset_mode{};
capability F_enter_pc_charset_mode{}; capability F_enter_pc_charset_mode{};
capability F_exit_pc_charset_mode{}; capability F_exit_pc_charset_mode{};
capability F_set_a_foreground{}; capability F_set_a_foreground{};
capability F_set_a_background{}; capability F_set_a_background{};
capability F_set_foreground{}; capability F_set_foreground{};
capability F_set_background{}; capability F_set_background{};
capability F_set_color_pair{}; capability F_set_color_pair{};
capability F_orig_pair{}; capability F_orig_pair{};
capability F_orig_colors{}; capability F_orig_colors{};
FChar on{}; FChar on{};
FChar off{}; FChar off{};
FChar reset_byte_mask{}; FChar reset_byte_mask{};
int max_color{1}; SGRoptimizer sgr_optimizer{attr_buf};
int attr_without_color{0};
char* attr_ptr{attr_buf}; int max_color{1};
char attr_buf[8192]{'\0'}; int attr_without_color{0};
bool ansi_default_color{false}; char* attr_ptr{attr_buf};
bool alt_equal_pc_charset{false}; char attr_buf[SGRoptimizer::ATTR_BUF_SIZE]{'\0'};
bool monochron{true}; bool ansi_default_color{false};
bool fake_reverse{false}; bool alt_equal_pc_charset{false};
bool monochron{true};
bool fake_reverse{false};
}; };

View File

@ -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)

View File

@ -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

156
src/sgr_optimizer.cpp Normal file
View File

@ -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

View File

@ -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 =
{ {