Add support for italics (#1009)

Co-authored-by: Ken Reneris <ms/devops kreneris@microsoft.com>
Co-authored-by: ArthurSonzogni <sonzogniarthur@gmail.com>
This commit is contained in:
KenReneris 2025-03-22 10:03:43 -07:00 committed by GitHub
parent bc682d25a6
commit 2c9a828402
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 107 additions and 3 deletions

View File

@ -49,6 +49,14 @@ current (development)
mistake. See #998. mistake. See #998.
### Dom ### Dom
- Feature: Add `italic` decorator. For instance:
```cpp
auto italic_text = text("Italic text") | italic;
```
```cpp
auto italic_text = italic(text("Italic text"));
```
Proposed by @kenReneris in #1009.
- Feature: Add `hscroll_indicator`. It display an horizontal indicator - Feature: Add `hscroll_indicator`. It display an horizontal indicator
reflecting the current scroll position. Proposed by @ibrahimnasson in reflecting the current scroll position. Proposed by @ibrahimnasson in
[issue 752](https://github.com/ArthurSonzogni/FTXUI/issues/752) [issue 752](https://github.com/ArthurSonzogni/FTXUI/issues/752)

View File

@ -84,6 +84,7 @@ add_library(dom
src/ftxui/dom/hbox.cpp src/ftxui/dom/hbox.cpp
src/ftxui/dom/hyperlink.cpp src/ftxui/dom/hyperlink.cpp
src/ftxui/dom/inverted.cpp src/ftxui/dom/inverted.cpp
src/ftxui/dom/italic.cpp
src/ftxui/dom/linear_gradient.cpp src/ftxui/dom/linear_gradient.cpp
src/ftxui/dom/node.cpp src/ftxui/dom/node.cpp
src/ftxui/dom/node_decorator.cpp src/ftxui/dom/node_decorator.cpp

View File

@ -109,6 +109,7 @@ Element can become flexible using the the `flex` decorator.
An element can be decorated using the functions: An element can be decorated using the functions:
- `bold` - `bold`
- `italic`
- `dim` - `dim`
- `inverted` - `inverted`
- `underlined` - `underlined`

View File

@ -39,6 +39,7 @@ add_executable(ftxui-tests
src/ftxui/dom/gridbox_test.cpp src/ftxui/dom/gridbox_test.cpp
src/ftxui/dom/hbox_test.cpp src/ftxui/dom/hbox_test.cpp
src/ftxui/dom/hyperlink_test.cpp src/ftxui/dom/hyperlink_test.cpp
src/ftxui/dom/italic_test.cpp
src/ftxui/dom/linear_gradient_test.cpp src/ftxui/dom/linear_gradient_test.cpp
src/ftxui/dom/scroll_indicator_test.cpp src/ftxui/dom/scroll_indicator_test.cpp
src/ftxui/dom/selection_test.cpp src/ftxui/dom/selection_test.cpp

View File

@ -123,8 +123,8 @@ The project is comprised of 3 modules:
This is the visual element of the program. It defines a `ftxui::Screen`, which This is the visual element of the program. It defines a `ftxui::Screen`, which
is a grid of `ftxui::Pixel`. A Pixel represents a Unicode character and its is a grid of `ftxui::Pixel`. A Pixel represents a Unicode character and its
associated style (bold, colors, etc.). The screen can be printed as a string associated style (bold, italic, colors, etc.). The screen can be printed as a
using `ftxui::Screen::ToString()`. The following example highlights this string using `ftxui::Screen::ToString()`. The following example highlights this
process: process:
```cpp ```cpp
@ -476,10 +476,11 @@ See [demo](https://arthursonzogni.github.io/FTXUI/examples/?file=component/linea
## Style {#dom-style} ## Style {#dom-style}
In addition to colored text and colored backgrounds. Many terminals support text In addition to colored text and colored backgrounds. Many terminals support text
effects such as: `bold`, `dim`, `underlined`, `inverted`, `blink`. effects such as: `bold`, `italic`, `dim`, `underlined`, `inverted`, `blink`.
```cpp ```cpp
Element bold(Element); Element bold(Element);
Element italic(Element);
Element dim(Element); Element dim(Element);
Element inverted(Element); Element inverted(Element);
Element underlined(Element); Element underlined(Element);

View File

@ -29,6 +29,7 @@ example(style_dim)
example(style_gallery) example(style_gallery)
example(style_hyperlink) example(style_hyperlink)
example(style_inverted) example(style_inverted)
example(style_italic)
example(style_strikethrough) example(style_strikethrough)
example(style_underlined) example(style_underlined)
example(style_underlined_double) example(style_underlined_double)

View File

@ -15,6 +15,7 @@ int main() {
hbox({ hbox({
text("normal") , text(" ") , text("normal") , text(" ") ,
text("bold") | bold , text(" ") , text("bold") | bold , text(" ") ,
text("italic") | italic , text(" ") ,
text("dim") | dim , text(" ") , text("dim") | dim , text(" ") ,
text("inverted") | inverted , text(" ") , text("inverted") | inverted , text(" ") ,
text("underlined") | underlined , text(" ") , text("underlined") | underlined , text(" ") ,

View File

@ -0,0 +1,23 @@
// Copyright 2025 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <ftxui/dom/elements.hpp> // for text, operator|, inverted, Fit, hbox, Element
#include <ftxui/screen/screen.hpp> // for Full, Screen
#include <memory> // for allocator
#include "ftxui/dom/node.hpp" // for Render
#include "ftxui/screen/color.hpp" // for ftxui
int main() {
using namespace ftxui;
auto document = hbox({
text("This text is "),
text("italic") | italic,
text(". Do you like it?"),
});
auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document));
Render(screen, document);
screen.Print();
return 0;
}

View File

@ -95,6 +95,7 @@ Element canvas(std::function<void(Canvas&)>);
// -- Decorator --- // -- Decorator ---
Element bold(Element); Element bold(Element);
Element dim(Element); Element dim(Element);
Element italic(Element);
Element inverted(Element); Element inverted(Element);
Element underlined(Element); Element underlined(Element);
Element underlinedDouble(Element); Element underlinedDouble(Element);

View File

@ -17,6 +17,7 @@ struct Pixel {
: blink(false), : blink(false),
bold(false), bold(false),
dim(false), dim(false),
italic(false),
inverted(false), inverted(false),
underlined(false), underlined(false),
underlined_double(false), underlined_double(false),
@ -27,6 +28,7 @@ struct Pixel {
bool blink : 1; bool blink : 1;
bool bold : 1; bool bold : 1;
bool dim : 1; bool dim : 1;
bool italic : 1;
bool inverted : 1; bool inverted : 1;
bool underlined : 1; bool underlined : 1;
bool underlined_double : 1; bool underlined_double : 1;

View File

@ -75,6 +75,7 @@ class DBox : public Node {
acc->bold = pixel.bold; acc->bold = pixel.bold;
acc->dim = pixel.dim; acc->dim = pixel.dim;
acc->inverted = pixel.inverted; acc->inverted = pixel.inverted;
acc->italic = pixel.italic;
acc->underlined = pixel.underlined; acc->underlined = pixel.underlined;
acc->underlined_double = pixel.underlined_double; acc->underlined_double = pixel.underlined_double;
acc->strikethrough = pixel.strikethrough; acc->strikethrough = pixel.strikethrough;

35
src/ftxui/dom/italic.cpp Normal file
View File

@ -0,0 +1,35 @@
// Copyright 2025 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <memory> // for make_shared
#include <utility> // for move
#include "ftxui/dom/elements.hpp" // for Element, underlinedDouble
#include "ftxui/dom/node.hpp" // for Node
#include "ftxui/dom/node_decorator.hpp" // for NodeDecorator
#include "ftxui/screen/box.hpp" // for Box
#include "ftxui/screen/screen.hpp" // for Pixel, Screen
namespace ftxui {
/// @brief Apply a underlinedDouble to text.
/// @ingroup dom
Element italic(Element child) {
class Impl : public NodeDecorator {
public:
using NodeDecorator::NodeDecorator;
void Render(Screen& screen) override {
for (int y = box_.y_min; y <= box_.y_max; ++y) {
for (int x = box_.x_min; x <= box_.x_max; ++x) {
screen.PixelAt(x, y).italic = true;
}
}
Node::Render(screen);
}
};
return std::make_shared<Impl>(std::move(child));
}
} // namespace ftxui

View File

@ -0,0 +1,22 @@
// Copyright 2025 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <string> // for allocator, string
#include "ftxui/dom/elements.hpp" // for operator|, text, bold, Element
#include "ftxui/dom/node.hpp" // for Render
#include "ftxui/screen/screen.hpp" // for Screen, Pixel
#include "gtest/gtest.h" // for Test, AssertionResult, EXPECT_TRUE, Message, TEST, TestPartResult
// NOLINTBEGIN
namespace ftxui {
TEST(ItalicTest, Basic) {
auto element = text("text") | italic;
Screen screen(5, 1);
Render(screen, element);
EXPECT_TRUE(screen.PixelAt(0, 0).italic);
}
} // namespace ftxui
// NOLINTEND

View File

@ -106,6 +106,12 @@ void UpdatePixelStyle(const Screen* screen,
: "\x1B[27m"); // INVERTED_RESET : "\x1B[27m"); // INVERTED_RESET
} }
// Italics
if (FTXUI_UNLIKELY(next.italic != prev.italic)) {
ss << (next.italic ? "\x1B[3m" // ITALIC_SET
: "\x1B[23m"); // ITALIC_RESET
}
// StrikeThrough // StrikeThrough
if (FTXUI_UNLIKELY(next.strikethrough != prev.strikethrough)) { if (FTXUI_UNLIKELY(next.strikethrough != prev.strikethrough)) {
ss << (next.strikethrough ? "\x1B[9m" // CROSSED_OUT ss << (next.strikethrough ? "\x1B[9m" // CROSSED_OUT