From e94d95c930bcaccb467d97e5f0c29d27462ffc97 Mon Sep 17 00:00:00 2001 From: Yaraslau Tamashevich Date: Thu, 7 Nov 2024 16:59:12 +0200 Subject: [PATCH] Extend clang-tidy checks --- src/.clang-tidy | 5 +- src/contour/BlurBehind.cpp | 2 +- src/contour/CaptureScreen.cpp | 2 +- src/contour/Config.cpp | 8 +- src/contour/ContourApp.cpp | 9 +- src/contour/ContourGuiApp.cpp | 2 + src/contour/TerminalSession.cpp | 4 +- src/contour/TerminalSessionManager.cpp | 3 +- src/contour/display/ShaderConfig.cpp | 6 +- src/contour/display/TerminalDisplay.cpp | 2 +- src/contour/helper.cpp | 37 +- src/crispy/App.cpp | 5 +- src/crispy/CLI.cpp | 215 +++++----- src/crispy/CLI_test.cpp | 11 +- src/crispy/LRUCache_test.cpp | 2 + src/crispy/StrongLRUCache_test.cpp | 2 + src/crispy/StrongLRUHashtable_test.cpp | 2 + src/text_shaper/fontconfig_locator.cpp | 7 +- src/text_shaper/open_shaper.cpp | 26 +- src/text_shaper/shaper.cpp | 3 +- src/vtbackend/ColorPalette.cpp | 9 +- src/vtbackend/Grid.cpp | 70 ++-- src/vtbackend/Grid_test.cpp | 47 ++- src/vtbackend/Image.cpp | 4 +- src/vtbackend/InputGenerator_test.cpp | 54 +-- src/vtbackend/Line_test.cpp | 40 +- src/vtbackend/RenderBufferBuilder.cpp | 53 +-- src/vtbackend/Screen.cpp | 50 ++- src/vtbackend/Screen_test.cpp | 25 +- src/vtbackend/Selector.cpp | 12 +- src/vtbackend/Selector_test.cpp | 26 +- src/vtbackend/SixelParser.cpp | 24 +- src/vtbackend/SixelParser_test.cpp | 24 +- src/vtbackend/StatusLineBuilder.cpp | 2 +- src/vtbackend/Terminal.cpp | 81 ++-- src/vtbackend/ViCommands.cpp | 118 +++--- src/vtbackend/ViCommands_test.cpp | 4 +- src/vtbackend/ViInputHandler.cpp | 2 +- src/vtbackend/Viewport.cpp | 2 +- src/vtparser/Parser.cpp | 9 +- src/vtparser/Parser.h | 2 +- src/vtpty/MockPty.cpp | 3 +- src/vtpty/MockViewPty.cpp | 2 +- src/vtpty/Process_unix.cpp | 8 +- src/vtpty/SshSession.cpp | 163 ++++---- src/vtpty/SshSession.h | 5 + src/vtpty/UnixPty.cpp | 11 +- src/vtrasterizer/BackgroundRenderer.cpp | 7 +- src/vtrasterizer/BoxDrawingRenderer.cpp | 415 ++++++++++--------- src/vtrasterizer/CursorRenderer.cpp | 20 +- src/vtrasterizer/DecorationRenderer.cpp | 29 +- src/vtrasterizer/ImageRenderer.cpp | 6 +- src/vtrasterizer/Pixmap.cpp | 16 +- src/vtrasterizer/RenderTarget.cpp | 6 +- src/vtrasterizer/Renderer.cpp | 20 +- src/vtrasterizer/TextClusterGrouper.cpp | 6 +- src/vtrasterizer/TextClusterGrouper_test.cpp | 10 +- src/vtrasterizer/TextRenderer.cpp | 22 +- src/vtrasterizer/utils.cpp | 4 +- 59 files changed, 993 insertions(+), 771 deletions(-) diff --git a/src/.clang-tidy b/src/.clang-tidy index e8ea01fff7..8135615895 100644 --- a/src/.clang-tidy +++ b/src/.clang-tidy @@ -57,7 +57,6 @@ Checks: >- -readability-container-contains, -readability-convert-member-functions-to-static, -readability-else-after-return, - -readability-function-cognitive-complexity, -readability-identifier-length, -readability-implicit-bool-conversion, -readability-magic-numbers, @@ -77,6 +76,8 @@ WarningsAsErrors: >- misc-const-correctness, modernize-use-nullptr, modernize-use-constraints, + modernize-use-designated-initializers, + readability-math-missing-parentheses, bugprone-narrowing-conversions, UseColor: true HeaderFilterRegex: 'src/(contour|crispy|text_shaper|vtpty|vtparser|vtbackend|vtrasterizer)/' @@ -154,3 +155,5 @@ CheckOptions: value: camelBack - key: readability-identifier-naming.ConstantCasePrefix value: '' + - key: readability-function-cognitive-complexity.Threshold + value: '50' diff --git a/src/contour/BlurBehind.cpp b/src/contour/BlurBehind.cpp index a5425ae64f..e0fb290660 100644 --- a/src/contour/BlurBehind.cpp +++ b/src/contour/BlurBehind.cpp @@ -72,7 +72,7 @@ namespace return nullopt; auto const atomName = reply->atom; - return XcbPropertyInfo { xcbConnection, winId, atomName }; + return XcbPropertyInfo { .connection = xcbConnection, .window = winId, .propertyAtom = atomName }; } void setPropertyX11(QWindow* window, string const& name, uint32_t value) diff --git a/src/contour/CaptureScreen.cpp b/src/contour/CaptureScreen.cpp index 2006198f50..4cd66652fa 100644 --- a/src/contour/CaptureScreen.cpp +++ b/src/contour/CaptureScreen.cpp @@ -306,7 +306,7 @@ bool captureScreen(CaptureSettings const& settings) settings.logicalLines ? "logical" : "physical", settings.lineCount, settings.words ? "words" : "lines", - settings.outputFile.data()); + settings.outputFile); // request screen capture reference_wrapper output(cout); diff --git a/src/contour/Config.cpp b/src/contour/Config.cpp index dc6df79de0..4d9c12fe5a 100644 --- a/src/contour/Config.cpp +++ b/src/contour/Config.cpp @@ -16,6 +16,7 @@ #include #include +#include #include #include @@ -272,7 +273,7 @@ void compareEntries(Config& config, auto const& output) for (auto const& entry: existingEntries) { - if (std::find(userEntries.begin(), userEntries.end(), entry) == userEntries.end()) + if (std::ranges::find(userEntries, entry) == userEntries.end()) { output()("[diff] Entry {} is missing in user config file\n", entry); } @@ -1098,7 +1099,7 @@ void YAMLConfigReader::loadFromEntry(YAML::Node const& node, std::string const& loadFromEntry(child, "max_width", width); uint height = 0; loadFromEntry(child, "max_height", height); - where.maxImageSize = { vtpty::Width { width }, vtpty::Height { height } }; + where.maxImageSize = { .width = vtpty::Width { width }, .height = vtpty::Height { height } }; } } @@ -1260,7 +1261,7 @@ void YAMLConfigReader::loadFromEntry(YAML::Node const& node, { if (literal == deprecated) { - errorLog()("Setting font locator to \"{}\" is deprecated. Use \"native\".", literal); + errorLog()(R"(Setting font locator to "{}" is deprecated. Use "native".)", literal); return NativeFontLocator; } } @@ -1803,6 +1804,7 @@ std::optional YAMLConfigReader::parseModifierKey(std::stri return std::nullopt; } +// NOLINTNEXTLINE(readability-function-cognitive-complexity) std::optional YAMLConfigReader::parseAction(YAML::Node const& node) { if (auto actionNode = node["action"]) diff --git a/src/contour/ContourApp.cpp b/src/contour/ContourApp.cpp index c33722d4a0..b372d898b2 100644 --- a/src/contour/ContourApp.cpp +++ b/src/contour/ContourApp.cpp @@ -484,6 +484,7 @@ int ContourApp::profileAction() crispy::cli::command ContourApp::parameterDefinition() const { + // NOLINTBEGIN return CLI::command { "contour", "Contour Terminal Emulator " CONTOUR_VERSION_STRING @@ -574,9 +575,10 @@ crispy::cli::command ContourApp::parameterDefinition() const "capture", "Captures the screen buffer of the currently running terminal.", { - CLI::option { "logical", - CLI::value { false }, - "Tells the terminal to use logical lines for counting and capturing." }, + CLI::option { .name = "logical", + .v = CLI::value { false }, + .helpText = + "Tells the terminal to use logical lines for counting and capturing." }, CLI::option { "words", CLI::value { false }, "Splits each line into words and outputs only one word per line." }, @@ -606,6 +608,7 @@ crispy::cli::command ContourApp::parameterDefinition() const "Profile name to activate in the currently connected terminal.", "NAME" } } } } } } }; + // NOLINTEND } } // namespace contour diff --git a/src/contour/ContourGuiApp.cpp b/src/contour/ContourGuiApp.cpp index 589395b822..cb15b2d3a2 100644 --- a/src/contour/ContourGuiApp.cpp +++ b/src/contour/ContourGuiApp.cpp @@ -70,6 +70,7 @@ crispy::cli::command ContourGuiApp::parameterDefinition() const { auto command = ContourApp::parameterDefinition(); + // NOLINTBEGIN command.children.insert( command.children.begin(), CLI::command { @@ -147,6 +148,7 @@ crispy::cli::command ContourGuiApp::parameterDefinition() const CLI::verbatim { "PROGRAM ARGS...", "Executes given program instead of the one provided in the configuration." } }); + // NOLINTEND return command; } diff --git a/src/contour/TerminalSession.cpp b/src/contour/TerminalSession.cpp index b42992d2fa..88060444cc 100644 --- a/src/contour/TerminalSession.cpp +++ b/src/contour/TerminalSession.cpp @@ -430,7 +430,7 @@ void TerminalSession::requestCaptureBuffer(LineCount lines, bool logical) if (!_display) return; - _pendingBufferCapture = CaptureBufferRequest { lines, logical }; + _pendingBufferCapture = CaptureBufferRequest { .lines = lines, .logical = logical }; emit requestPermissionForBufferCapture(); // _display->post( @@ -1499,7 +1499,7 @@ int TerminalSession::executeAllActions(std::vector const& actio } auto const containsToggleKeybind = [](std::vector const& actions) { - return std::any_of(actions.begin(), actions.end(), [](actions::Action const& action) { + return std::ranges::any_of(actions, [](actions::Action const& action) { return holds_alternative(action); }); }; diff --git a/src/contour/TerminalSessionManager.cpp b/src/contour/TerminalSessionManager.cpp index d01d4934e5..27723d478b 100644 --- a/src/contour/TerminalSessionManager.cpp +++ b/src/contour/TerminalSessionManager.cpp @@ -12,6 +12,7 @@ #include +#include #include using namespace std::string_literals; @@ -179,7 +180,7 @@ void TerminalSessionManager::removeSession(TerminalSession& thatSession) _app.onExit(thatSession); // TODO: the logic behind that impl could probably be moved here. - auto i = std::find_if(_sessions.begin(), _sessions.end(), [&](auto p) { return p == &thatSession; }); + auto i = std::ranges::find_if(_sessions, [&](auto p) { return p == &thatSession; }); if (i != _sessions.end()) { _sessions.erase(i); diff --git a/src/contour/display/ShaderConfig.cpp b/src/contour/display/ShaderConfig.cpp index 4503c099a6..9c47168dab 100644 --- a/src/contour/display/ShaderConfig.cpp +++ b/src/contour/display/ShaderConfig.cpp @@ -81,10 +81,12 @@ ShaderConfig builtinShaderConfig(ShaderClass shaderClass) auto const fileContents = file.readAll().toStdString(); auto const fileHeader = versionHeader + sharedDefines; - return ShaderSource { shaderFilePath, QString::fromStdString(fileHeader + fileContents) }; + return ShaderSource { .location = shaderFilePath, + .contents = QString::fromStdString(fileHeader + fileContents) }; }; QString const basename = QString::fromStdString(to_string(shaderClass)); - return ShaderConfig { makeSource(basename + ".vert"), makeSource(basename + ".frag") }; + return ShaderConfig { .vertexShader = makeSource(basename + ".vert"), + .fragmentShader = makeSource(basename + ".frag") }; }; return makeConfig(shaderClass); } diff --git a/src/contour/display/TerminalDisplay.cpp b/src/contour/display/TerminalDisplay.cpp index dcc5345f1b..efdb310787 100644 --- a/src/contour/display/TerminalDisplay.cpp +++ b/src/contour/display/TerminalDisplay.cpp @@ -1056,7 +1056,7 @@ vtbackend::RefreshRate TerminalDisplay::refreshRate() const DPI TerminalDisplay::fontDPI() const noexcept { - return DPI { 96, 96 } * contentScale(); + return DPI { .x = 96, .y = 96 } * contentScale(); } bool TerminalDisplay::isFullScreen() const diff --git a/src/contour/helper.cpp b/src/contour/helper.cpp index 7c6d85dead..b5935458ba 100644 --- a/src/contour/helper.cpp +++ b/src/contour/helper.cpp @@ -71,7 +71,7 @@ namespace auto const col = vtbackend::ColumnOffset( clamp((sx - marginLeft) / cellSize.width.as(), 0, *pageSize.columns - 1)); - return { row, col }; + return { .line = row, .column = col }; } PixelCoordinate makeMousePixelPosition(QHoverEvent* event, @@ -85,8 +85,8 @@ namespace #endif auto const marginLeft = static_cast(unbox(margins.horizontal) * dpr); auto const marginTop = static_cast(unbox(margins.vertical) * dpr); - return PixelCoordinate { PixelCoordinate::X { int(double(position.x()) * dpr) - marginLeft }, - PixelCoordinate::Y { int(double(position.y()) * dpr) - marginTop } }; + return PixelCoordinate { .x = PixelCoordinate::X { int(double(position.x()) * dpr) - marginLeft }, + .y = PixelCoordinate::Y { int(double(position.y()) * dpr) - marginTop } }; } PixelCoordinate makeMousePixelPosition(QMouseEvent* event, @@ -100,8 +100,8 @@ namespace #endif auto const marginLeft = static_cast(unbox(margins.horizontal) * dpr); auto const marginTop = static_cast(unbox(margins.vertical) * dpr); - return PixelCoordinate { PixelCoordinate::X { int(double(position.x()) * dpr) - marginLeft }, - PixelCoordinate::Y { int(double(position.y()) * dpr) - marginTop } }; + return PixelCoordinate { .x = PixelCoordinate::X { int(double(position.x()) * dpr) - marginLeft }, + .y = PixelCoordinate::Y { int(double(position.y()) * dpr) - marginTop } }; } PixelCoordinate makeMousePixelPosition(QWheelEvent* event, @@ -115,8 +115,8 @@ namespace #endif auto const marginLeft = static_cast(unbox(margins.horizontal) * dpr); auto const marginTop = static_cast(unbox(margins.vertical) * dpr); - return PixelCoordinate { PixelCoordinate::X { int(double(position.x()) * dpr) - marginLeft }, - PixelCoordinate::Y { int(double(position.y()) * dpr) - marginTop } }; + return PixelCoordinate { .x = PixelCoordinate::X { int(double(position.x()) * dpr) - marginLeft }, + .y = PixelCoordinate::Y { int(double(position.y()) * dpr) - marginTop } }; } QPoint transposed(QPoint p) noexcept @@ -137,7 +137,7 @@ namespace inputLog()("[{}] Accumulate scroll with current value {}", modifiers, - crispy::point { session.getScrollX(), session.getScrollY() }); + crispy::point { .x = session.getScrollX(), .y = session.getScrollY() }); if (std::abs(session.getScrollX()) > unbox(session.terminal().cellPixelSize().width)) { @@ -357,8 +357,8 @@ bool sendKeyEvent(QKeyEvent* event, vtbackend::KeyboardEventType eventType, Term } // NOLINTNEXTLINE(readability-qualified-auto) - if (auto const i = find_if( - begin(KeyMappings), end(KeyMappings), [event](auto const& x) { return x.first == event->key(); }); + if (auto const i = + std::ranges::find_if(KeyMappings, [event](auto const& x) { return x.first == event->key(); }); i != end(KeyMappings)) { session.sendKeyEvent(i->second, modifiers, eventType, now); @@ -370,9 +370,8 @@ bool sendKeyEvent(QKeyEvent* event, vtbackend::KeyboardEventType eventType, Term if (event->text().isEmpty()) { // NOLINTNEXTLINE(readability-qualified-auto) - if (auto const i = find_if(begin(CharMappings), - end(CharMappings), - [event](auto const& x) { return x.first == event->key(); }); + if (auto const i = std::ranges::find_if(CharMappings, + [event](auto const& x) { return x.first == event->key(); }); i != end(CharMappings)) { session.sendCharEvent(static_cast(i->second), physicalKey, modifiers, eventType, now); @@ -559,12 +558,12 @@ vtbackend::FontDef getFontDefinition(vtrasterizer::Renderer& renderer) else return styledFont.toPattern(); }; - return { renderer.fontDescriptions().size.pt, - renderer.fontDescriptions().regular.familyName, - nameOfStyledFont(text::font_weight::bold, text::font_slant::normal), - nameOfStyledFont(text::font_weight::normal, text::font_slant::italic), - nameOfStyledFont(text::font_weight::bold, text::font_slant::italic), - renderer.fontDescriptions().emoji.toPattern() }; + return { .size = renderer.fontDescriptions().size.pt, + .regular = renderer.fontDescriptions().regular.familyName, + .bold = nameOfStyledFont(text::font_weight::bold, text::font_slant::normal), + .italic = nameOfStyledFont(text::font_weight::normal, text::font_slant::italic), + .boldItalic = nameOfStyledFont(text::font_weight::bold, text::font_slant::italic), + .emoji = renderer.fontDescriptions().emoji.toPattern() }; } vtrasterizer::PageMargin computeMargin(ImageSize cellSize, diff --git a/src/crispy/App.cpp b/src/crispy/App.cpp index d32c99c717..9a3597a647 100644 --- a/src/crispy/App.cpp +++ b/src/crispy/App.cpp @@ -136,9 +136,8 @@ void app::link(std::string command, std::function handler) void app::listDebugTags() { auto& categories = logstore::get(); - sort(begin(categories), end(categories), [](auto const& a, auto const& b) { - return a.get().name() < b.get().name(); - }); + std::ranges::sort(categories, + [](auto const& a, auto const& b) { return a.get().name() < b.get().name(); }); auto const maxNameLength = std::accumulate(begin(categories), end(categories), size_t { 0 }, [&](auto acc, auto const& cat) { diff --git a/src/crispy/CLI.cpp b/src/crispy/CLI.cpp index 6c26e43a00..f79c28c880 100644 --- a/src/crispy/CLI.cpp +++ b/src/crispy/CLI.cpp @@ -488,7 +488,7 @@ optional parse(command const& command, string_view_list const& args) { validate(command); - auto context = parse_context { args }; + auto context = parse_context { .args = args }; prefillDefaults(context, command); @@ -750,120 +750,135 @@ namespace // {{{ helpers return result; } + void printCommandSequence(ostream& os, + command const& com, + unsigned margin, + vector& parents, + const auto& stylize) + { + os << indent(1); + for (command const* parent: parents) + os << stylize(parent->name, help_element::OptionValue /*well, yeah*/) << ' '; + + if (com.select == command_select::Explicit) + os << com.name; + else + { + os << stylize("[", help_element::Braces); + os << stylize(com.name, help_element::ImplicitCommand); + os << stylize("]", help_element::Braces); + } + + os << "\n"; + + if (!parents.empty()) + { + unsigned cursor = 1; + os << indent(2, &cursor); + os << stylize(wordWrapped(com.helpText, cursor, margin, &cursor), help_element::HelpText) + << "\n\n"; + } + } + + void printOptions(ostream& os, + command const& com, + help_display_style const& style, + unsigned margin, + [[maybe_unused]] vector& parents) + { + auto const stylize = stylizer(style); + + os << indent(2) << stylize("Options:", help_element::Header) << "\n\n"; + + auto const leftPadding = indent(3); + auto const minRightPadSize = 2; + auto const maxOptionTextSize = longestOptionText(com.options, style.optionStyle); + auto const columnWidth = + static_cast(leftPadding.size() + maxOptionTextSize + minRightPadSize); + + for (option const& option: com.options) + { + // if (option.deprecated) + // continue; + + auto const leftSize = leftPadding.size() + printOption(option, nullopt, style.optionStyle).size(); + assert(columnWidth >= leftSize); + auto const actualRightPaddingSize = columnWidth - leftSize; + auto const left = leftPadding + printOption(option, style.colors, style.optionStyle) + + spaces(actualRightPaddingSize); + + os << left; + + auto cursor = columnWidth + 1; + os << stylize(wordWrapped(option.helpText, columnWidth, margin, &cursor), help_element::HelpText); + + // {{{ append default value, if any + auto const defaultValueStr = [&]() -> string { + if (holds_alternative(option.v)) + return get(option.v) ? "true" : "false"; + else if (holds_alternative(option.v)) + return std::to_string(get(option.v)); + else if (holds_alternative(option.v)) + return std::to_string(get(option.v)); + else if (holds_alternative(option.v)) + return std::to_string(get(option.v)); + else + return get(option.v); + }(); + if ((option.presence == presence::Optional && !defaultValueStr.empty()) + || (holds_alternative(option.v) && get(option.v))) + { + auto const defaultTextPrefix = string("default:"); + auto const defaultText = stylize("[", help_element::Braces) + defaultTextPrefix + " " + + stylize(defaultValueStr, help_element::OptionValue) + + stylize("]", help_element::Braces); + auto const defaultTextLength = 1 + defaultTextPrefix.size() + 1 + defaultValueStr.size() + 1; + if (cursor + defaultTextLength > margin) + os << "\n" << spaces(columnWidth) << defaultText; + else + os << " " << defaultText; + } + // }}} + + os << '\n'; + } + if (com.verbatim.has_value()) + { + auto const& verbatim = com.verbatim.value(); + auto const leftSize = static_cast(leftPadding.size() + 2 + verbatim.placeholder.size()); + assert(columnWidth > leftSize); + auto const actualRightPaddingSize = columnWidth - leftSize; + auto const left = leftPadding + stylize("[", help_element::Braces) + + stylize(verbatim.placeholder, help_element::Verbatim) + + stylize("]", help_element::Braces) + spaces(actualRightPaddingSize); + + os << left; + auto cursor = columnWidth + 1; + os << stylize(wordWrapped(verbatim.helpText, columnWidth, margin, &cursor), + help_element::HelpText); + os << '\n'; + } + os << '\n'; + } + void detailedDescription(ostream& os, command const& com, help_display_style const& style, unsigned margin, - vector& parents) + [[maybe_unused]] vector& parents) { // NOTE: We asume that cursor position is at first column! auto const stylize = stylizer(style); - bool const hasParentCommand = !parents.empty(); bool const isLeafCommand = com.children.empty(); if (isLeafCommand || !com.options.empty() || com.verbatim.has_value()) // {{{ print command sequence { - os << indent(1); - for (command const* parent: parents) - os << stylize(parent->name, help_element::OptionValue /*well, yeah*/) << ' '; - - if (com.select == command_select::Explicit) - os << com.name; - else - { - os << stylize("[", help_element::Braces); - os << stylize(com.name, help_element::ImplicitCommand); - os << stylize("]", help_element::Braces); - } - - os << "\n"; - - if (hasParentCommand) - { - unsigned cursor = 1; - os << indent(2, &cursor); - os << stylize(wordWrapped(com.helpText, cursor, margin, &cursor), help_element::HelpText) - << "\n\n"; - } + printCommandSequence(os, com, margin, parents, stylize); } // }}} if (!com.options.empty() || com.verbatim.has_value()) // {{{ print options { - os << indent(2) << stylize("Options:", help_element::Header) << "\n\n"; - - auto const leftPadding = indent(3); - auto const minRightPadSize = 2; - auto const maxOptionTextSize = longestOptionText(com.options, style.optionStyle); - auto const columnWidth = - static_cast(leftPadding.size() + maxOptionTextSize + minRightPadSize); - - for (option const& option: com.options) - { - // if (option.deprecated) - // continue; - - auto const leftSize = - leftPadding.size() + printOption(option, nullopt, style.optionStyle).size(); - assert(columnWidth >= leftSize); - auto const actualRightPaddingSize = columnWidth - leftSize; - auto const left = leftPadding + printOption(option, style.colors, style.optionStyle) - + spaces(actualRightPaddingSize); - - os << left; - - auto cursor = columnWidth + 1; - os << stylize(wordWrapped(option.helpText, columnWidth, margin, &cursor), - help_element::HelpText); - - // {{{ append default value, if any - auto const defaultValueStr = [&]() -> string { - if (holds_alternative(option.v)) - return get(option.v) ? "true" : "false"; - else if (holds_alternative(option.v)) - return std::to_string(get(option.v)); - else if (holds_alternative(option.v)) - return std::to_string(get(option.v)); - else if (holds_alternative(option.v)) - return std::to_string(get(option.v)); - else - return get(option.v); - }(); - if ((option.presence == presence::Optional && !defaultValueStr.empty()) - || (holds_alternative(option.v) && get(option.v))) - { - auto const defaultTextPrefix = string("default:"); - auto const defaultText = stylize("[", help_element::Braces) + defaultTextPrefix + " " - + stylize(defaultValueStr, help_element::OptionValue) - + stylize("]", help_element::Braces); - auto const defaultTextLength = - 1 + defaultTextPrefix.size() + 1 + defaultValueStr.size() + 1; - if (cursor + defaultTextLength > margin) - os << "\n" << spaces(columnWidth) << defaultText; - else - os << " " << defaultText; - } - // }}} - - os << '\n'; - } - if (com.verbatim.has_value()) - { - auto const& verbatim = com.verbatim.value(); - auto const leftSize = - static_cast(leftPadding.size() + 2 + verbatim.placeholder.size()); - assert(columnWidth > leftSize); - auto const actualRightPaddingSize = columnWidth - leftSize; - auto const left = leftPadding + stylize("[", help_element::Braces) - + stylize(verbatim.placeholder, help_element::Verbatim) - + stylize("]", help_element::Braces) + spaces(actualRightPaddingSize); - - os << left; - auto cursor = columnWidth + 1; - os << stylize(wordWrapped(verbatim.helpText, columnWidth, margin, &cursor), - help_element::HelpText); - os << '\n'; - } - os << '\n'; + printOptions(os, com, style, margin, parents); } // }}} if (!com.children.empty()) // {{{ recurse to sub commands diff --git a/src/crispy/CLI_test.cpp b/src/crispy/CLI_test.cpp index 9323e96839..b0f67c0178 100644 --- a/src/crispy/CLI_test.cpp +++ b/src/crispy/CLI_test.cpp @@ -44,13 +44,14 @@ namespace cli = crispy::cli; using namespace std::string_view_literals; using namespace std::string_literals; -// NOLINTBEGIN(misc-const-correctness) +// NOLINTBEGIN(misc-const-correctness, modernize-use-designated-initializers) TEST_CASE("CLI.option.type.bool") { auto const cmd = cli::command { - "contour", - "help here", - cli::option_list { cli::option { "verbose"sv, cli::value { false }, "Help text here"sv } }, + .name = "contour", + .helpText = "help here", + .options = cli::option_list { cli::option { + .name = "verbose"sv, .v = cli::value { false }, .helpText = "Help text here"sv } }, }; SECTION("set") @@ -120,4 +121,4 @@ TEST_CASE("CLI.contour-full-test") CHECK(flags.values.at("contour.capture.output") == cli::value { "out.vt"s }); CHECK(flags.values.at("contour.capture.timeout") == cli::value { 1.0 }); } -// NOLINTEND(misc-const-correctness) +// NOLINTEND(misc-const-correctness,modernize-use-designated-initializers) diff --git a/src/crispy/LRUCache_test.cpp b/src/crispy/LRUCache_test.cpp index 1c9237bd1b..493a54c73e 100644 --- a/src/crispy/LRUCache_test.cpp +++ b/src/crispy/LRUCache_test.cpp @@ -37,6 +37,7 @@ static std::string join(std::vector const& list, std::string_view delimiter = return s; } +// NOLINTBEGIN(misc-const-correctness,readability-function-cognitive-complexity) TEST_CASE("lru_cache.ctor", "[lrucache]") { auto cache = crispy::lru_cache(4); @@ -153,3 +154,4 @@ TEST_CASE("lru_cache.try_emplace", "[lrucache]") CHECK(cache.at(2) == 4); CHECK(cache.at(3) == 6); } +// NOLINTEND(misc-const-correctness,readability-function-cognitive-complexity) diff --git a/src/crispy/StrongLRUCache_test.cpp b/src/crispy/StrongLRUCache_test.cpp index 38ffd86860..8dac64584c 100644 --- a/src/crispy/StrongLRUCache_test.cpp +++ b/src/crispy/StrongLRUCache_test.cpp @@ -11,6 +11,7 @@ using namespace crispy; using namespace std; using namespace std::string_view_literals; +// NOLINTBEGIN(misc-const-correctness,readability-function-cognitive-complexity) TEST_CASE("strong_lru_cache.operator_index", "") { auto cache = strong_lru_cache(strong_hashtable_size { 8 }, lru_capacity { 4 }); @@ -278,3 +279,4 @@ TEST_CASE("strong_lru_cache.remove_with_hashTable_lookup_collision", "") cache.remove(3); REQUIRE(joinHumanReadable(cache.keys()).empty()); } +// NOLINTEND(misc-const-correctness,readability-function-cognitive-complexity) diff --git a/src/crispy/StrongLRUHashtable_test.cpp b/src/crispy/StrongLRUHashtable_test.cpp index 9af37ec61d..ae3ca0ad5f 100644 --- a/src/crispy/StrongLRUHashtable_test.cpp +++ b/src/crispy/StrongLRUHashtable_test.cpp @@ -56,6 +56,7 @@ inline string ch(Value first, Value second, Values... remaining) } } // namespace +// NOLINTBEGIN(misc-const-correctness,readability-function-cognitive-complexity) TEST_CASE("strong_hash", "") { auto empty = strong_hash::compute(""); @@ -411,3 +412,4 @@ TEST_CASE("strong_lru_hashtable.peek", "") REQUIRE(joinHumanReadable(cache.hashes()) == sh(4, 3, 2, 1)); } } +// NOLINTEND(misc-const-correctness,readability-function-cognitive-complexity) diff --git a/src/text_shaper/fontconfig_locator.cpp b/src/text_shaper/fontconfig_locator.cpp index db3a4b9b81..7ad51c5f42 100644 --- a/src/text_shaper/fontconfig_locator.cpp +++ b/src/text_shaper/fontconfig_locator.cpp @@ -252,7 +252,10 @@ font_source_list fontconfig_locator::locate(font_description const& description) if (FcPatternGetInteger(font, FC_SLANT, 0, &integerValue) == FcResultMatch) slant = fcToFontSlant(integerValue); - output.emplace_back(font_path { string { (char const*) (file) }, ttcIndex, weight, slant }); + output.emplace_back(font_path { .value = string { (char const*) (file) }, + .collectionIndex = ttcIndex, + .weight = weight, + .slant = slant }); locatorLog()("Font {} (ttc index {}, weight {}, slant {}, spacing {}) in chain: {}", output.size(), ttcIndex, @@ -388,7 +391,7 @@ font_source_list fontconfig_locator::all() continue; locatorLog()("font({}, {}, {})", fcWeightStr(weight), fcSlantStr(slant), (char*) family); - output.emplace_back(font_path { (char const*) filename }); + output.emplace_back(font_path { .value = (char const*) filename }); } FcObjectSetDestroy(os); diff --git a/src/text_shaper/open_shaper.cpp b/src/text_shaper/open_shaper.cpp index 67c02ee698..e041d24588 100644 --- a/src/text_shaper/open_shaper.cpp +++ b/src/text_shaper/open_shaper.cpp @@ -374,7 +374,8 @@ namespace for (auto const i: iota(0u, glyphCount)) { glyph_position gpos {}; - gpos.glyph = glyph_key { fontInfo.size, font, glyph_index { info[i].codepoint } }; + gpos.glyph = + glyph_key { .size = fontInfo.size, .font = font, .index = glyph_index { info[i].codepoint } }; #if defined(GLYPH_KEY_DEBUG) { auto const cluster = info[i].cluster; @@ -432,7 +433,8 @@ struct open_shaper::private_open_shaper // {{{ font_weight fontWeight) { auto const sourceId = identifierOf(source); - if (auto i = fontPathAndSizeToKeyMapping.find(FontInfo { sourceId, fontSize, fontWeight }); + if (auto i = fontPathAndSizeToKeyMapping.find( + FontInfo { .path = sourceId, .size = fontSize, .weight = fontWeight }); i != fontPathAndSizeToKeyMapping.end()) return i->second; @@ -450,10 +452,15 @@ struct open_shaper::private_open_shaper // {{{ auto hbFontPtr = hb_font_ptr(hb_ft_font_create_referenced(ftFacePtr.get()), [](auto p) { hb_font_destroy(p); }); - auto fontInfo = HbFontInfo { source, {}, fontSize, std::move(ftFacePtr), std::move(hbFontPtr) }; + auto fontInfo = HbFontInfo { .primary = source, + .fallbacks = {}, + .size = fontSize, + .ftFace = std::move(ftFacePtr), + .hbFont = std::move(hbFontPtr) }; auto key = create_font_key(); - fontPathAndSizeToKeyMapping.emplace(pair { FontInfo { sourceId, fontSize, fontWeight }, key }); + fontPathAndSizeToKeyMapping.emplace( + pair { FontInfo { .path = sourceId, .size = fontSize, .weight = fontWeight }, key }); fontKeyToHbFontInfoMapping.emplace(pair { key, std::move(fontInfo) }); locatorLog()( "Loading font: key={}, id=\"{}\" size={} dpi {} {}", key, sourceId, fontSize, dpi, metrics(key)); @@ -636,7 +643,7 @@ optional open_shaper::shape(font_key font, char32_t codepoint) return nullopt; glyph_position gpos {}; - gpos.glyph = glyph_key { fontInfo.size, font, glyphIndex }; + gpos.glyph = glyph_key { .size = fontInfo.size, .font = font, .index = glyphIndex }; #if defined(GLYPH_KEY_DEBUG) gpos.glyph.text = std::u32string(1, codepoint); #endif @@ -788,8 +795,9 @@ optional open_shaper::rasterize(glyph_key glyph, render_mode m auto const pitch = static_cast(ftBitmap.pitch); for (auto const i: iota(size_t { 0 }, static_cast(ftBitmap.rows))) for (auto const j: iota(size_t { 0 }, static_cast(ftBitmap.width))) - output.bitmap[i * width.as() + j] = min( - static_cast(uint8_t(ftBitmap.buffer[i * pitch + j]) * 255), uint8_t { 255 }); + output.bitmap[(i * width.as()) + j] = + min(static_cast(uint8_t(ftBitmap.buffer[(i * pitch) + j]) * 255), + uint8_t { 255 }); FT_Bitmap_Done(_d->ft, &ftBitmap); break; @@ -803,7 +811,7 @@ optional open_shaper::rasterize(glyph_key glyph, render_mode m auto const* const s = ftFace->glyph->bitmap.buffer; for (auto const i: iota(0u, *output.bitmapSize.height)) for (auto const j: iota(0u, *output.bitmapSize.width)) - output.bitmap[i * *output.bitmapSize.width + j] = s[i * pitch + j]; + output.bitmap[(i * unbox(output.bitmapSize.width)) + j] = s[(i * pitch) + j]; break; } case FT_PIXEL_MODE_LCD: { @@ -853,7 +861,7 @@ optional open_shaper::rasterize(glyph_key glyph, render_mode m { auto const* s = &ftFace->glyph->bitmap - .buffer[static_cast(i) * pitch + static_cast(j) * 4u]; + .buffer[(static_cast(i) * pitch) + (static_cast(j) * 4u)]; // BGRA -> RGBA *t++ = s[2]; diff --git a/src/text_shaper/shaper.cpp b/src/text_shaper/shaper.cpp index 3afeab5c98..048ef2a906 100644 --- a/src/text_shaper/shaper.cpp +++ b/src/text_shaper/shaper.cpp @@ -40,7 +40,8 @@ namespace unsigned int count = 0; for (size_t y = sr; y < min(sr + factor, unbox(inputSize.height)); y++) { - uint8_t const* p = inputBitmap.data() + (y * unbox(inputSize.width) * 4) + sc * 4; + uint8_t const* p = + inputBitmap.data() + (y * unbox(inputSize.width) * 4) + (sc * 4); for (auto x = sc; x < min(sc + factor, unbox(inputSize.width)); x++, count++) { for (size_t i = 0; i < NumComponents; ++i) diff --git a/src/vtbackend/ColorPalette.cpp b/src/vtbackend/ColorPalette.cpp index dabc226542..324be15521 100644 --- a/src/vtbackend/ColorPalette.cpp +++ b/src/vtbackend/ColorPalette.cpp @@ -56,12 +56,13 @@ ColorPalette::Palette const ColorPalette::defaultColorPalette = []() constexpr { for (unsigned green = 0; green < 6; ++green) for (unsigned blue = 0; blue < 6; ++blue) colors[16 + (red * 36) + (green * 6) + blue] = - RGBColor { static_cast(red ? (red * 40 + 55) : 0), - static_cast(green ? (green * 40 + 55) : 0), - static_cast(blue ? (blue * 40 + 55) : 0) }; + RGBColor { static_cast(red ? ((red * 40) + 55) : 0), + static_cast(green ? ((green * 40) + 55) : 0), + static_cast(blue ? ((blue * 40) + 55) : 0) }; // colors 232-255 are a grayscale ramp, intentionally leaving out black and white - for (uint8_t gray = 0, level = uint8_t(gray * 10 + 8); gray < 24; ++gray, level = uint8_t(gray * 10 + 8)) + for (uint8_t gray = 0, level = uint8_t((gray * 10) + 8); gray < 24; + ++gray, level = uint8_t((gray * 10) + 8)) colors[size_t(232 + gray)] = RGBColor { level, level, level }; // dim colors diff --git a/src/vtbackend/Grid.cpp b/src/vtbackend/Grid.cpp index a4907304db..114d0e4fdd 100644 --- a/src/vtbackend/Grid.cpp +++ b/src/vtbackend/Grid.cpp @@ -45,7 +45,9 @@ namespace detail lines.reserve(totalLineCount); for ([[maybe_unused]] auto const _: ranges::views::iota(0u, totalLineCount)) - lines.emplace_back(defaultLineFlags, TrivialLineBuffer { pageSize.columns, initialSGR }); + lines.emplace_back( + defaultLineFlags, + TrivialLineBuffer { .displayWidth = pageSize.columns, .textAttributes = initialSGR }); return lines; } @@ -370,7 +372,8 @@ LineCount Grid::scrollUp(LineCount linesCountToScrollUp, GraphicsAttribute for ([[maybe_unused]] auto const _: ranges::views::iota(0, linesToAllocate)) { _lines.emplace_back(defaultLineFlags(), - TrivialLineBuffer { _pageSize.columns, GraphicsAttributes() }); + TrivialLineBuffer { .displayWidth = _pageSize.columns, + .textAttributes = GraphicsAttributes() }); } return scrollUp(linesCountToScrollUp, defaultAttributes); } @@ -401,7 +404,8 @@ LineCount Grid::scrollUp(LineCount linesCountToScrollUp, GraphicsAttribute fill_n(next(_lines.begin(), *_pageSize.lines), unbox(linesAppendCount), Line { defaultLineFlags(), - TrivialLineBuffer { _pageSize.columns, defaultAttributes } }); + TrivialLineBuffer { .displayWidth = _pageSize.columns, + .textAttributes = defaultAttributes } }); rotateBuffersLeft(linesAppendCount); } if (linesAppendCount < linesCountToScrollUp) @@ -428,11 +432,12 @@ LineCount Grid::scrollUp(LineCount n, GraphicsAttributes defaultAttributes // these two booleans could be cached and updated whenever margin updates, // so not even this needs to be computed for the general case. - auto const fullHorizontal = - margin.horizontal - == Margin::Horizontal { ColumnOffset { 0 }, unbox(_pageSize.columns) - 1 }; + auto const fullHorizontal = margin.horizontal + == Margin::Horizontal { .from = ColumnOffset { 0 }, + .to = unbox(_pageSize.columns) - 1 }; auto const fullVertical = - margin.vertical == Margin::Vertical { LineOffset(0), unbox(_pageSize.lines) - 1 }; + margin.vertical + == Margin::Vertical { .from = LineOffset(0), .to = unbox(_pageSize.lines) - 1 }; if (fullHorizontal) { @@ -501,11 +506,12 @@ void Grid::scrollDown(LineCount vN, GraphicsAttributes const& defaultAttri // so not even this needs to be computed for the general case. auto const fullHorizontal = margin.horizontal - == Margin::Horizontal { ColumnOffset { 0 }, - unbox(_pageSize.columns) - ColumnOffset(1) }; + == Margin::Horizontal { .from = ColumnOffset { 0 }, + .to = unbox(_pageSize.columns) - ColumnOffset(1) }; auto const fullVertical = margin.vertical - == Margin::Vertical { LineOffset(0), unbox(_pageSize.lines) - LineOffset(1) }; + == Margin::Vertical { .from = LineOffset(0), + .to = unbox(_pageSize.lines) - LineOffset(1) }; auto const n = std::min(vN, margin.vertical.length()); @@ -621,7 +627,9 @@ CellLocation Grid::growLines(LineCount newHeight, CellLocation cursor) auto const linesToFill = max(0, *newTotalLineCount - *currentTotalLineCount); for ([[maybe_unused]] auto const _: ranges::views::iota(0, linesToFill)) - _lines.emplace_back(wrappableFlag, TrivialLineBuffer { _pageSize.columns, GraphicsAttributes {} }); + _lines.emplace_back( + wrappableFlag, + TrivialLineBuffer { .displayWidth = _pageSize.columns, .textAttributes = GraphicsAttributes {} }); _pageSize.lines += totalLinesToExtend; _linesUsed = min(_linesUsed + totalLinesToExtend, LineCount::cast_from(_lines.size())); @@ -634,6 +642,7 @@ CellLocation Grid::growLines(LineCount newHeight, CellLocation cursor) } template +// NOLINTNEXTLINE(readability-function-cognitive-complexity) CellLocation Grid::resize(PageSize newSize, CellLocation currentCursorPos, bool wrapPending) { if (_pageSize == newSize) @@ -693,7 +702,7 @@ CellLocation Grid::resize(PageSize newSize, CellLocation currentCursorPos, _pageSize.lines -= numLinesToPushUp; clampHistory(); verifyState(); - return CellLocation { -boxed_cast(numLinesToPushUp), {} }; + return CellLocation { .line = -boxed_cast(numLinesToPushUp), .column = {} }; } verifyState(); @@ -710,7 +719,7 @@ CellLocation Grid::resize(PageSize newSize, CellLocation currentCursorPos, line.resize(newColumnCount); _pageSize.columns = newColumnCount; verifyState(); - return CellLocation { LineOffset(0), ColumnOffset(wrapPending ? 1 : 0) }; + return CellLocation { .line = LineOffset(0), .column = ColumnOffset(wrapPending ? 1 : 0) }; } else { @@ -787,9 +796,10 @@ CellLocation Grid::resize(PageSize newSize, CellLocation currentCursorPos, // so fill the gap until we have a full page. cy = _pageSize.lines - LineCount::cast_from(grownLines.size()); while (LineCount::cast_from(grownLines.size()) < _pageSize.lines) - grownLines.emplace_back( - defaultLineFlags(), - TrivialLineBuffer { newColumnCount, GraphicsAttributes {}, GraphicsAttributes {} }); + grownLines.emplace_back(defaultLineFlags(), + TrivialLineBuffer { .displayWidth = newColumnCount, + .textAttributes = GraphicsAttributes {}, + .fillAttributes = GraphicsAttributes {} }); Ensures(LineCount::cast_from(grownLines.size()) == _pageSize.lines); } @@ -799,9 +809,10 @@ CellLocation Grid::resize(PageSize newSize, CellLocation currentCursorPos, // Fill scrollback lines. auto const totalLineCount = unbox(_pageSize.lines + maxHistoryLineCount()); while (grownLines.size() < totalLineCount) - grownLines.emplace_back( - defaultLineFlags(), - TrivialLineBuffer { newColumnCount, GraphicsAttributes {}, GraphicsAttributes {} }); + grownLines.emplace_back(defaultLineFlags(), + TrivialLineBuffer { .displayWidth = newColumnCount, + .textAttributes = GraphicsAttributes {}, + .fillAttributes = GraphicsAttributes {} }); _lines = std::move(grownLines); _pageSize.columns = newColumnCount; @@ -810,7 +821,8 @@ CellLocation Grid::resize(PageSize newSize, CellLocation currentCursorPos, rotateBuffersLeft(newHistoryLineCount); verifyState(); - return CellLocation { -boxed_cast(cy), ColumnOffset(wrapPending ? 1 : 0) }; + return CellLocation { .line = -boxed_cast(cy), + .column = ColumnOffset(wrapPending ? 1 : 0) }; } }; @@ -904,9 +916,10 @@ CellLocation Grid::resize(PageSize newSize, CellLocation currentCursorPos, Require(numLinesWritten >= _pageSize.lines); while (shrinkedLines.size() < totalLineCount) - shrinkedLines.emplace_back( - LineFlag::None, - TrivialLineBuffer { newColumnCount, GraphicsAttributes {}, GraphicsAttributes {} }); + shrinkedLines.emplace_back(LineFlag::None, + TrivialLineBuffer { .displayWidth = newColumnCount, + .textAttributes = GraphicsAttributes {}, + .fillAttributes = GraphicsAttributes {} }); shrinkedLines.rotate_left( unbox(numLinesWritten - _pageSize.lines)); // maybe to be done outisde? @@ -982,7 +995,10 @@ void Grid::appendNewLines(LineCount count, GraphicsAttributes attr) if (auto const n = std::min(count, _pageSize.lines); *n > 0) { generate_n(back_inserter(_lines), *n, [&]() { - return Line(wrappableFlag, TrivialLineBuffer { _pageSize.columns, attr, attr }); + return Line(wrappableFlag, + TrivialLineBuffer { .displayWidth = _pageSize.columns, + .textAttributes = attr, + .fillAttributes = attr }); }); clampHistory(); } @@ -1064,12 +1080,14 @@ CellLocationRange Grid::wordRangeUnderCursor(CellLocation position, { current.line++; current.column = ColumnOffset(0); - current = stretchedColumn(CellLocation { current.line, current.column + 1 }); + current = + stretchedColumn(CellLocation { .line = current.line, .column = current.column + 1 }); } if (*current.column + 1 < *pageSize().columns) { - current = stretchedColumn(CellLocation { current.line, current.column + 1 }); + current = + stretchedColumn(CellLocation { .line = current.line, .column = current.column + 1 }); } else if (*current.line + 1 < *pageSize().lines) { diff --git a/src/vtbackend/Grid_test.cpp b/src/vtbackend/Grid_test.cpp index ac304997d9..3f3733776c 100644 --- a/src/vtbackend/Grid_test.cpp +++ b/src/vtbackend/Grid_test.cpp @@ -85,8 +85,10 @@ Grid setupGrid(PageSize pageSize, constexpr Margin fullPageMargin(PageSize pageSize) { - return Margin { Margin::Vertical { LineOffset(0), pageSize.lines.as() - 1 }, - Margin::Horizontal { ColumnOffset(0), pageSize.columns.as() - 1 } }; + return Margin { .vertical = + Margin::Vertical { .from = LineOffset(0), .to = pageSize.lines.as() - 1 }, + .horizontal = Margin::Horizontal { .from = ColumnOffset(0), + .to = pageSize.columns.as() - 1 } }; } [[maybe_unused]] Grid setupGrid5x2() @@ -334,9 +336,10 @@ TEST_CASE("resize_lines_nr2_with_scrollback_moving_fully_into_page", "[grid]") CHECK(grid.maxHistoryLineCount() == LineCount(3)); CHECK(grid.historyLineCount() == LineCount(2)); - auto const curCursorPos = CellLocation { grid.pageSize().lines.as() - 1, ColumnOffset(1) }; + auto const curCursorPos = + CellLocation { .line = grid.pageSize().lines.as() - 1, .column = ColumnOffset(1) }; auto const newPageSize = PageSize { LineCount(4), ColumnCount(3) }; - auto const newCursorPos0 = CellLocation { curCursorPos.line + 2, curCursorPos.column }; + auto const newCursorPos0 = CellLocation { .line = curCursorPos.line + 2, .column = curCursorPos.column }; CellLocation newCursorPos = grid.resize(newPageSize, curCursorPos, false); CHECK(newCursorPos.line == newCursorPos0.line); CHECK(newCursorPos.column == newCursorPos0.column); @@ -360,7 +363,7 @@ TEST_CASE("resize_lines_nr3_with_scrollback_moving_into_page_overflow", "[grid]" REQUIRE(grid.pageSize().columns == ColumnCount(3)); REQUIRE(grid.pageSize().lines == LineCount(2)); - auto const curCursorPos = CellLocation { LineOffset(1), ColumnOffset(1) }; + auto const curCursorPos = CellLocation { .line = LineOffset(1), .column = ColumnOffset(1) }; auto const newPageSize = PageSize { LineCount(5), ColumnCount(3) }; logGridText(grid, "BEFORE"); CellLocation newCursorPos = grid.resize(newPageSize, curCursorPos, false); @@ -382,7 +385,7 @@ TEST_CASE("resize_grow_lines_with_history_cursor_no_bottom", "[grid]") CHECK(grid.maxHistoryLineCount() == LineCount(3)); CHECK(grid.historyLineCount() == LineCount(2)); - auto const curCursorPos = CellLocation { LineOffset(0), ColumnOffset(1) }; + auto const curCursorPos = CellLocation { .line = LineOffset(0), .column = ColumnOffset(1) }; logGridText(grid, "before resize"); CellLocation newCursorPos = grid.resize(PageSize { LineCount(3), ColumnCount(3) }, curCursorPos, false); logGridText(grid, "after resize"); @@ -410,7 +413,7 @@ TEST_CASE("resize_shrink_lines_with_history", "[grid]") // shrink by one line (=> move page one line up into scrollback) auto const newPageSize = PageSize { LineCount(1), ColumnCount(3) }; - auto const curCursorPos = CellLocation { LineOffset(1), ColumnOffset(1) }; + auto const curCursorPos = CellLocation { .line = LineOffset(1), .column = ColumnOffset(1) }; logGridText(grid, "BEFORE"); CellLocation const newCursorPos = grid.resize(newPageSize, curCursorPos, false); logGridText(grid, "AFTER"); @@ -441,7 +444,7 @@ TEST_CASE("resize_shrink_columns_with_reflow_and_unwrappable", "[grid]") auto grid = setupGridForResizeTests2x3xN(LineCount(5)); auto const newPageSize = PageSize { LineCount(2), ColumnCount(2) }; - auto const curCursorPos = CellLocation { LineOffset(1), ColumnOffset(1) }; + auto const curCursorPos = CellLocation { .line = LineOffset(1), .column = ColumnOffset(1) }; grid.lineAt(LineOffset(0)).setWrappable(false); logGridText(grid, "BEFORE"); auto const newCursorPos = grid.resize(newPageSize, curCursorPos, false); @@ -484,7 +487,7 @@ TEST_CASE("resize_shrink_columns_with_reflow_grow_lines_and_unwrappable", "[grid // JK // L auto grid = setupGridForResizeTests2x3xN(LineCount(5)); - auto const curCursorPos = CellLocation { LineOffset(1), ColumnOffset(1) }; + auto const curCursorPos = CellLocation { .line = LineOffset(1), .column = ColumnOffset(1) }; grid.lineAt(LineOffset(0)).setWrappable(false); // logGridText(grid, "BEFORE"); auto const newCursorPos = grid.resize(PageSize { LineCount(4), ColumnCount(2) }, curCursorPos, false); @@ -518,7 +521,8 @@ TEST_CASE("resize_reflow_shrink", "[grid]") // Shrink slowly from 5x2 to 4x2 to 3x2 to 2x2. // 4x2 - (void) grid.resize(PageSize { LineCount(2), ColumnCount(4) }, CellLocation { {}, {} }, false); + (void) grid.resize( + PageSize { LineCount(2), ColumnCount(4) }, CellLocation { .line = {}, .column = {} }, false); logGridText(grid, "after resize 4x2"); CHECK(*grid.historyLineCount() == 2); @@ -541,7 +545,8 @@ TEST_CASE("resize_reflow_shrink", "[grid]") // 3x2 std::cout << std::format("Starting resize to 3x2\n"); - (void) grid.resize(PageSize { LineCount(2), ColumnCount(3) }, CellLocation { {}, {} }, false); + (void) grid.resize( + PageSize { LineCount(2), ColumnCount(3) }, CellLocation { .line = {}, .column = {} }, false); logGridText(grid, "after resize 3x2"); CHECK(*grid.historyLineCount() == 2); @@ -552,7 +557,8 @@ TEST_CASE("resize_reflow_shrink", "[grid]") CHECK(grid.lineText(LineOffset(1)) == "de "); // 2x2 - (void) grid.resize(PageSize { LineCount(2), ColumnCount(2) }, CellLocation { {}, {} }, false); + (void) grid.resize( + PageSize { LineCount(2), ColumnCount(2) }, CellLocation { .line = {}, .column = {} }, false); logGridText(grid, "after resize 2x2"); CHECK(grid.pageSize() == PageSize { LineCount(2), ColumnCount(2) }); @@ -571,7 +577,8 @@ TEST_CASE("Grid.reflow", "[grid]") SECTION("resize 4x2") { - (void) grid.resize(PageSize { LineCount(2), ColumnCount(4) }, CellLocation { {}, {} }, false); + (void) grid.resize( + PageSize { LineCount(2), ColumnCount(4) }, CellLocation { .line = {}, .column = {} }, false); logGridText(grid, "after resize"); CHECK(grid.historyLineCount() == LineCount(2)); @@ -886,7 +893,12 @@ TEST_CASE("Grid resize", "[grid]") bufferObject->writeAtEnd(text); auto const bufferFragment = bufferObject->ref(0, 4); auto const sgr = GraphicsAttributes {}; - auto const trivial = TrivialLineBuffer { width, sgr, sgr, HyperlinkId {}, width, bufferFragment }; + auto const trivial = TrivialLineBuffer { .displayWidth = width, + .textAttributes = sgr, + .fillAttributes = sgr, + .hyperlink = HyperlinkId {}, + .usedColumns = width, + .text = bufferFragment }; auto lineTrivial = Line(LineFlag::None, trivial); grid.lineAt(LineOffset(0)) = lineTrivial; REQUIRE(grid.lineAt(LineOffset(0)).isTrivialBuffer()); @@ -910,7 +922,12 @@ TEST_CASE("Grid resize with wrap and spaces", "[grid]") bufferObject->writeAtEnd(text); auto const bufferFragment = bufferObject->ref(0, unbox(width)); auto const sgr = GraphicsAttributes {}; - auto const trivial = TrivialLineBuffer { width, sgr, sgr, HyperlinkId {}, width, bufferFragment }; + auto const trivial = TrivialLineBuffer { .displayWidth = width, + .textAttributes = sgr, + .fillAttributes = sgr, + .hyperlink = HyperlinkId {}, + .usedColumns = width, + .text = bufferFragment }; auto lineTrivial = Line(LineFlag::None, trivial); grid.lineAt(LineOffset(0)) = lineTrivial; diff --git a/src/vtbackend/Image.cpp b/src/vtbackend/Image.cpp index d388a23d08..a4dec99711 100644 --- a/src/vtbackend/Image.cpp +++ b/src/vtbackend/Image.cpp @@ -55,7 +55,7 @@ Image::Data RasterizedImage::fragment(CellLocation pos) const auto const xOffset = pos.column * unbox(_cellSize.width); auto const yOffset = pos.line * unbox(_cellSize.height); - auto const pixelOffset = CellLocation { yOffset, xOffset }; + auto const pixelOffset = CellLocation { .line = yOffset, .column = xOffset }; Image::Data fragData; fragData.resize(_cellSize.area() * 4); // RGBA @@ -92,7 +92,7 @@ Image::Data RasterizedImage::fragment(CellLocation pos) const auto const startOffset = static_cast( ((pixelOffset.line + y) * unbox(_image->width()) + unbox(pixelOffset.column)) * 4); const auto* const source = &_image->data()[startOffset]; - target = copy(source, source + static_cast(availableWidth) * 4, target); + target = copy(source, source + (static_cast(availableWidth) * 4), target); // fill vertical gap on right for (int x = availableWidth; x < unbox(_cellSize.width); ++x) diff --git a/src/vtbackend/InputGenerator_test.cpp b/src/vtbackend/InputGenerator_test.cpp index 1575b335d4..3db63d2dcc 100644 --- a/src/vtbackend/InputGenerator_test.cpp +++ b/src/vtbackend/InputGenerator_test.cpp @@ -136,37 +136,37 @@ TEST_CASE("InputGenerator.Modifier+ArrowKeys", "[terminal,input]") auto constexpr Super = Modifiers { Modifier::Super }; auto constexpr Mappings = std::array { - Mapping { None, Key::UpArrow, "\033[A"sv }, - Mapping { None, Key::DownArrow, "\033[B"sv }, - Mapping { None, Key::RightArrow, "\033[C"sv }, - Mapping { None, Key::LeftArrow, "\033[D"sv }, - Mapping { Shift, Key::UpArrow, "\033[1;2A"sv }, - Mapping { Shift, Key::DownArrow, "\033[1;2B"sv }, - Mapping { Shift, Key::RightArrow, "\033[1;2C"sv }, - Mapping { Shift, Key::LeftArrow, "\033[1;2D"sv }, + Mapping { .modifiers = None, .key = Key::UpArrow, .expected = "\033[A"sv }, + Mapping { .modifiers = None, .key = Key::DownArrow, .expected = "\033[B"sv }, + Mapping { .modifiers = None, .key = Key::RightArrow, .expected = "\033[C"sv }, + Mapping { .modifiers = None, .key = Key::LeftArrow, .expected = "\033[D"sv }, + Mapping { .modifiers = Shift, .key = Key::UpArrow, .expected = "\033[1;2A"sv }, + Mapping { .modifiers = Shift, .key = Key::DownArrow, .expected = "\033[1;2B"sv }, + Mapping { .modifiers = Shift, .key = Key::RightArrow, .expected = "\033[1;2C"sv }, + Mapping { .modifiers = Shift, .key = Key::LeftArrow, .expected = "\033[1;2D"sv }, #ifdef __APPLE__ - Mapping { Alt, Key::UpArrow, "\033[1;5A"sv }, - Mapping { Alt, Key::DownArrow, "\033[1;5B"sv }, - Mapping { Alt, Key::RightArrow, "\033[1;5C"sv }, - Mapping { Alt, Key::LeftArrow, "\033[1;5D"sv }, + Mapping { .modifiers = Alt, .key = Key::UpArrow, .expected = "\033[1;5A"sv }, + Mapping { .modifiers = Alt, .key = Key::DownArrow, .expected = "\033[1;5B"sv }, + Mapping { .modifiers = Alt, .key = Key::RightArrow, .expected = "\033[1;5C"sv }, + Mapping { .modifiers = Alt, .key = Key::LeftArrow, .expected = "\033[1;5D"sv }, #else - Mapping { Alt, Key::UpArrow, "\033[1;3A"sv }, - Mapping { Alt, Key::DownArrow, "\033[1;3B"sv }, - Mapping { Alt, Key::RightArrow, "\033[1;3C"sv }, - Mapping { Alt, Key::LeftArrow, "\033[1;3D"sv }, + Mapping { .modifiers = Alt, .key = Key::UpArrow, .expected = "\033[1;3A"sv }, + Mapping { .modifiers = Alt, .key = Key::DownArrow, .expected = "\033[1;3B"sv }, + Mapping { .modifiers = Alt, .key = Key::RightArrow, .expected = "\033[1;3C"sv }, + Mapping { .modifiers = Alt, .key = Key::LeftArrow, .expected = "\033[1;3D"sv }, #endif - Mapping { Control, Key::UpArrow, "\033[1;5A"sv }, - Mapping { Control, Key::DownArrow, "\033[1;5B"sv }, - Mapping { Control, Key::RightArrow, "\033[1;5C"sv }, - Mapping { Control, Key::LeftArrow, "\033[1;5D"sv }, - Mapping { Super, Key::UpArrow, "\033[1;9A"sv }, - Mapping { Super, Key::DownArrow, "\033[1;9B"sv }, - Mapping { Super, Key::RightArrow, "\033[1;9C"sv }, - Mapping { Super, Key::LeftArrow, "\033[1;9D"sv }, + Mapping { .modifiers = Control, .key = Key::UpArrow, .expected = "\033[1;5A"sv }, + Mapping { .modifiers = Control, .key = Key::DownArrow, .expected = "\033[1;5B"sv }, + Mapping { .modifiers = Control, .key = Key::RightArrow, .expected = "\033[1;5C"sv }, + Mapping { .modifiers = Control, .key = Key::LeftArrow, .expected = "\033[1;5D"sv }, + Mapping { .modifiers = Super, .key = Key::UpArrow, .expected = "\033[1;9A"sv }, + Mapping { .modifiers = Super, .key = Key::DownArrow, .expected = "\033[1;9B"sv }, + Mapping { .modifiers = Super, .key = Key::RightArrow, .expected = "\033[1;9C"sv }, + Mapping { .modifiers = Super, .key = Key::LeftArrow, .expected = "\033[1;9D"sv }, // some mixes - Mapping { Shift | Alt, Key::UpArrow, "\033[1;4A"sv }, - Mapping { Control | Alt, Key::UpArrow, "\033[1;7A"sv }, - Mapping { Control | Alt | Super, Key::UpArrow, "\033[1;15A"sv }, + Mapping { .modifiers = Shift | Alt, .key = Key::UpArrow, .expected = "\033[1;4A"sv }, + Mapping { .modifiers = Control | Alt, .key = Key::UpArrow, .expected = "\033[1;7A"sv }, + Mapping { .modifiers = Control | Alt | Super, .key = Key::UpArrow, .expected = "\033[1;15A"sv }, }; for (auto const& mapping: Mappings) diff --git a/src/vtbackend/Line_test.cpp b/src/vtbackend/Line_test.cpp index 60b1d2b620..b5d79a9e62 100644 --- a/src/vtbackend/Line_test.cpp +++ b/src/vtbackend/Line_test.cpp @@ -38,8 +38,12 @@ TEST_CASE("Line.resize", "[Line]") auto const bufferFragment = bufferObject->ref(0, 4); auto const sgr = GraphicsAttributes {}; - auto const trivial = - TrivialLineBuffer { DisplayWidth, sgr, sgr, HyperlinkId {}, DisplayWidth, bufferFragment }; + auto const trivial = TrivialLineBuffer { .displayWidth = DisplayWidth, + .textAttributes = sgr, + .fillAttributes = sgr, + .hyperlink = HyperlinkId {}, + .usedColumns = DisplayWidth, + .text = bufferFragment }; CHECK(trivial.text.view() == string_view(text.data())); auto lineTrivial = Line(LineFlag::None, trivial); CHECK(lineTrivial.isTrivialBuffer()); @@ -65,8 +69,12 @@ TEST_CASE("Line.reflow", "[Line]") auto const bufferFragment = bufferObject->ref(0, 4); auto const sgr = GraphicsAttributes {}; - auto const trivial = - TrivialLineBuffer { DisplayWidth, sgr, sgr, HyperlinkId {}, DisplayWidth, bufferFragment }; + auto const trivial = TrivialLineBuffer { .displayWidth = DisplayWidth, + .textAttributes = sgr, + .fillAttributes = sgr, + .hyperlink = HyperlinkId {}, + .usedColumns = DisplayWidth, + .text = bufferFragment }; CHECK(trivial.text.view() == string_view(text.data())); auto lineTrivial = Line(LineFlag::None, trivial); CHECK(lineTrivial.isTrivialBuffer()); @@ -91,8 +99,12 @@ TEST_CASE("Line.inflate", "[Line]") sgr.backgroundColor = Color::Indexed(IndexedColor::Yellow); sgr.underlineColor = Color::Indexed(IndexedColor::Red); sgr.flags |= CellFlag::CurlyUnderlined; - auto const trivial = - TrivialLineBuffer { ColumnCount(10), sgr, sgr, HyperlinkId {}, ColumnCount(10), bufferFragment }; + auto const trivial = TrivialLineBuffer { .displayWidth = ColumnCount(10), + .textAttributes = sgr, + .fillAttributes = sgr, + .hyperlink = HyperlinkId {}, + .usedColumns = ColumnCount(10), + .text = bufferFragment }; auto const inflated = inflate(trivial); @@ -127,8 +139,12 @@ TEST_CASE("Line.inflate.Unicode", "[Line]") sgr.backgroundColor = Color::Indexed(IndexedColor::Yellow); sgr.underlineColor = Color::Indexed(IndexedColor::Red); sgr.flags |= CellFlag::CurlyUnderlined; - auto const trivial = - TrivialLineBuffer { DisplayWidth, sgr, sgr, HyperlinkId {}, DisplayWidth, bufferFragment }; + auto const trivial = TrivialLineBuffer { .displayWidth = DisplayWidth, + .textAttributes = sgr, + .fillAttributes = sgr, + .hyperlink = HyperlinkId {}, + .usedColumns = DisplayWidth, + .text = bufferFragment }; auto const inflated = inflate(trivial); @@ -184,8 +200,12 @@ TEST_CASE("Line.inflate.Unicode.FamilyEmoji", "[Line]") fillSGR.underlineColor = Color::Indexed(IndexedColor::Red); fillSGR.flags |= CellFlag::CurlyUnderlined; - auto const trivial = - TrivialLineBuffer { DisplayWidth, sgr, fillSGR, HyperlinkId {}, UsedColumnCount, bufferFragment }; + auto const trivial = TrivialLineBuffer { .displayWidth = DisplayWidth, + .textAttributes = sgr, + .fillAttributes = fillSGR, + .hyperlink = HyperlinkId {}, + .usedColumns = UsedColumnCount, + .text = bufferFragment }; auto const inflated = inflate(trivial); diff --git a/src/vtbackend/RenderBufferBuilder.cpp b/src/vtbackend/RenderBufferBuilder.cpp index 9331f82020..e37308216c 100644 --- a/src/vtbackend/RenderBufferBuilder.cpp +++ b/src/vtbackend/RenderBufferBuilder.cpp @@ -39,12 +39,12 @@ namespace RGBColorPair makeRGBColorPair(RGBColorPair actualColors, CellRGBColorAndAlphaPair configuredColor) noexcept { - return RGBColorPair { mix(makeRGBColor(actualColors, configuredColor.foreground), - actualColors.foreground, - configuredColor.foregroundAlpha), - mix(makeRGBColor(actualColors, configuredColor.background), - actualColors.background, - configuredColor.backgroundAlpha) } + return RGBColorPair { .foreground = mix(makeRGBColor(actualColors, configuredColor.foreground), + actualColors.foreground, + configuredColor.foregroundAlpha), + .background = mix(makeRGBColor(actualColors, configuredColor.background), + actualColors.background, + configuredColor.backgroundAlpha) } .distinct(); } @@ -85,15 +85,16 @@ namespace return selectionColors; if (!selected) - return RGBColorPair { makeRGBColor(sgrColors, colorPalette.cursor.textOverrideColor), - makeRGBColor(sgrColors, colorPalette.cursor.color) } + return RGBColorPair { .foreground = + makeRGBColor(sgrColors, colorPalette.cursor.textOverrideColor), + .background = makeRGBColor(sgrColors, colorPalette.cursor.color) } .distinct(); Require(isCursor && selected); auto cursorColor = - RGBColorPair { makeRGBColor(selectionColors, colorPalette.cursor.textOverrideColor), - makeRGBColor(selectionColors, colorPalette.cursor.color) }; + RGBColorPair { .foreground = makeRGBColor(selectionColors, colorPalette.cursor.textOverrideColor), + .background = makeRGBColor(selectionColors, colorPalette.cursor.color) }; return mix(cursorColor, selectionColors, 0.25f).distinct(); } @@ -137,13 +138,13 @@ optional RenderBufferBuilder::renderCursor() const auto const shape = _terminal->focused() ? _terminal->cursorShape() : InactiveCursorShape; auto const cursorScreenPosition = - CellLocation { _baseLine + _cursorPosition->line - + boxed_cast(_terminal->viewport().scrollOffset()), - _cursorPosition->column }; + CellLocation { .line = _baseLine + _cursorPosition->line + + boxed_cast(_terminal->viewport().scrollOffset()), + .column = _cursorPosition->column }; auto const cellWidth = _terminal->currentScreen().cellWidthAt(*_cursorPosition); - return RenderCursor { cursorScreenPosition, shape, cellWidth }; + return RenderCursor { .position = cursorScreenPosition, .shape = shape, .width = cellWidth }; } template @@ -250,9 +251,10 @@ RGBColorPair RenderBufferBuilder::makeColorsForCell(CellLocation gridPosit // clang-format on auto const selected = - _includeSelection && _terminal->isSelected(CellLocation { gridPosition.line, gridPosition.column }); + _includeSelection + && _terminal->isSelected(CellLocation { .line = gridPosition.line, .column = gridPosition.column }); auto const highlighted = - _terminal->isHighlighted(CellLocation { gridPosition.line, gridPosition.column }); + _terminal->isHighlighted(CellLocation { .line = gridPosition.line, .column = gridPosition.column }); auto const blink = _terminal->blinkState(); auto const rapidBlink = _terminal->rapidBlinkState(); @@ -290,7 +292,7 @@ template RenderLine RenderBufferBuilder::createRenderLine(TrivialLineBuffer const& lineBuffer, LineOffset lineOffset) const { - auto const pos = CellLocation { lineOffset, ColumnOffset(0) }; + auto const pos = CellLocation { .line = lineOffset, .column = ColumnOffset(0) }; auto const gridPosition = _terminal->viewport().translateScreenToGridCoordinate(pos); auto renderLine = RenderLine {}; renderLine.lineOffset = lineOffset; @@ -361,7 +363,7 @@ void RenderBufferBuilder::renderTrivialLine(TrivialLineBuffer const& lineB // render text _searchPatternOffset = 0; - renderUtf8Text(CellLocation { lineOffset, ColumnOffset(0) }, + renderUtf8Text(CellLocation { .line = lineOffset, .column = ColumnOffset(0) }, lineBuffer.textAttributes, lineBuffer.text.view(), true); @@ -369,7 +371,7 @@ void RenderBufferBuilder::renderTrivialLine(TrivialLineBuffer const& lineB // {{{ fill the remaining empty cells for (auto columnOffset = textMargin; columnOffset < pageColumnsEnd; ++columnOffset) { - auto const pos = CellLocation { lineOffset, columnOffset }; + auto const pos = CellLocation { .line = lineOffset, .column = columnOffset }; auto const gridPosition = _terminal->viewport().translateScreenToGridCoordinate(pos); auto renderAttributes = createRenderAttributes(gridPosition, lineBuffer.fillAttributes); @@ -431,8 +433,8 @@ void RenderBufferBuilder::matchSearchPattern(T const& cellText) auto const isFocusedMatch = CellLocationRange { - _output->cells[offsetIntoFront].position, - _output->cells.back().position, + .first = _output->cells[offsetIntoFront].position, + .second = _output->cells.back().position, } .contains( _terminal->viewport().translateGridToScreenCoordinate(_terminal->normalModeCursorPosition())); @@ -458,8 +460,8 @@ void RenderBufferBuilder::matchSearchPattern(T const& cellText) for (size_t i = offsetIntoFront; i < _output->cells.size(); ++i) { auto& cellAttributes = _output->cells[i].attributes; - auto const actualColors = - RGBColorPair { cellAttributes.foregroundColor, cellAttributes.backgroundColor }; + auto const actualColors = RGBColorPair { .foreground = cellAttributes.foregroundColor, + .background = cellAttributes.backgroundColor }; auto const searchMatchColors = makeRGBColorPair(actualColors, highlightColors); cellAttributes.backgroundColor = searchMatchColors.background; @@ -484,7 +486,8 @@ bool RenderBufferBuilder::isCursorLine(LineOffset line) const noexcept return _terminal->inputHandler().mode() != ViMode::Insert && _cursorPosition && line == _terminal->viewport() - .translateGridToScreenCoordinate(CellLocation { _cursorPosition->line, {} }) + .translateGridToScreenCoordinate( + CellLocation { .line = _cursorPosition->line, .column = {} }) .line; } @@ -596,7 +599,7 @@ bool RenderBufferBuilder::tryRenderInputMethodEditor(CellLocation screenPo template void RenderBufferBuilder::renderCell(Cell const& screenCell, LineOffset line, ColumnOffset column) { - auto const screenPosition = CellLocation { line, column }; + auto const screenPosition = CellLocation { .line = line, .column = column }; auto const gridPosition = _terminal->viewport().translateScreenToGridCoordinate(screenPosition); if (tryRenderInputMethodEditor(screenPosition, gridPosition)) diff --git a/src/vtbackend/Screen.cpp b/src/vtbackend/Screen.cpp index c5686417c1..d5965c5b00 100644 --- a/src/vtbackend/Screen.cpp +++ b/src/vtbackend/Screen.cpp @@ -340,9 +340,11 @@ void Screen::applyPageSizeToMainDisplay(PageSize mainDisplayPageSize) cursorPosition = _grid.resize(mainDisplayPageSize, cursorPosition, _cursor.wrapPending); cursorPosition = clampCoordinate(cursorPosition); - auto const margin = - Margin { Margin::Vertical { {}, mainDisplayPageSize.lines.as() - 1 }, - Margin::Horizontal { {}, mainDisplayPageSize.columns.as() - 1 } }; + auto const margin = Margin { + .vertical = Margin::Vertical { .from = {}, .to = mainDisplayPageSize.lines.as() - 1 }, + .horizontal = + Margin::Horizontal { .from = {}, .to = mainDisplayPageSize.columns.as() - 1 } + }; *_margin = margin; @@ -938,7 +940,7 @@ void Screen::sendTerminalId() // version number // TODO: (PACKAGE_VERSION_MAJOR * 100 + PACKAGE_VERSION_MINOR) * 100 + PACKAGE_VERSION_MICRO auto constexpr Pv = - (LIBTERMINAL_VERSION_MAJOR * 100 + LIBTERMINAL_VERSION_MINOR) * 100 + LIBTERMINAL_VERSION_PATCH; + (((LIBTERMINAL_VERSION_MAJOR * 100) + LIBTERMINAL_VERSION_MINOR) * 100) + LIBTERMINAL_VERSION_PATCH; // ROM cardridge registration number (always 0) auto constexpr Pc = 0; @@ -1032,7 +1034,10 @@ void Screen::selectiveEraseLine(LineOffset line) auto const left = ColumnOffset(0); auto const right = boxed_cast(pageSize().columns - 1); - auto const area = Rect { Top(*line), Left(*left), Bottom(*line), Right(*right) }; + auto const area = Rect { .top = unbox(line), + .left = unbox(left), + .bottom = unbox(line), + .right = unbox(right) }; _terminal->markRegionDirty(area); } @@ -1054,7 +1059,10 @@ void Screen::selectiveErase(LineOffset line, ColumnOffset begin, ColumnOff auto const left = begin; auto const right = end - 1; - auto const area = Rect { Top(*line), Left(*left), Bottom(*line), Right(*right) }; + auto const area = Rect { .top = unbox(line), + .left = unbox(left), + .bottom = unbox(line), + .right = unbox(right) }; _terminal->markRegionDirty(area); } @@ -1150,7 +1158,8 @@ void Screen::clearToEndOfLine() auto const line = _cursor.position.line; auto const left = _cursor.position.column; auto const right = boxed_cast(pageSize().columns - 1); - auto const area = Rect { Top(*line), Left(*left), Bottom(*line), Right(*right) }; + auto const area = + Rect { .top = Top(*line), .left = Left(*left), .bottom = Bottom(*line), .right = Right(*right) }; _terminal->markRegionDirty(area); } @@ -1168,7 +1177,8 @@ void Screen::clearToBeginOfLine() auto const line = _cursor.position.line; auto const left = ColumnOffset(0); auto const right = _cursor.position.column; - auto const area = Rect { Top(*line), Left(*left), Bottom(*line), Right(*right) }; + auto const area = + Rect { .top = Top(*line), .left = Left(*left), .bottom = Bottom(*line), .right = Right(*right) }; _terminal->markRegionDirty(area); } @@ -1180,7 +1190,8 @@ void Screen::clearLine() auto const line = _cursor.position.line; auto const left = ColumnOffset(0); auto const right = boxed_cast(pageSize().columns - 1); - auto const area = Rect { Top(*line), Left(*left), Bottom(*line), Right(*right) }; + auto const area = + Rect { .top = Top(*line), .left = Left(*left), .bottom = Bottom(*line), .right = Right(*right) }; _terminal->markRegionDirty(area); } // }}} @@ -1415,9 +1426,9 @@ void Screen::hyperlink(string id, string uri) } // We ignore the user id since we need to ensure it's unique. We generate our own. _cursor.hyperlink = _terminal->hyperlinks().nextHyperlinkId++; - _terminal->hyperlinks().cache.emplace( - _cursor.hyperlink, - make_shared(HyperlinkInfo { std::move(cacheId), std::move(uri) })); + _terminal->hyperlinks().cache.emplace(_cursor.hyperlink, + make_shared(HyperlinkInfo { + .userId = std::move(cacheId), .uri = std::move(uri) })); } // TODO: // Care about eviction. @@ -1548,7 +1559,7 @@ void Screen::captureBuffer(LineCount lineCount, bool logicalLines) size_t constexpr MaxChunkSize = 4096; size_t currentChunkSize = 0; - auto const pushContent = [&](auto const data) -> void { + auto const pushContent = [&](auto const& data) -> void { if (data.empty()) return; if (currentChunkSize == 0) // initiate chunk @@ -1813,7 +1824,7 @@ void Screen::sixelImage(ImageSize pixelSize, Image::Data&& rgbaData) ceil(pixelSize.width.as() / _terminal->cellPixelSize().width.as())); auto const lineCount = LineCount::cast_from( ceil(pixelSize.height.as() / _terminal->cellPixelSize().height.as())); - auto const extent = GridSize { lineCount, columnCount }; + auto const extent = GridSize { .lines = lineCount, .columns = columnCount }; auto const autoScrollAtBottomMargin = !_terminal->isModeEnabled(DECMode::NoSixelScrolling); auto const topLeft = autoScrollAtBottomMargin ? logicalCursorPosition() : CellLocation {}; @@ -1887,7 +1898,8 @@ void Screen::renderImage(shared_ptr image, for (GridSize::Offset const offset: GridSize { linesToBeRendered, columnsToBeRendered }) { Cell& cell = at(topLeft + offset); - cell.setImageFragment(rasterizedImage, CellLocation { offset.line, offset.column }); + cell.setImageFragment(rasterizedImage, + CellLocation { .line = offset.line, .column = offset.column }); cell.setHyperlink(_cursor.hyperlink); }; moveCursorTo(topLeft.line + offset, topLeft.column); @@ -3297,6 +3309,7 @@ void Screen::applyAndLog(Function const& function, Sequence const& seq) } template +// NOLINTNEXTLINE(readability-function-cognitive-complexity) ApplyResult Screen::apply(Function const& function, Sequence const& seq) { // This function assumed that the incoming instruction has been already resolved to a given @@ -3393,10 +3406,13 @@ ApplyResult Screen::apply(Function const& function, Sequence const& seq) auto const targetTop = LineOffset(seq.param_or(5, *origin.line + 1) - 1); auto const targetLeft = ColumnOffset(seq.param_or(6, *origin.column + 1) - 1); - auto const targetTopLeft = CellLocation { targetTop, targetLeft }; + auto const targetTopLeft = CellLocation { .line = targetTop, .column = targetLeft }; auto const targetPage = seq.param_or(7, 0); - copyArea(Rect { top, left, bottom, right }, page, targetTopLeft, targetPage); + copyArea(Rect { .top = top, .left = left, .bottom = bottom, .right = right }, + page, + targetTopLeft, + targetPage); } break; case DECERA: { diff --git a/src/vtbackend/Screen_test.cpp b/src/vtbackend/Screen_test.cpp index 81341da883..cfe63cf8fb 100644 --- a/src/vtbackend/Screen_test.cpp +++ b/src/vtbackend/Screen_test.cpp @@ -107,7 +107,7 @@ MockTerm screenForDECRA() } // namespace // }}} -// NOLINTBEGIN(misc-const-correctness) +// NOLINTBEGIN(misc-const-correctness,readability-function-cognitive-complexity) // {{{ writeText // AutoWrap disabled: text length is less then available columns in line. @@ -2089,18 +2089,19 @@ TEST_CASE("MoveCursorToNextTab", "[screen]") auto mock = MockTerm { PageSize { LineCount(3), ColumnCount(20) } }; auto& screen = mock.terminal.primaryScreen(); screen.moveCursorToNextTab(); - REQUIRE(screen.logicalCursorPosition() == CellLocation { LineOffset(0), ColumnOffset(1 * TabWidth + 0) }); + REQUIRE(screen.logicalCursorPosition() == CellLocation { LineOffset(0), ColumnOffset(TabWidth + 0) }); screen.moveCursorToColumn(ColumnOffset(TabWidth - 1)); screen.moveCursorToNextTab(); - REQUIRE(screen.logicalCursorPosition() == CellLocation { LineOffset(0), ColumnOffset(1 * TabWidth + 0) }); + REQUIRE(screen.logicalCursorPosition() == CellLocation { LineOffset(0), ColumnOffset(TabWidth + 0) }); screen.moveCursorToColumn(ColumnOffset(TabWidth - 1)); screen.moveCursorToNextTab(); - REQUIRE(screen.logicalCursorPosition() == CellLocation { LineOffset(0), ColumnOffset(1 * TabWidth + 0) }); + REQUIRE(screen.logicalCursorPosition() == CellLocation { LineOffset(0), ColumnOffset(TabWidth + 0) }); screen.moveCursorToNextTab(); - REQUIRE(screen.logicalCursorPosition() == CellLocation { LineOffset(0), ColumnOffset(2 * TabWidth + 0) }); + REQUIRE(screen.logicalCursorPosition() + == CellLocation { LineOffset(0), ColumnOffset((2 * TabWidth) + 0) }); screen.moveCursorToNextTab(); REQUIRE(screen.logicalCursorPosition() == CellLocation { LineOffset(0), ColumnOffset(19) }); @@ -3472,9 +3473,9 @@ TEST_CASE("DECCRA.Right.intersecting", "[screen]") "ghijkl\n"; auto constexpr Page = 0; - auto constexpr STopLeft = CellLocation { LineOffset(1), ColumnOffset(1) }; - auto constexpr SBottomRight = CellLocation { LineOffset(3), ColumnOffset(3) }; - auto constexpr TTopLeft = CellLocation { LineOffset(1), ColumnOffset(2) }; + auto constexpr STopLeft = CellLocation { .line = LineOffset(1), .column = ColumnOffset(1) }; + auto constexpr SBottomRight = CellLocation { .line = LineOffset(3), .column = ColumnOffset(3) }; + auto constexpr TTopLeft = CellLocation { .line = LineOffset(1), .column = ColumnOffset(2) }; auto const deccraSeq = std::format("\033[{};{};{};{};{};{};{};{}$v", STopLeft.line + 1, @@ -3510,9 +3511,9 @@ TEST_CASE("DECCRA.Left.intersecting", "[screen]") "ghijkl\n"; auto constexpr Page = 0; - auto constexpr STopLeft = CellLocation { LineOffset(1), ColumnOffset(3) }; - auto constexpr SBottomRight = CellLocation { LineOffset(2), ColumnOffset(5) }; - auto constexpr TTopLeft = CellLocation { LineOffset(1), ColumnOffset(2) }; + auto constexpr STopLeft = CellLocation { .line = LineOffset(1), .column = ColumnOffset(3) }; + auto constexpr SBottomRight = CellLocation { .line = LineOffset(2), .column = ColumnOffset(5) }; + auto constexpr TTopLeft = CellLocation { .line = LineOffset(1), .column = ColumnOffset(2) }; auto const deccraSeq = std::format("\033[{};{};{};{};{};{};{};{}$v", STopLeft.line + 1, @@ -3750,7 +3751,7 @@ TEST_CASE("LS1 and LS0", "[screen]") // TODO: SendDeviceAttributes // TODO: SendTerminalId -// NOLINTEND(misc-const-correctness) +// NOLINTEND(misc-const-correctness,readability-function-cognitive-complexity) // NOLINTBEGIN(misc-const-correctness) // NOLINTEND(misc-const-correctness) diff --git a/src/vtbackend/Selector.cpp b/src/vtbackend/Selector.cpp index b3dd408ef9..67aabf7b59 100644 --- a/src/vtbackend/Selector.cpp +++ b/src/vtbackend/Selector.cpp @@ -79,7 +79,7 @@ bool Selection::intersects(Rect area) const noexcept // TODO: make me more efficient for (auto line = area.top.as(); line <= area.bottom.as(); ++line) for (auto col = area.left.as(); col <= area.right.as(); ++col) - if (contains({ line, col })) + if (contains({ .line = line, .column = col })) return true; return false; @@ -171,12 +171,12 @@ CellLocation WordWiseSelection::extendSelectionForward(CellLocation pos) const n { current.line++; current.column = ColumnOffset(0); - current = stretchedColumn(_helper, { current.line, current.column + 1 }); + current = stretchedColumn(_helper, { .line = current.line, .column = current.column + 1 }); } if (*current.column + 1 < *_helper.pageSize().columns) { - current = stretchedColumn(_helper, { current.line, current.column + 1 }); + current = stretchedColumn(_helper, { .line = current.line, .column = current.column + 1 }); } else if (*current.line + 1 < *_helper.pageSize().lines) { @@ -260,7 +260,8 @@ vector RectangularSelection::ranges() const { auto const line = from.line + LineOffset::cast_from(i); auto const left = from.column; - auto const right = stretchedColumn(_helper, CellLocation { line, to.column }).column; + auto const right = + stretchedColumn(_helper, CellLocation { .line = line, .column = to.column }).column; result[i] = Range { line, left, right }; } @@ -274,7 +275,8 @@ FullLineSelection::FullLineSelection(SelectionHelper const& helper, Selection(helper, ViMode::VisualLine, start, std::move(onSelectionUpdated)) { _from.column = ColumnOffset(0); - extend(CellLocation { _to.line, boxed_cast(_helper.pageSize().columns - 1) }); + extend(CellLocation { .line = _to.line, + .column = boxed_cast(_helper.pageSize().columns - 1) }); } bool FullLineSelection::extend(CellLocation to) diff --git a/src/vtbackend/Selector_test.cpp b/src/vtbackend/Selector_test.cpp index 890a9e99ff..0e984e2050 100644 --- a/src/vtbackend/Selector_test.cpp +++ b/src/vtbackend/Selector_test.cpp @@ -76,7 +76,7 @@ template TextSelection(Screen const&) -> TextSelection; } // namespace -// NOLINTBEGIN(misc-const-correctness) +// NOLINTBEGIN(misc-const-correctness,readability-function-cognitive-complexity) TEST_CASE("Selector.Linear", "[selector]") { auto term = MockTerm(PageSize { LineCount(3), ColumnCount(11) }, LineCount(5)); @@ -94,7 +94,7 @@ TEST_CASE("Selector.Linear", "[selector]") SECTION("single-cell") { // "b" - auto const pos = CellLocation { LineOffset(1), ColumnOffset(1) }; + auto const pos = CellLocation { .line = LineOffset(1), .column = ColumnOffset(1) }; auto selector = LinearSelection(selectionHelper, pos, []() {}); (void) selector.extend(pos); selector.complete(); @@ -114,9 +114,9 @@ TEST_CASE("Selector.Linear", "[selector]") SECTION("forward single-line") { // "b,c" - auto const pos = CellLocation { LineOffset(1), ColumnOffset(1) }; + auto const pos = CellLocation { .line = LineOffset(1), .column = ColumnOffset(1) }; auto selector = LinearSelection(selectionHelper, pos, []() {}); - (void) selector.extend(CellLocation { LineOffset(1), ColumnOffset(3) }); + (void) selector.extend(CellLocation { .line = LineOffset(1), .column = ColumnOffset(3) }); selector.complete(); vector const selection = selector.ranges(); @@ -134,9 +134,9 @@ TEST_CASE("Selector.Linear", "[selector]") SECTION("forward multi-line") { // "b,cdefg,hi\n1234" - auto const pos = CellLocation { LineOffset(1), ColumnOffset(1) }; + auto const pos = CellLocation { .line = LineOffset(1), .column = ColumnOffset(1) }; auto selector = LinearSelection(selectionHelper, pos, []() {}); - (void) selector.extend(CellLocation { LineOffset(2), ColumnOffset(3) }); + (void) selector.extend(CellLocation { .line = LineOffset(2), .column = ColumnOffset(3) }); selector.complete(); vector const selection = selector.ranges(); @@ -171,9 +171,9 @@ TEST_CASE("Selector.Linear", "[selector]") 2 | "bar" */ - auto selector = - LinearSelection(selectionHelper, CellLocation { LineOffset(-2), ColumnOffset(6) }, []() {}); - (void) selector.extend(CellLocation { LineOffset(-1), ColumnOffset(2) }); + auto selector = LinearSelection( + selectionHelper, CellLocation { .line = LineOffset(-2), .column = ColumnOffset(6) }, []() {}); + (void) selector.extend(CellLocation { .line = LineOffset(-1), .column = ColumnOffset(2) }); selector.complete(); vector const selection = selector.ranges(); @@ -208,9 +208,9 @@ TEST_CASE("Selector.Linear", "[selector]") 2 | "" */ - auto selector = - LinearSelection(selectionHelper, CellLocation { LineOffset(-2), ColumnOffset(8) }, []() {}); - (void) selector.extend(CellLocation { LineOffset(0), ColumnOffset(1) }); + auto selector = LinearSelection( + selectionHelper, CellLocation { .line = LineOffset(-2), .column = ColumnOffset(8) }, []() {}); + (void) selector.extend(CellLocation { .line = LineOffset(0), .column = ColumnOffset(1) }); selector.complete(); vector const selection = selector.ranges(); @@ -254,4 +254,4 @@ TEST_CASE("Selector.Rectangular", "[selector]") { // TODO } -// NOLINTEND(misc-const-correctness) +// NOLINTEND(misc-const-correctness,readability-function-cognitive-complexity) diff --git a/src/vtbackend/SixelParser.cpp b/src/vtbackend/SixelParser.cpp index 9d42a827eb..47fb6e80ba 100644 --- a/src/vtbackend/SixelParser.cpp +++ b/src/vtbackend/SixelParser.cpp @@ -50,11 +50,11 @@ namespace if (t > 1) t -= 1; if (t < 1. / 6) - return p + (q - p) * 6 * t; + return p + ((q - p) * 6 * t); if (t < 1. / 2) return q; if (t < 2. / 3) - return p + (q - p) * (2. / 3 - t) * 6; + return p + ((q - p) * (2. / 3 - t) * 6); return p; } @@ -71,13 +71,13 @@ namespace } else { - auto const q = l < 0.5 ? l * (1 + s) : l + s - l * s; - auto const p = 2 * l - q; + auto const q = l < 0.5 ? l * (1 + s) : l + s - (l * s); + auto const p = (2 * l) - q; auto result = RGBColor {}; - result.red = static_cast(hue2rgb(p, q, h + 1. / 3) * 255); + result.red = static_cast(hue2rgb(p, q, h + (1. / 3)) * 255); result.green = static_cast(hue2rgb(p, q, h) * 255); - result.blue = static_cast(hue2rgb(p, q, h - 1. / 3) * 255); + result.blue = static_cast(hue2rgb(p, q, h - (1. / 3)) * 255); return result; } } @@ -371,7 +371,7 @@ void SixelImageBuilder::clear(RGBAColor fillColor) _sixelCursor = {}; auto* p = _buffer.data(); - auto* const e = p + _maxSize.area() * 4; + auto* const e = p + (_maxSize.area() * 4); while (p != e) { *p++ = fillColor.red(); @@ -385,7 +385,7 @@ RGBAColor SixelImageBuilder::at(CellLocation coord) const noexcept { auto const line = unbox(coord.line) % unbox(_size.height); auto const col = unbox(coord.column) % unbox(_size.width); - auto const base = line * unbox(_size.width) * 4 + col * 4; + auto const base = (line * unbox(_size.width) * 4) + (col * 4); const auto* const color = &_buffer[base]; return RGBAColor { color[0], color[1], color[2], color[3] }; } @@ -405,9 +405,9 @@ void SixelImageBuilder::write(CellLocation const& coord, RGBColor const& value) for (unsigned int i = 0; i < _aspectRatio; ++i) { - auto const base = (coord.line.as() + i) - * unbox((_explicitSize ? _size.width : _maxSize.width)) * 4u - + unbox(coord.column) * 4u; + auto const base = ((coord.line.as() + i) + * unbox((_explicitSize ? _size.width : _maxSize.width)) * 4u) + + (unbox(coord.column) * 4u); _buffer[base + 0] = value.red; _buffer[base + 1] = value.green; _buffer[base + 2] = value.blue; @@ -464,7 +464,7 @@ void SixelImageBuilder::render(int8_t sixel) for (unsigned int i = 0; i < 6; ++i) { auto const y = _sixelCursor.line + static_cast(i * _aspectRatio); - auto const pos = CellLocation { y, x }; + auto const pos = CellLocation { .line = y, .column = x }; auto const pin = 1 << i; auto const pinned = (sixel & pin) != 0; if (pinned) diff --git a/src/vtbackend/SixelParser_test.cpp b/src/vtbackend/SixelParser_test.cpp index 4cccc7d9ea..f7573c6ee1 100644 --- a/src/vtbackend/SixelParser_test.cpp +++ b/src/vtbackend/SixelParser_test.cpp @@ -41,7 +41,8 @@ TEST_CASE("SixelParser.ground_000000", "[sixel]") { for (int y = 0; y < ib.size().height.as(); ++y) { - auto const& actualColor = ib.at(CellLocation { LineOffset(y), ColumnOffset(x) }); + auto const& actualColor = + ib.at(CellLocation { .line = LineOffset(y), .column = ColumnOffset(x) }); CHECK(actualColor == DefaultColor); } } @@ -67,7 +68,8 @@ TEST_CASE("SixelParser.ground_111111", "[sixel]") { for (int y = 0; y < ib.size().height.as(); ++y) { - auto const& actualColor = ib.at(CellLocation { LineOffset(y), ColumnOffset(x) }); + auto const& actualColor = + ib.at(CellLocation { .line = LineOffset(y), .column = ColumnOffset(x) }); auto const pinned = x == 0 && y >= 0 && y <= 5; INFO(std::format("x={}, y={}, {}", x, y, pinned ? "pinned" : "")); if (pinned) @@ -99,7 +101,8 @@ TEST_CASE("SixelParser.ground_000001", "[sixel]") for (int y = 0; y < ib.size().height.as(); ++y) { INFO(std::format("x={}, y={}", x, y)); - auto const& actualColor = ib.at(CellLocation { LineOffset(y), ColumnOffset(x) }); + auto const& actualColor = + ib.at(CellLocation { .line = LineOffset(y), .column = ColumnOffset(x) }); auto const pinned = x == 0 && y == 0; if (pinned) CHECK(actualColor.rgb() == PinColor); @@ -130,7 +133,8 @@ TEST_CASE("SixelParser.ground_010101", "[sixel]") for (int y = 0; y < ib.size().height.as(); ++y) { INFO(std::format("x={}, y={}", x, y)); - auto const& actualColor = ib.at(CellLocation { LineOffset(y), ColumnOffset(x) }); + auto const& actualColor = + ib.at(CellLocation { .line = LineOffset(y), .column = ColumnOffset(x) }); auto const pinned = x == 0 && (y < 6 && y % 2 == 0); if (pinned) CHECK(actualColor.rgb() == PinColor); @@ -161,7 +165,8 @@ TEST_CASE("SixelParser.ground_101010", "[sixel]") for (int y = 0; y < ib.size().height.as(); ++y) { INFO(std::format("x={}, y={}", x, y)); - auto const& actualColor = ib.at(CellLocation { LineOffset(y), ColumnOffset(x) }); + auto const& actualColor = + ib.at(CellLocation { .line = LineOffset(y), .column = ColumnOffset(x) }); auto const pinned = x == 0 && (y < 6 && y % 2 != 0); if (pinned) CHECK(actualColor.rgb() == PinColor); @@ -227,7 +232,8 @@ TEST_CASE("SixelParser.rep", "[sixel]") { for (int y = 0; y < ib.size().height.as(); ++y) { - auto const& actualColor = ib.at(CellLocation { LineOffset(y), ColumnOffset(x) }); + auto const& actualColor = + ib.at(CellLocation { .line = LineOffset(y), .column = ColumnOffset(x) }); auto const pinned = x < 12 && y < 6; if (pinned) CHECK(actualColor.rgb() == PinColor); @@ -268,7 +274,7 @@ TEST_CASE("SixelParser.setAndUseColor", "[sixel]") { auto const& expectedColor = x < 5 && y < 6 ? PinColors.at(static_cast(x ? x : 4)) : DefaultColor; - auto const& actualColor = ib.at(CellLocation { LineOffset(y), ColumnOffset(x) }); + auto const& actualColor = ib.at(CellLocation { .line = LineOffset(y), .column = ColumnOffset(x) }); // INFO(std::format("at {}, expect {}, actual {}", // CellLocation { LineOffset(y), ColumnOffset(x) }, // expectedColor, @@ -304,7 +310,7 @@ TEST_CASE("SixelParser.rewind", "[sixel]") for (int x = 0; x < 4; ++x) { auto const expectedColor = x < 2 ? PinColors[2] : PinColors[1]; - auto const pos = CellLocation { LineOffset(y), ColumnOffset(x) }; + auto const pos = CellLocation { .line = LineOffset(y), .column = ColumnOffset(x) }; auto const actualColor = ib.at(pos); CHECK(actualColor == expectedColor); @@ -346,7 +352,7 @@ TEST_CASE("SixelParser.newline", "[sixel]") return PinColors[0]; }(x, y); - auto const pos = CellLocation { LineOffset(y), ColumnOffset(x) }; + auto const pos = CellLocation { .line = LineOffset(y), .column = ColumnOffset(x) }; auto const actualColor = ib.at(pos); CHECK(actualColor == expectedColor); diff --git a/src/vtbackend/StatusLineBuilder.cpp b/src/vtbackend/StatusLineBuilder.cpp index bf2cf9f726..2774375421 100644 --- a/src/vtbackend/StatusLineBuilder.cpp +++ b/src/vtbackend/StatusLineBuilder.cpp @@ -471,7 +471,7 @@ struct VTSerializer std::string serializeToVT(Terminal const& vt, StatusLineSegment const& segment, StatusLineStyling styling) { - auto serializer = VTSerializer { vt, styling }; + auto serializer = VTSerializer { .vt = vt, .styling = styling }; for (auto const& item: segment) serializer(item); return serializer.result; diff --git a/src/vtbackend/Terminal.cpp b/src/vtbackend/Terminal.cpp index c60d75f115..d9fd970c90 100644 --- a/src/vtbackend/Terminal.cpp +++ b/src/vtbackend/Terminal.cpp @@ -92,7 +92,7 @@ namespace // {{{ helpers constexpr CellLocation raiseToMinimum(CellLocation location, LineOffset minimumLine) noexcept { - return CellLocation { std::max(location.line, minimumLine), location.column }; + return CellLocation { .line = std::max(location.line, minimumLine), .column = location.column }; } } // namespace @@ -141,12 +141,18 @@ Terminal::Terminal(Events& eventListener, _cellPixelSize {}, _defaultColorPalette { _settings.colorPalette }, _colorPalette { _settings.colorPalette }, - _mainScreenMargin { Margin::Vertical { {}, _settings.pageSize.lines.as() - LineOffset(1) }, - Margin::Horizontal { - {}, _settings.pageSize.columns.as() - ColumnOffset(1) } }, - _hostWritableScreenMargin { Margin::Vertical { {}, LineOffset(0) }, - Margin::Horizontal { - {}, _settings.pageSize.columns.as() - ColumnOffset(1) } }, + _mainScreenMargin { + .vertical = + Margin::Vertical { .from = {}, .to = _settings.pageSize.lines.as() - LineOffset(1) }, + .horizontal = + Margin::Horizontal { .from = {}, + .to = _settings.pageSize.columns.as() - ColumnOffset(1) } + }, + _hostWritableScreenMargin { .vertical = Margin::Vertical { .from = {}, .to = LineOffset(0) }, + .horizontal = + Margin::Horizontal { .from = {}, + .to = _settings.pageSize.columns.as() + - ColumnOffset(1) } }, _maxSixelColorRegisters { _settings.maxImageRegisterCount }, _effectiveImageCanvasSize { _settings.maxImageSize }, _sixelColorPalette { std::make_shared(_maxSixelColorRegisters, @@ -154,7 +160,7 @@ Terminal::Terminal(Events& eventListener, _imagePool { [this](Image const* image) { discardImage(*image); } }, - _hyperlinks { HyperlinkCache { 1024 } }, + _hyperlinks { .cache = HyperlinkCache { 1024 } }, _sequenceBuilder { ModeDependantSequenceHandler { *this }, TerminalInstructionCounter { *this } }, _parser { std::ref(_sequenceBuilder) }, _viCommands { *this }, @@ -725,8 +731,8 @@ bool Terminal::handleMouseSelection(Modifiers modifiers) _speedClicks = (diffMs >= 0.0 && diffMs <= 1000.0 ? _speedClicks : 0) % 4 + 1; auto const startPos = CellLocation { - _currentMousePosition.line - boxed_cast(_viewport.scrollOffset()), - _currentMousePosition.column, + .line = _currentMousePosition.line - boxed_cast(_viewport.scrollOffset()), + .column = _currentMousePosition.column, }; if (_inputHandler.mode() != ViMode::Insert) @@ -768,8 +774,8 @@ void Terminal::triggerWordWiseSelectionWithCustomDelimiters(string const& delimi { verifyState(); auto const startPos = CellLocation { - _currentMousePosition.line - boxed_cast(_viewport.scrollOffset()), - _currentMousePosition.column, + .line = _currentMousePosition.line - boxed_cast(_viewport.scrollOffset()), + .column = _currentMousePosition.column, }; if (_inputHandler.mode() != ViMode::Insert) _viCommands.cursorPosition = startPos; @@ -1225,9 +1231,11 @@ void Terminal::resizeScreen(PageSize totalPageSize, optional pixels) setCellPixelSize(pixels.value() / mainDisplayPageSize); // Reset margin to their default. - _primaryScreen.margin() = - Margin { Margin::Vertical { {}, mainDisplayPageSize.lines.as() - 1 }, - Margin::Horizontal { {}, mainDisplayPageSize.columns.as() - 1 } }; + _primaryScreen.margin() = Margin { + .vertical = Margin::Vertical { .from = {}, .to = mainDisplayPageSize.lines.as() - 1 }, + .horizontal = + Margin::Horizontal { .from = {}, .to = mainDisplayPageSize.columns.as() - 1 } + }; _alternateScreen.margin() = _primaryScreen.margin(); applyPageSizeToCurrentBuffer(); @@ -1601,6 +1609,7 @@ void Terminal::setMode(AnsiMode mode, bool enable) _modes.set(mode, enable); } +// NOLINTNEXTLINE(readability-function-cognitive-complexity) void Terminal::setMode(DECMode mode, bool enable) { if (!isValidDECMode(static_cast(mode))) @@ -1627,8 +1636,8 @@ void Terminal::setMode(DECMode mode, bool enable) if (!enable) { _mainScreenMargin.horizontal = - Margin::Horizontal { ColumnOffset(0), - boxed_cast(_settings.pageSize.columns - 1) }; + Margin::Horizontal { .from = ColumnOffset(0), + .to = boxed_cast(_settings.pageSize.columns - 1) }; _supportedVTSequences.enableSequence(SCOSC); _supportedVTSequences.disableSequence(DECSLRM); } @@ -1898,9 +1907,14 @@ void Terminal::hardReset() resetColorPalette(); _hostWritableStatusLineScreen.margin() = Margin { - Margin::Vertical { {}, boxed_cast(_hostWritableStatusLineScreen.pageSize().lines) - 1 }, - Margin::Horizontal { {}, - boxed_cast(_hostWritableStatusLineScreen.pageSize().columns) - 1 } + .vertical = + Margin::Vertical { .from = {}, + .to = boxed_cast(_hostWritableStatusLineScreen.pageSize().lines) + - 1 }, + .horizontal = + Margin::Horizontal { + .from = {}, + .to = boxed_cast(_hostWritableStatusLineScreen.pageSize().columns) - 1 }, }; _hostWritableStatusLineScreen.verifyState(); @@ -1910,14 +1924,20 @@ void Terminal::hardReset() auto const mainDisplayPageSize = _settings.pageSize - statusLineHeight(); - _primaryScreen.margin() = - Margin { Margin::Vertical { {}, boxed_cast(mainDisplayPageSize.lines) - 1 }, - Margin::Horizontal { {}, boxed_cast(mainDisplayPageSize.columns) - 1 } }; + _primaryScreen.margin() = Margin { + .vertical = + Margin::Vertical { .from = {}, .to = boxed_cast(mainDisplayPageSize.lines) - 1 }, + .horizontal = Margin::Horizontal { .from = {}, + .to = boxed_cast(mainDisplayPageSize.columns) - 1 }, + }; _primaryScreen.verifyState(); - _alternateScreen.margin() = - Margin { Margin::Vertical { {}, boxed_cast(mainDisplayPageSize.lines) - 1 }, - Margin::Horizontal { {}, boxed_cast(mainDisplayPageSize.columns) - 1 } }; + _alternateScreen.margin() = Margin { + .vertical = + Margin::Vertical { .from = {}, .to = boxed_cast(mainDisplayPageSize.lines) - 1 }, + .horizontal = Margin::Horizontal { .from = {}, + .to = boxed_cast(mainDisplayPageSize.columns) - 1 }, + }; alternateScreen().margin() = _primaryScreen.margin(); // NB: We do *NOT* verify alternate screen, because the page size would probably fail as it is // designed to be adjusted when the given screen is activated. @@ -1993,8 +2013,9 @@ void Terminal::applyPageSizeToMainDisplay(ScreenType screenType) // adjust margins for statuslines as well auto const statuslineMargin = - Margin { Margin::Vertical { {}, statusLineHeight().as() - 1 }, - Margin::Horizontal { {}, _settings.pageSize.columns.as() - 1 } }; + Margin { .vertical = Margin::Vertical { .from = {}, .to = statusLineHeight().as() - 1 }, + .horizontal = Margin::Horizontal { + .from = {}, .to = _settings.pageSize.columns.as() - 1 } }; _indicatorScreenMargin = statuslineMargin; _hostWritableScreenMargin = statuslineMargin; @@ -2333,7 +2354,7 @@ void Terminal::setHighlightRange(HighlightRange highlightRange) { auto range = std::get(highlightRange); auto points = orderedPoints(range.from, range.to); - range = RectangularHighlight { points.first, points.second }; + range = RectangularHighlight { .from = points.first, .to = points.second }; } _highlightRange = highlightRange; _eventListener.updateHighlights(); @@ -2424,7 +2445,7 @@ void TraceHandler::writeText(char32_t codepoint) void TraceHandler::writeText(std::string_view codepoints, size_t cellCount) { - _pendingSequences.emplace_back(CodepointSequence { codepoints, cellCount }); + _pendingSequences.emplace_back(CodepointSequence { .text = codepoints, .cellCount = cellCount }); } void TraceHandler::writeTextEnd() diff --git a/src/vtbackend/ViCommands.cpp b/src/vtbackend/ViCommands.cpp index b0c034a624..d4193e195e 100644 --- a/src/vtbackend/ViCommands.cpp +++ b/src/vtbackend/ViCommands.cpp @@ -317,11 +317,11 @@ void ViCommands::executeYank(ViMotion motion, unsigned count) case ViMotion::Selection: { assert(_terminal->selector()); if (_lastMode == ViMode::VisualBlock) - _terminal->setHighlightRange( - RectangularHighlight { _terminal->selector()->from(), _terminal->selector()->to() }); + _terminal->setHighlightRange(RectangularHighlight { .from = _terminal->selector()->from(), + .to = _terminal->selector()->to() }); else - _terminal->setHighlightRange( - LinearHighlight { _terminal->selector()->from(), _terminal->selector()->to() }); + _terminal->setHighlightRange(LinearHighlight { .from = _terminal->selector()->from(), + .to = _terminal->selector()->to() }); _terminal->copyToClipboard(_terminal->extractSelectionText()); _terminal->inputHandler().setMode(ViMode::Normal); break; @@ -330,7 +330,7 @@ void ViCommands::executeYank(ViMotion motion, unsigned count) auto const [from, to] = translateToCellRange(motion, count); // motion is inclusive but for yank we want to exclude the last cell which is the first cell of // the next word - executeYank(from, { to.line, to.column - 1 }); + executeYank(from, { .line = to.line, .column = to.column - 1 }); } break; } @@ -354,7 +354,7 @@ std::string ViCommands::extractTextAndHighlightRange(CellLocation from, CellLoca auto text = _terminal->extractSelectionText(); _terminal->clearSelection(); - _terminal->setHighlightRange(LinearHighlight { from, to }); + _terminal->setHighlightRange(LinearHighlight { .from = from, .to = to }); _terminal->inputHandler().setMode(ViMode::Normal); _terminal->screenUpdated(); return text; @@ -377,11 +377,11 @@ void ViCommands::executeOpen(ViMotion motion, unsigned count) case ViMotion::Selection: { assert(_terminal->selector()); if (_lastMode == ViMode::VisualBlock) - _terminal->setHighlightRange( - RectangularHighlight { _terminal->selector()->from(), _terminal->selector()->to() }); + _terminal->setHighlightRange(RectangularHighlight { .from = _terminal->selector()->from(), + .to = _terminal->selector()->to() }); else - _terminal->setHighlightRange( - LinearHighlight { _terminal->selector()->from(), _terminal->selector()->to() }); + _terminal->setHighlightRange(LinearHighlight { .from = _terminal->selector()->from(), + .to = _terminal->selector()->to() }); _terminal->copyToClipboard(_terminal->extractSelectionText()); @@ -488,7 +488,7 @@ void ViCommands::paste(unsigned count, bool stripped) CellLocation ViCommands::prev(CellLocation location) const noexcept { if (location.column.value > 0) - return { location.line, location.column - 1 }; + return { .line = location.line, .column = location.column - 1 }; auto const topLineOffset = _terminal->isPrimaryScreen() ? -boxed_cast(_terminal->primaryScreen().historyLineCount()) @@ -509,7 +509,7 @@ CellLocation ViCommands::next(CellLocation location) const noexcept if (location.column < rightMargin) { auto const width = max(uint8_t { 1 }, _terminal->currentScreen().cellWidthAt(location)); - return { location.line, location.column + ColumnOffset::cast_from(width) }; + return { .line = location.line, .column = location.column + ColumnOffset::cast_from(width) }; } if (location.line < boxed_cast(_terminal->pageSize().lines - 1)) @@ -609,7 +609,7 @@ CellLocationRange ViCommands::expandMatchingPair(TextObjectScope scope, char lef b = prev(b); } - return { a, b }; + return { .first = a, .second = b }; } CellLocationRange ViCommands::translateToCellRange(TextObjectScope scope, @@ -665,7 +665,7 @@ CellLocationRange ViCommands::translateToCellRange(TextObjectScope scope, break; } } - return { a, b }; + return { .first = a, .second = b }; } CellLocationRange ViCommands::translateToCellRange(ViMotion motion, unsigned count) noexcept @@ -673,19 +673,20 @@ CellLocationRange ViCommands::translateToCellRange(ViMotion motion, unsigned cou switch (motion) { case ViMotion::FullLine: - return { cursorPosition - cursorPosition.column, - { cursorPosition.line, _terminal->pageSize().columns.as() - 1 } }; + return { .first = cursorPosition - cursorPosition.column, + .second = { .line = cursorPosition.line, + .column = _terminal->pageSize().columns.as() - 1 } }; default: //. - return { cursorPosition, translateToCellLocationAndRecord(motion, count) }; + return { .first = cursorPosition, .second = translateToCellLocationAndRecord(motion, count) }; } } CellLocation ViCommands::findBeginOfWordAt(CellLocation location, JumpOver jumpOver) const noexcept { auto const firstAddressableLocation = - CellLocation { -LineOffset::cast_from(_terminal->currentScreen().historyLineCount()), - ColumnOffset(0) }; + CellLocation { .line = -LineOffset::cast_from(_terminal->currentScreen().historyLineCount()), + .column = ColumnOffset(0) }; auto current = location; auto leftLocation = prev(current); @@ -745,7 +746,7 @@ bool ViCommands::compareCellTextAt(CellLocation position, char32_t codepoint) co CellLocation ViCommands::globalCharUp(CellLocation location, char ch, unsigned count) const noexcept { auto const pageTop = -_terminal->currentScreen().historyLineCount().as(); - auto result = CellLocation { location.line, ColumnOffset(0) }; + auto result = CellLocation { .line = location.line, .column = ColumnOffset(0) }; while (count > 0) { if (location.column == ColumnOffset(0) && result.line > pageTop) @@ -765,7 +766,7 @@ CellLocation ViCommands::globalCharUp(CellLocation location, char ch, unsigned c CellLocation ViCommands::globalCharDown(CellLocation location, char ch, unsigned count) const noexcept { auto const pageBottom = _terminal->pageSize().lines.as() - 1; - auto result = CellLocation { location.line, ColumnOffset(0) }; + auto result = CellLocation { .line = location.line, .column = ColumnOffset(0) }; while (count > 0) { if (location.column == ColumnOffset(0) && result.line < pageBottom) @@ -782,6 +783,7 @@ CellLocation ViCommands::globalCharDown(CellLocation location, char ch, unsigned return result; } +// NOLINTNEXTLINE(readability-function-cognitive-complexity) CellLocation ViCommands::translateToCellLocationAndRecord(ViMotion motion, unsigned count) noexcept { auto addJumpHistory = [this](CellLocation const& location) { @@ -812,63 +814,63 @@ CellLocation ViCommands::translateToCellLocationAndRecord(ViMotion motion, unsig return resultPosition; } case ViMotion::ScreenColumn: // | - return snapToCell({ cursorPosition.line, - min(ColumnOffset::cast_from(count - 1), - _terminal->pageSize().columns.as() - 1) }); + return snapToCell({ .line = cursorPosition.line, + .column = min(ColumnOffset::cast_from(count - 1), + _terminal->pageSize().columns.as() - 1) }); case ViMotion::FileBegin: // gg return snapToCell( - { LineOffset::cast_from(-_terminal->currentScreen().historyLineCount().as()), - ColumnOffset(0) }); + { .line = LineOffset::cast_from(-_terminal->currentScreen().historyLineCount().as()), + .column = ColumnOffset(0) }); case ViMotion::FileEnd: // G - return addJumpHistory( - snapToCell({ _terminal->pageSize().lines.as() - 1, ColumnOffset(0) })); + return addJumpHistory(snapToCell( + { .line = _terminal->pageSize().lines.as() - 1, .column = ColumnOffset(0) })); case ViMotion::PageTop: // - return snapToCell({ boxed_cast(-_terminal->viewport().scrollOffset()) - + *_terminal->viewport().scrollOff(), - ColumnOffset(0) }); + return snapToCell({ .line = boxed_cast(-_terminal->viewport().scrollOffset()) + + *_terminal->viewport().scrollOff(), + .column = ColumnOffset(0) }); case ViMotion::PageBottom: // - return snapToCell({ boxed_cast(-_terminal->viewport().scrollOffset()) - + boxed_cast(_terminal->pageSize().lines - - *_terminal->viewport().scrollOff() - 1), - ColumnOffset(0) }); + return snapToCell({ .line = boxed_cast(-_terminal->viewport().scrollOffset()) + + boxed_cast(_terminal->pageSize().lines + - *_terminal->viewport().scrollOff() - 1), + .column = ColumnOffset(0) }); case ViMotion::LineBegin: // 0 - return { cursorPosition.line, ColumnOffset(0) }; + return { .line = cursorPosition.line, .column = ColumnOffset(0) }; case ViMotion::LineTextBegin: // ^ { - auto result = CellLocation { cursorPosition.line, ColumnOffset(0) }; + auto result = CellLocation { .line = cursorPosition.line, .column = ColumnOffset(0) }; while (result.column < _terminal->pageSize().columns.as() - 1 && _terminal->currentScreen().isCellEmpty(result)) ++result.column; return result; } case ViMotion::LineDown: // j - return { min(cursorPosition.line + LineOffset::cast_from(count), - _terminal->pageSize().lines.as() - 1), - cursorPosition.column }; + return { .line = min(cursorPosition.line + LineOffset::cast_from(count), + _terminal->pageSize().lines.as() - 1), + .column = cursorPosition.column }; case ViMotion::LineEnd: // $ return getRightMostNonEmptyCellLocation(*_terminal, cursorPosition.line); case ViMotion::LineUp: // k - return { max(cursorPosition.line - LineOffset::cast_from(count), - -_terminal->currentScreen().historyLineCount().as()), - cursorPosition.column }; + return { .line = max(cursorPosition.line - LineOffset::cast_from(count), + -_terminal->currentScreen().historyLineCount().as()), + .column = cursorPosition.column }; case ViMotion::LinesCenter: // M - return addJumpHistory({ LineOffset::cast_from(_terminal->pageSize().lines / 2 - 1) - - boxed_cast(_terminal->viewport().scrollOffset()), - cursorPosition.column }); + return addJumpHistory({ .line = LineOffset::cast_from(_terminal->pageSize().lines / 2 - 1) + - boxed_cast(_terminal->viewport().scrollOffset()), + .column = cursorPosition.column }); case ViMotion::PageDown: - return { min(cursorPosition.line + LineOffset::cast_from(_terminal->pageSize().lines / 2), - _terminal->pageSize().lines.as() - 1), - cursorPosition.column }; + return { .line = min(cursorPosition.line + LineOffset::cast_from(_terminal->pageSize().lines / 2), + _terminal->pageSize().lines.as() - 1), + .column = cursorPosition.column }; case ViMotion::PageUp: - return { max(cursorPosition.line - LineOffset::cast_from(_terminal->pageSize().lines / 2), - -_terminal->currentScreen().historyLineCount().as()), - cursorPosition.column }; + return { .line = max(cursorPosition.line - LineOffset::cast_from(_terminal->pageSize().lines / 2), + -_terminal->currentScreen().historyLineCount().as()), + .column = cursorPosition.column }; return cursorPosition - min(cursorPosition.line, LineOffset::cast_from(_terminal->pageSize().lines) / 2); case ViMotion::ParagraphBackward: // { { auto const pageTop = -_terminal->currentScreen().historyLineCount().as(); - auto prev = CellLocation { cursorPosition.line, ColumnOffset(0) }; + auto prev = CellLocation { .line = cursorPosition.line, .column = ColumnOffset(0) }; if (prev.line.value > 0) prev.line--; auto current = prev; @@ -892,7 +894,7 @@ CellLocation ViCommands::translateToCellLocationAndRecord(ViMotion motion, unsig case ViMotion::LineMarkUp: // [m { auto const gridTop = -_terminal->currentScreen().historyLineCount().as(); - auto result = CellLocation { cursorPosition.line, ColumnOffset(0) }; + auto result = CellLocation { .line = cursorPosition.line, .column = ColumnOffset(0) }; while (count > 0) { if (result.line > gridTop @@ -908,7 +910,7 @@ CellLocation ViCommands::translateToCellLocationAndRecord(ViMotion motion, unsig case ViMotion::LineMarkDown: // ]m { auto const pageBottom = _terminal->pageSize().lines.as() - 1; - auto result = CellLocation { cursorPosition.line, ColumnOffset(0) }; + auto result = CellLocation { .line = cursorPosition.line, .column = ColumnOffset(0) }; while (count > 0) { if (cursorPosition.column == ColumnOffset(0) && result.line < pageBottom) @@ -926,7 +928,7 @@ CellLocation ViCommands::translateToCellLocationAndRecord(ViMotion motion, unsig case ViMotion::ParagraphForward: // } { auto const pageBottom = _terminal->pageSize().lines.as() - 1; - auto prev = CellLocation { cursorPosition.line, ColumnOffset(0) }; + auto prev = CellLocation { .line = cursorPosition.line, .column = ColumnOffset(0) }; if (prev.line < pageBottom) prev.line++; auto current = prev; @@ -1038,8 +1040,8 @@ CellLocation ViCommands::translateToCellLocationAndRecord(ViMotion motion, unsig case ViMotion::WordForward: // w { auto const lastAddressableLocation = - CellLocation { LineOffset::cast_from(_terminal->pageSize().lines - 1), - ColumnOffset::cast_from(_terminal->pageSize().columns - 1) }; + CellLocation { .line = LineOffset::cast_from(_terminal->pageSize().lines - 1), + .column = ColumnOffset::cast_from(_terminal->pageSize().columns - 1) }; auto result = cursorPosition; while (count > 0) { diff --git a/src/vtbackend/ViCommands_test.cpp b/src/vtbackend/ViCommands_test.cpp index 68dbb52063..1b3b92bad6 100644 --- a/src/vtbackend/ViCommands_test.cpp +++ b/src/vtbackend/ViCommands_test.cpp @@ -46,8 +46,8 @@ auto setupMockTerminal(std::string_view text, { return vtbackend::MockTerm { vtpty::PageSize { // increment line count by one for indicator statusline. - pageSize.lines + 1, - pageSize.columns }, + .lines = pageSize.lines + 1, + .columns = pageSize.columns }, history, 1024, // ptyReadBufferSize [text](auto& mock) { diff --git a/src/vtbackend/ViInputHandler.cpp b/src/vtbackend/ViInputHandler.cpp index d06322f686..d244d697fa 100644 --- a/src/vtbackend/ViInputHandler.cpp +++ b/src/vtbackend/ViInputHandler.cpp @@ -441,7 +441,7 @@ Handled ViInputHandler::handleSearchEditor(char32_t ch, Modifiers modifiers) { assert(_searchEditMode != SearchEditMode::Disabled); - switch (InputMatch { modifiers, ch }) + switch (InputMatch { .modifiers = modifiers, .ch = ch }) { case '\x1B'_key: _searchTerm.clear(); diff --git a/src/vtbackend/Viewport.cpp b/src/vtbackend/Viewport.cpp index f7e176e273..ab2dad8a01 100644 --- a/src/vtbackend/Viewport.cpp +++ b/src/vtbackend/Viewport.cpp @@ -64,7 +64,7 @@ CellLocation Viewport::clampCellLocation(CellLocation const& location) const noe auto const line = std::clamp(location.line, viewportTop, viewportBottom); auto const column = std::clamp(location.column, viewportLeft, viewportRight); - return CellLocation { line, column }; + return CellLocation { .line = line, .column = column }; } bool Viewport::makeVisibleWithinSafeArea(LineOffset lineOffset, LineCount paddingLines) diff --git a/src/vtparser/Parser.cpp b/src/vtparser/Parser.cpp index f68d4ae35d..0d709ecbfe 100644 --- a/src/vtparser/Parser.cpp +++ b/src/vtparser/Parser.cpp @@ -13,12 +13,11 @@ namespace vtparser using ranges::views::enumerate; -void parserTableDot(std::ostream& os) // {{{ +auto fillTransitions() { using Transition = std::pair; using Range = ParserTable::Range; using RangeSet = std::vector; - ParserTable const& table = ParserTable::get(); // (State, Byte) -> State auto transitions = std::map {}; @@ -39,7 +38,13 @@ void parserTableDot(std::ostream& os) // {{{ } } } + return transitions; +} + +void parserTableDot(std::ostream& os) // {{{ +{ // TODO: isReachableFromAnywhere(targetState) to check if x can be reached from anywhere. + auto const transitions = fillTransitions(); os << "digraph {\n"; os << " node [shape=box];\n"; diff --git a/src/vtparser/Parser.h b/src/vtparser/Parser.h index 61b018b407..ff9e627146 100644 --- a/src/vtparser/Parser.h +++ b/src/vtparser/Parser.h @@ -740,7 +740,7 @@ inline std::pair extractCodePrefix(T const& data) noexcept } void parserTableDot(std::ostream& os); - +auto fillTransitions(); } // end namespace vtparser #include diff --git a/src/vtpty/MockPty.cpp b/src/vtpty/MockPty.cpp index acb8e9aa4a..d77c4c30b6 100644 --- a/src/vtpty/MockPty.cpp +++ b/src/vtpty/MockPty.cpp @@ -22,8 +22,7 @@ std::optional MockPty::read(crispy::buffer_object& storag std::optional /*timeout*/, size_t size) { - auto const n = - std::min(size, std::min(_outputBuffer.size() - _outputReadOffset, storage.bytesAvailable())); + auto const n = std::min({ size, _outputBuffer.size() - _outputReadOffset, storage.bytesAvailable() }); auto const chunk = string_view { _outputBuffer.data() + _outputReadOffset, n }; _outputReadOffset += n; auto const pooled = storage.writeAtEnd(chunk); diff --git a/src/vtpty/MockViewPty.cpp b/src/vtpty/MockViewPty.cpp index cbbbd467e4..c26b32bf9b 100644 --- a/src/vtpty/MockViewPty.cpp +++ b/src/vtpty/MockViewPty.cpp @@ -22,7 +22,7 @@ std::optional MockViewPty::read(crispy::buffer_object& st std::optional /*timeout*/, size_t size) { - auto const n = std::min(std::min(_outputBuffer.size(), storage.bytesAvailable()), size); + auto const n = std::min({ _outputBuffer.size(), storage.bytesAvailable(), size }); auto result = storage.writeAtEnd(_outputBuffer.substr(0, n)); _outputBuffer.remove_prefix(n); return ReadResult { .data = std::string_view(result.data(), result.size()), .fromStdoutFastPipe = false }; diff --git a/src/vtpty/Process_unix.cpp b/src/vtpty/Process_unix.cpp index 31ec34e740..238c658940 100644 --- a/src/vtpty/Process_unix.cpp +++ b/src/vtpty/Process_unix.cpp @@ -103,7 +103,13 @@ Process::Process(string const& path, Environment const& env, bool escapeSandbox, unique_ptr pty): - _d(new Private { path, args, cwd, env, escapeSandbox, std::move(pty) }, [](Private* p) { delete p; }) + _d(new Private { .path = path, + .args = args, + .cwd = cwd, + .env = env, + .escapeSandbox = escapeSandbox, + .pty = std::move(pty) }, + [](Private* p) { delete p; }) { } diff --git a/src/vtpty/SshSession.cpp b/src/vtpty/SshSession.cpp index a12611e439..51bcaa7805 100644 --- a/src/vtpty/SshSession.cpp +++ b/src/vtpty/SshSession.cpp @@ -383,6 +383,89 @@ void SshSession::setState(State nextState) } } +bool SshSession::requestPty() +{ + // Mode encoding defined here: https://datatracker.ietf.org/doc/html/rfc4250#section-4.5 + auto const modes = ""sv; + auto const term = _config.env.count("TERM") ? _config.env.at("TERM") : ""s; + auto const rc = libssh2_channel_request_pty_ex(_p->sshChannel, + term.data(), + term.size(), + modes.data(), + modes.size(), + _pageSize.columns.as(), + _pageSize.lines.as(), + _pixels.has_value() ? _pixels->width.as() : 0, + _pixels.has_value() ? _pixels->height.as() : 0); + if (rc == LIBSSH2_ERROR_EAGAIN) + { + _p->wantsWaitForSocket = true; + return false; + } + if (rc != LIBSSH2_ERROR_NONE) + { + logError("Failed to request PTY. {}", libssl2ErrorString(rc)); + setState(State::Failure); + return false; + } + setState(State::SetEnv); + _walkIndex = 0; + return true; +} + +bool SshSession::setEnv() +{ + int i = 0; + for (auto const& [name, value]: _config.env) + { + // Skip already set environment variables + if (i < _walkIndex) + { + ++i; + continue; + } + + if (name == "TERM") + continue; // passed later via requestPty() + + int const rc = + libssh2_channel_setenv_ex(_p->sshChannel, name.data(), name.size(), value.data(), value.size()); + if (rc == LIBSSH2_ERROR_EAGAIN) + { + _walkIndex = i; // remember where we left off + _p->wantsWaitForSocket = true; // and wait for socket to become writable + return false; + } + if (rc != LIBSSH2_ERROR_NONE) + { + logError("Failed to set SSH environment variable \"{}\". {}", name, libssl2ErrorString(rc)); + } + } + setState(State::StartShell); + return true; +} + +void SshSession::resizeScreen() +{ + auto const rc = + libssh2_channel_request_pty_size_ex(_p->sshChannel, + unbox(_pageSize.columns), + unbox(_pageSize.lines), + _pixels.has_value() ? unbox(_pixels->width) : 0, + _pixels.has_value() ? unbox(_pixels->height) : 0); + if (rc == LIBSSH2_ERROR_EAGAIN) + { + _p->wantsWaitForSocket = true; + return; + } + if (rc != LIBSSH2_ERROR_NONE) + { + logError("Failed to request PTY resize. {}", libssl2ErrorString(rc)); + return; + } + setState(State::Operational); +} + void SshSession::processState() { waitForSocket(); @@ -505,64 +588,14 @@ void SshSession::processState() [[fallthrough]]; } case State::RequestPty: { - // Mode encoding defined here: https://datatracker.ietf.org/doc/html/rfc4250#section-4.5 - auto const modes = ""sv; - auto const term = _config.env.count("TERM") ? _config.env.at("TERM") : ""s; - auto const rc = - libssh2_channel_request_pty_ex(_p->sshChannel, - term.data(), - term.size(), - modes.data(), - modes.size(), - _pageSize.columns.as(), - _pageSize.lines.as(), - _pixels.has_value() ? _pixels->width.as() : 0, - _pixels.has_value() ? _pixels->height.as() : 0); - if (rc == LIBSSH2_ERROR_EAGAIN) - { - _p->wantsWaitForSocket = true; - return; - } - if (rc != LIBSSH2_ERROR_NONE) - { - logError("Failed to request PTY. {}", libssl2ErrorString(rc)); - setState(State::Failure); + if (!requestPty()) return; - } - setState(State::SetEnv); - _walkIndex = 0; + [[fallthrough]]; } case State::SetEnv: { - int i = 0; - for (auto const& [name, value]: _config.env) - { - // Skip already set environment variables - if (i < _walkIndex) - { - ++i; - continue; - } - - if (name == "TERM") - continue; // passed later via requestPty() - - int const rc = libssh2_channel_setenv_ex( - _p->sshChannel, name.data(), name.size(), value.data(), value.size()); - if (rc == LIBSSH2_ERROR_EAGAIN) - { - _walkIndex = i; // remember where we left off - _p->wantsWaitForSocket = true; // and wait for socket to become writable - return; - } - if (rc != LIBSSH2_ERROR_NONE) - { - logError("Failed to set SSH environment variable \"{}\". {}", - name, - libssl2ErrorString(rc)); - } - } - setState(State::StartShell); + if (!setEnv()) + return; [[fallthrough]]; } case State::StartShell: { @@ -582,23 +615,7 @@ void SshSession::processState() //. return; case State::ResizeScreen: { - auto const rc = libssh2_channel_request_pty_size_ex( - _p->sshChannel, - unbox(_pageSize.columns), - unbox(_pageSize.lines), - _pixels.has_value() ? unbox(_pixels->width) : 0, - _pixels.has_value() ? unbox(_pixels->height) : 0); - if (rc == LIBSSH2_ERROR_EAGAIN) - { - _p->wantsWaitForSocket = true; - return; - } - if (rc != LIBSSH2_ERROR_NONE) - { - logError("Failed to request PTY resize. {}", libssl2ErrorString(rc)); - return; - } - setState(State::Operational); + resizeScreen(); return; } case State::Failure: @@ -887,7 +904,9 @@ std::optional SshSession::exitStatus() const } if (exitSignalStr) - return SignalExit { exitSignalStr, errorMessage ? errorMessage : "", languageTag ? languageTag : "" }; + return SignalExit { .signal = exitSignalStr, + .errorMessage = errorMessage ? errorMessage : "", + .languageTag = languageTag ? languageTag : "" }; return NormalExit { exitcode }; } diff --git a/src/vtpty/SshSession.h b/src/vtpty/SshSession.h index 4640e5e5e8..af7bf62dae 100644 --- a/src/vtpty/SshSession.h +++ b/src/vtpty/SshSession.h @@ -116,6 +116,11 @@ class SshSession final: public Pty // Handles each individual states. void processState(); + // some of the complex states to handle + bool requestPty(); + bool setEnv(); + void resizeScreen(); + void setState(State nextState); void logInfo(std::string_view message) const; diff --git a/src/vtpty/UnixPty.cpp b/src/vtpty/UnixPty.cpp index dd32d70335..aaaf38b33c 100644 --- a/src/vtpty/UnixPty.cpp +++ b/src/vtpty/UnixPty.cpp @@ -63,10 +63,10 @@ namespace assert(*windowSize.lines <= numeric_limits::max()); assert(*windowSize.columns <= numeric_limits::max()); - winsize const ws { unbox(windowSize.lines), - unbox(windowSize.columns), - unbox(pixels.value_or(ImageSize {}).width), - unbox(pixels.value_or(ImageSize {}).height) }; + winsize const ws { .ws_row = unbox(windowSize.lines), + .ws_col = unbox(windowSize.columns), + .ws_xpixel = unbox(pixels.value_or(ImageSize {}).width), + .ws_ypixel = unbox(pixels.value_or(ImageSize {}).height) }; #if defined(__APPLE__) auto* wsa = const_cast(&ws); @@ -82,7 +82,8 @@ namespace ptyLog()("PTY opened. master={}, slave={}", masterFd, slaveFd); - return { PtyMasterHandle::cast_from(masterFd), PtySlaveHandle::cast_from(slaveFd) }; + return { .master = PtyMasterHandle::cast_from(masterFd), + .slave = PtySlaveHandle::cast_from(slaveFd) }; } #if defined(__linux__) && defined(UTEMPTER) diff --git a/src/vtrasterizer/BackgroundRenderer.cpp b/src/vtrasterizer/BackgroundRenderer.cpp index 818485f0d7..aa8654aa69 100644 --- a/src/vtrasterizer/BackgroundRenderer.cpp +++ b/src/vtrasterizer/BackgroundRenderer.cpp @@ -27,7 +27,8 @@ void BackgroundRenderer::renderLine(vtbackend::RenderLine const& line) { if (line.textAttributes.backgroundColor != _defaultColor) { - auto const position = vtbackend::CellLocation { line.lineOffset, vtbackend::ColumnOffset(0) }; + auto const position = + vtbackend::CellLocation { .line = line.lineOffset, .column = vtbackend::ColumnOffset(0) }; auto const pos = _gridMetrics.mapTopLeft(position); auto const width = _gridMetrics.cellSize.width * vtbackend::Width::cast_from(line.usedColumns); @@ -41,8 +42,8 @@ void BackgroundRenderer::renderLine(vtbackend::RenderLine const& line) if (line.fillAttributes.backgroundColor != _defaultColor) { auto const position = - vtbackend::CellLocation { line.lineOffset, - boxed_cast(line.usedColumns) }; + vtbackend::CellLocation { .line = line.lineOffset, + .column = boxed_cast(line.usedColumns) }; auto const pos = _gridMetrics.mapTopLeft(position); auto const width = _gridMetrics.cellSize.width * vtbackend::Width::cast_from(line.displayWidth - line.usedColumns); diff --git a/src/vtrasterizer/BoxDrawingRenderer.cpp b/src/vtrasterizer/BoxDrawingRenderer.cpp index 154423b3b1..ae75dd6f64 100644 --- a/src/vtrasterizer/BoxDrawingRenderer.cpp +++ b/src/vtrasterizer/BoxDrawingRenderer.cpp @@ -53,7 +53,7 @@ namespace { for (size_t j = 0; j < cellSize.width.as(); ++j) { - dest[i * pitch + j] = image[(height - i - 1u) * pitch + j]; + dest[(i * pitch) + j] = image[((height - i - 1u) * pitch) + j]; } } return dest; @@ -133,7 +133,7 @@ namespace detail auto const putpixel = [&](int x, int y, uint8_t alpha = 0xFFu) { auto const fy = clamp((unsigned) y, 0u, h - 1); auto const fx = clamp((unsigned) x, 0u, w - 1); - buffer[fy * w + fx] = alpha; + buffer[(fy * w) + fx] = alpha; gaps[fy].push_back(fx); }; @@ -141,17 +141,18 @@ namespace detail drawEllipseArc(putpixel, imageSize, crispy::point { // radius - unbox(imageSize.width) / 2 - int(thickness) / 2, - unbox(imageSize.height) / 2 - int(thickness) / 2 }, + .x = (unbox(imageSize.width) / 2) - (int(thickness) / 2), + .y = (unbox(imageSize.height) / 2) - (int(thickness) / 2) }, arc); // outer circle - drawEllipseArc(putpixel, - imageSize, - crispy::point { // radius - unbox(imageSize.width) / 2 + int(thickness) / 2 - 1, - unbox(imageSize.height) / 2 + int(thickness) / 2 - 1 }, - arc); + drawEllipseArc( + putpixel, + imageSize, + crispy::point { // radius + .x = (unbox(imageSize.width) / 2) + (int(thickness) / 2) - 1, + .y = (unbox(imageSize.height) / 2) + (int(thickness) / 2) - 1 }, + arc); // Close arc at open ends to filling works. // bool const isLeft = arc == Arc::TopLeft || arc == Arc::BottomLeft; @@ -164,9 +165,9 @@ namespace detail { if (auto& gap = gaps[y]; !gap.empty()) { - sort(begin(gap), end(gap)); + std::ranges::sort(gap); for (auto const xi: iota(gap.front(), gap.back())) - buffer.at(y * unbox(imageSize.width) + xi) = 0xFF; + buffer.at((y * unbox(imageSize.width)) + xi) = 0xFF; } } } @@ -217,31 +218,31 @@ namespace detail auto constexpr BlockLeft = 3 / 12_th; auto constexpr BlockRight = 9 / 12_th; auto constexpr BlockTop = 3 / 12_th; - auto const blockBottom = 1.0 - (double(underlinePosition) / unbox(size.height)) - 2 * Gap; + auto const blockBottom = 1.0 - (double(underlinePosition) / unbox(size.height)) - (2 * Gap); auto b = blockElement<1>(size); switch (part) { case Part::Left: - b.rect({ BlockLeft-2*Gap, BlockTop-2*Gap }, { 1, BlockTop-Gap }); // top line - b.rect({ BlockLeft-2*Gap, blockBottom+Gap }, { 1, blockBottom+2*Gap }); // bottom line - b.rect({ BlockLeft-2*Gap, BlockTop-2*Gap }, { BlockLeft-Gap, blockBottom+Gap }); // left bar + b.rect({ .x=BlockLeft-(2*Gap), .y=BlockTop-(2*Gap) }, { .x=1, .y=BlockTop-Gap }); // top line + b.rect({ .x=BlockLeft-(2*Gap), .y=blockBottom+Gap }, { .x=1, .y=blockBottom+(2*Gap) }); // bottom line + b.rect({ .x=BlockLeft-(2*Gap), .y=BlockTop-(2*Gap) }, { .x=BlockLeft-Gap, .y=blockBottom+Gap }); // left bar if (filledval) - b.rect({ BlockLeft, BlockTop }, { 1, blockBottom }); + b.rect({ .x=BlockLeft, .y=BlockTop }, { .x=1, .y=blockBottom }); break; case Part::Middle: - b.rect({ 0, BlockTop-2*Gap }, { 1, BlockTop-Gap }); // top line - b.rect({ 0, blockBottom+Gap }, { 1, blockBottom+2*Gap }); // bottom line + b.rect({ .x=0, .y=BlockTop-(2*Gap) }, { .x=1, .y=BlockTop-Gap }); // top line + b.rect({ .x=0, .y=blockBottom+Gap }, { .x=1, .y=blockBottom+(2*Gap) }); // bottom line if (filledval) - b.rect({ 0, BlockTop }, { 1, blockBottom }); + b.rect({ .x=0, .y=BlockTop }, { .x=1, .y=blockBottom }); break; case Part::Right: - b.rect({ 0, BlockTop-2*Gap }, { BlockRight+2*Gap, BlockTop-Gap }); // top line - b.rect({ 0, blockBottom+Gap }, { BlockRight+2*Gap, blockBottom+2*Gap }); // bottom line - b.rect({ BlockRight+Gap, BlockTop-2*Gap }, { BlockRight+2*Gap, blockBottom+Gap }); // left bar + b.rect({ .x=0, .y=BlockTop-(2*Gap) }, { .x=BlockRight+(2*Gap), .y=BlockTop-Gap }); // top line + b.rect({ .x=0, .y=blockBottom+Gap }, { .x=BlockRight+(2*Gap), .y=blockBottom+(2*Gap) }); // bottom line + b.rect({ .x=BlockRight+Gap, .y=BlockTop-(2*Gap) }, { .x=BlockRight+(2*Gap), .y=blockBottom+Gap }); // left bar if (filledval) - b.rect({ 0, BlockTop }, { BlockRight, blockBottom }); + b.rect({ .x=0, .y=BlockTop }, { .x=BlockRight, .y=blockBottom }); break; } // clang-format on @@ -503,7 +504,7 @@ namespace detail x < int(unbox(size.width) * to.x); ++x) { - image[size_t(h - y) * *size.width + size_t(x)] = (uint8_t) filler(x, y); + image[(size_t(h - y) * unbox(size.width)) + size_t(x)] = (uint8_t) filler(x, y); } } } @@ -545,7 +546,7 @@ namespace detail auto dotted(ImageSize size) { auto const s = *size.width / N; - auto const f = linearEq({ 0, 0 }, { 10, 10 }); + auto const f = linearEq({ .x = 0, .y = 0 }, { .x = 10, .y = 10 }); return [s, f](int x, int y) { return ((y) / s) % 2 && ((x) / s) % 2 ? 255 : 0; }; @@ -555,7 +556,7 @@ namespace detail auto gatter(ImageSize size) { auto const s = *size.width / N; - auto const f = linearEq({ 0, 0 }, { 10, 10 }); + auto const f = linearEq({ .x = 0, .y = 0 }, { .x = 10, .y = 10 }); return [s, f](int x, int y) { return ((y) / s) % 2 || ((x) / s) % 2 ? 255 : 0; }; @@ -565,9 +566,10 @@ namespace detail auto dbar(ImageSize size) { auto const s = *size.height / N; - auto const f = linearEq({ 0, 0 }, { unbox(size.width), unbox(size.height) }); + auto const f = + linearEq({ .x = 0, .y = 0 }, { .x = unbox(size.width), .y = unbox(size.height) }); return [s, f](int x, int y) { - return (unsigned(y - P * f(x)) / s) % 2 ? 0 : 255; + return (unsigned(y - (P * f(x))) / s) % 2 ? 0 : 255; }; } @@ -608,33 +610,33 @@ namespace detail template auto getTriangleProps(ImageSize size) { - auto const c = - point { Direction == Dir::Left ? unbox(size.width) / DivisorX - : unbox(size.width) - unbox(size.width) / DivisorX, - unbox(size.height) / 2 }; + auto const c = point { .x = Direction == Dir::Left + ? unbox(size.width) / DivisorX + : unbox(size.width) - (unbox(size.width) / DivisorX), + .y = unbox(size.height) / 2 }; auto const w = unbox(size.width) - 1; auto const h = unbox(size.height) - 1; if constexpr (Direction == Dir::Left) { - auto const a = linearEq({ 0, 0 }, c); - auto const b = linearEq({ 0, h }, c); + auto const a = linearEq({ .x = 0, .y = 0 }, c); + auto const b = linearEq({ .x = 0, .y = h }, c); return [a, b](int x) { return pair { a(x), b(x) }; }; } else if constexpr (Direction == Dir::Right) { - auto const a = linearEq(c, { w, 0 }); - auto const b = linearEq(c, { w, h }); + auto const a = linearEq(c, { .x = w, .y = 0 }); + auto const b = linearEq(c, { .x = w, .y = h }); return [a, b](int x) { return pair { a(x), b(x) }; }; } else if constexpr (Direction == Dir::Top) { - auto const a = linearEq({ 0, 0 }, c); - auto const b = linearEq(c, { w, 0 }); + auto const a = linearEq({ .x = 0, .y = 0 }, c); + auto const b = linearEq(c, { .x = w, .y = 0 }); return [a, b, c](int x) { if (x < c.x) return pair { 0, a(x) }; @@ -644,8 +646,8 @@ namespace detail } else if constexpr (Direction == Dir::Bottom) { - auto const a = linearEq({ 0, h }, c); - auto const b = linearEq(c, { w, h }); + auto const a = linearEq({ .x = 0, .y = h }, c); + auto const b = linearEq(c, { .x = w, .y = h }); return [a, b, c, h](int x) { if (x < c.x) return pair { a(x), h }; @@ -659,11 +661,11 @@ namespace detail template auto triChecker(ImageSize size) { - auto const c = point { unbox(size.width) / 2, unbox(size.height) / 2 }; + auto const c = point { .x = unbox(size.width) / 2, .y = unbox(size.height) / 2 }; auto const w = unbox(size.width) - 1; - auto const f = linearEq({ 0, 0 }, c); - auto const g = linearEq(c, { w, 0 }); + auto const f = linearEq({ .x = 0, .y = 0 }, c); + auto const g = linearEq(c, { .x = w, .y = 0 }); auto const k = checker<4, Inverted::No>(size); return [=](int x, int y) { @@ -685,11 +687,11 @@ namespace detail auto constexpr Set = Inv == Inverted::No ? 255 : 0; auto constexpr Unset = 255 - Set; - auto const c = point { unbox(size.width) / 2, unbox(size.height) / 2 }; + auto const c = point { .x = unbox(size.width) / 2, .y = unbox(size.height) / 2 }; auto const w = unbox(size.width) - 1; - auto const f = linearEq({ 0, 0 }, c); - auto const g = linearEq(c, { w, 0 }); + auto const f = linearEq({ .x = 0, .y = 0 }, c); + auto const g = linearEq(c, { .x = w, .y = 0 }); return [=](int x, int y) { auto const [a, b] = pair { f(x), g(x) }; @@ -716,7 +718,7 @@ namespace detail for (auto const x: ranges::views::iota(0u, unbox(pixmap.size.width))) { auto const [a, b] = p(int(x)); - pixmap.buffer[unsigned(h - y) * w + x] = a <= int(y) && int(y) <= b ? set : unset; + pixmap.buffer[(unsigned(h - y) * w) + x] = a <= int(y) && int(y) <= b ? set : unset; } } } @@ -748,7 +750,7 @@ namespace detail for (auto const y: ranges::views::iota(0u, pixmap.size.height.as())) for (auto const x: ranges::views::iota(0u, pixmap.size.width.as())) if (condition(int(x), int(y))) - pixmap.buffer.at(w * (h - y) + x) = 0xFF; + pixmap.buffer.at((w * (h - y)) + x) = 0xFF; } inline atlas::Buffer upperDiagonalMosaic(ImageSize size, Ratio ra, Ratio rb) @@ -816,12 +818,14 @@ namespace detail // 1 <= n <= r*n constexpr inline RatioBlock horiz_nth(double r, int n) noexcept { - return RatioBlock { { 0, r * double(n - 1) }, { 1, r * double(n) } }; + return RatioBlock { .from = { .x = 0, .y = r * double(n - 1) }, + .to = { .x = 1, .y = r * double(n) } }; } constexpr inline RatioBlock vert_nth(double r, int n) noexcept { - return RatioBlock { { r * double(n - 1), 0 }, { r * double(n), 1 } }; + return RatioBlock { .from = { .x = r * double(n - 1), .y = 0 }, + .to = { .x = r * double(n), .y = 1 } }; } [[maybe_unused]] inline Pixmap operator*(Pixmap&& image, RatioBlock block) @@ -1049,7 +1053,7 @@ optional BoxDrawingRenderer::buildElements(char32_t codepoint) return b; }; auto const progressBar = [size, this]() { - return ProgressBar { size, _gridMetrics.underline.position }; + return ProgressBar { .size = size, .underlinePosition = _gridMetrics.underline.position }; }; auto const segmentArt = [size, this]() { auto constexpr AntiAliasingSamplingFactor = 1; @@ -1302,50 +1306,50 @@ optional BoxDrawingRenderer::buildElements(char32_t codepoint) case 0x1FB3B: return blockSextant(size, 2, 3, 4, 5, 6); // 🬻 BLOCK SEXTANT-23456 // }}} // {{{ 1FB3C..1FBAF diagonals, nth, block elements - case 0x1FB3C: return /* 🬼 */ ld({ 0, 3 / 4_th }, { 1 / 4_th, 1 }); - case 0x1FB3D: return /* 🬽 */ ld({ 0, 3 / 4_th }, { 1, 1 }); - case 0x1FB3E: return /* 🬾 */ ld({ 0, 1 / 4_th }, { 1 / 2_th, 1 }); - case 0x1FB3F: return /* 🬿 */ ld({ 0, 1 / 4_th }, { 1, 1 }); - case 0x1FB40: return /* 🭀 */ ld({ 0, 0 }, { 1 / 2_th, 1 }); - case 0x1FB41: return /* 🭁 */ ld({ 0, 1 / 4_th }, { 1 / 2_th, 0 }); - case 0x1FB42: return /* 🭂 */ ld({ 0, 1 / 4_th }, { 1, 0 }); - case 0x1FB43: return /* 🭃 */ ld({ 0, 3 / 4_th }, { 1 / 2_th, 0 }); - case 0x1FB44: return /* 🭄 */ ld({ 0, 3 / 4_th }, { 1, 0 }); - case 0x1FB45: return /* 🭅 */ ld({ 0, 1 }, { 1 / 2_th, 0 }); - case 0x1FB46: return /* 🭆 */ ld({ 0, 3 / 4_th }, { 1, 1 / 4_th }); - case 0x1FB47: return /* 🭇 */ ld({ 3 / 4_th, 1 }, { 1, 3 / 4_th }); - case 0x1FB48: return /* 🭈 */ ld({ 0, 1 }, { 1, 3 / 4_th }); - case 0x1FB49: return /* 🭉 */ ld({ 1 / 2_th, 1 }, { 1, 1 / 4_th }); - case 0x1FB4A: return /* 🭊 */ ld({ 0, 1 }, { 1, 1 / 4_th }); - case 0x1FB4B: return /* 🭋 */ ld({ 1 / 2_th, 1 }, { 1, 0 }); - case 0x1FB4C: return /* 🭌 */ ld({ 1 / 2_th, 0 }, { 1, 1 / 4_th }); - case 0x1FB4D: return /* 🭍 */ ld({ 0, 0 }, { 1, 1 / 4_th }); - case 0x1FB4E: return /* 🭎 */ ld({ 1 / 2_th, 0 }, { 1, 3 / 4_th }); - case 0x1FB4F: return /* 🭏 */ ld({ 0, 0 }, { 1, 3 / 4_th }); - case 0x1FB50: return /* 🭐 */ ld({ 1 / 2_th, 0 }, { 1, 1 }); - case 0x1FB51: return /* 🭑 */ ld({ 0, 1 / 4_th }, { 1, 3 / 4_th }); - case 0x1FB52: return /* 🭒 */ ud({ 0, 3 / 4_th }, { 1 / 2_th, 1 }); - case 0x1FB53: return /* 🭓 */ ud({ 0, 3 / 4_th }, { 1, 1 }); - case 0x1FB54: return /* 🭔 */ ud({ 0, 1 / 4_th }, { 1 / 2_th, 1 }); - case 0x1FB55: return /* 🭕 */ ud({ 0, 1 / 4_th }, { 1, 1 }); // XXX - case 0x1FB56: return /* 🭖 */ ud({ 0, 0 }, { 1 / 2_th, 1 }); - case 0x1FB57: return /* 🭗 */ ud({ 0, 1 / 4_th }, { 1 / 4_th, 0 }); - case 0x1FB58: return /* 🭘 */ ud({ 0, 1 / 4_th }, { 1, 0 }); - case 0x1FB59: return /* 🭙 */ ud({ 0, 3 / 4_th }, { 1 / 2_th, 0 }); - case 0x1FB5A: return /* 🭚 */ ud({ 0, 3 / 4_th }, { 1, 0 }); - case 0x1FB5B: return /* 🭛 */ ud({ 0, 1 }, { 1 / 2_th, 0 }); - case 0x1FB5C: return /* 🭜 */ ud({ 0, 3 / 4_th }, { 1, 1 / 4_th }); - case 0x1FB5D: return /* 🭝 */ ud({ 1 / 2_th, 1 }, { 1, 3 / 4_th }); - case 0x1FB5E: return /* 🭞 */ ud({ 0, 1 }, { 1, 3 / 4_th }); - case 0x1FB5F: return /* 🭟 */ ud({ 1 / 2_th, 1 }, { 1, 1 / 4_th }); - case 0x1FB60: return /* 🭠 */ ud({ 0, 1 }, { 1, .25 }); - case 0x1FB61: return /* 🭡 */ ud({ 1 / 2_th, 1 }, { 1, 0 }); - case 0x1FB62: return /* 🭢 */ ud({ 3 / 4_th, 0 }, { 1, 1 / 4_th }); - case 0x1FB63: return /* 🭣 */ ud({ 0, 0 }, { 1, 1 / 4_th }); - case 0x1FB64: return /* 🭤 */ ud({ 1 / 2_th, 0 }, { 1, 3 / 4_th }); - case 0x1FB65: return /* 🭥 */ ud({ 0, 0 }, { 1, 3 / 4_th }); - case 0x1FB66: return /* 🭦 */ ud({ 1 / 2_th, 0 }, { 1, 1 }); - case 0x1FB67: return /* 🭧 */ ud({ 0, 1 / 4_th }, { 1, 3 / 4_th }); + case 0x1FB3C: return /* 🬼 */ ld({ .x = 0, .y = 3 / 4_th }, { .x = 1 / 4_th, .y = 1 }); + case 0x1FB3D: return /* 🬽 */ ld({ .x = 0, .y = 3 / 4_th }, {.x = 1, .y = 1 }); + case 0x1FB3E: return /* 🬾 */ ld({ .x = 0, .y = 1 / 4_th }, {.x = 1 / 2_th, .y = 1 }); + case 0x1FB3F: return /* 🬿 */ ld({ .x = 0, .y = 1 / 4_th }, {.x = 1, .y = 1 }); + case 0x1FB40: return /* 🭀 */ ld({ .x = 0, .y = 0 }, { .x = 1 / 2_th, .y = 1 }); + case 0x1FB41: return /* 🭁 */ ld({ .x = 0, .y = 1 / 4_th }, { .x = 1 / 2_th, .y = 0 }); + case 0x1FB42: return /* 🭂 */ ld({ .x = 0, .y = 1 / 4_th }, { .x = 1, .y = 0 }); + case 0x1FB43: return /* 🭃 */ ld({ .x = 0, .y = 3 / 4_th }, { .x = 1 / 2_th, .y = 0 }); + case 0x1FB44: return /* 🭄 */ ld({ .x = 0, .y = 3 / 4_th }, { .x = 1, .y = 0 }); + case 0x1FB45: return /* 🭅 */ ld({ .x = 0, .y = 1 }, { .x = 1 / 2_th, .y = 0 }); + case 0x1FB46: return /* 🭆 */ ld({ .x = 0, .y = 3 / 4_th }, { .x = 1, .y = 1 / 4_th }); + case 0x1FB47: return /* 🭇 */ ld({ .x = 3 / 4_th, .y = 1 }, { .x = 1, .y = 3 / 4_th }); + case 0x1FB48: return /* 🭈 */ ld({ .x = 0, .y = 1 }, { .x = 1, .y = 3 / 4_th }); + case 0x1FB49: return /* 🭉 */ ld({ .x = 1 / 2_th, .y = 1 }, { .x = 1, .y = 1 / 4_th }); + case 0x1FB4A: return /* 🭊 */ ld({ .x = 0, .y = 1 }, { .x = 1, .y = 1 / 4_th }); + case 0x1FB4B: return /* 🭋 */ ld({ .x = 1 / 2_th, .y = 1 }, { .x = 1, .y = 0 }); + case 0x1FB4C: return /* 🭌 */ ld({ .x = 1 / 2_th, .y = 0 }, { .x = 1, .y = 1 / 4_th }); + case 0x1FB4D: return /* 🭍 */ ld({ .x = 0, .y = 0 }, { .x = 1, .y = 1 / 4_th }); + case 0x1FB4E: return /* 🭎 */ ld({ .x = 1 / 2_th, .y = 0 }, { .x = 1, .y = 3 / 4_th }); + case 0x1FB4F: return /* 🭏 */ ld({ .x = 0, .y = 0 }, { .x = 1, .y = 3 / 4_th }); + case 0x1FB50: return /* 🭐 */ ld({ .x = 1 / 2_th, .y = 0 }, { .x = 1, .y = 1 }); + case 0x1FB51: return /* 🭑 */ ld({ .x = 0, .y = 1 / 4_th }, { .x = 1, .y = 3 / 4_th }); + case 0x1FB52: return /* 🭒 */ ud({ .x = 0, .y = 3 / 4_th }, { .x = 1 / 2_th, .y = 1 }); + case 0x1FB53: return /* 🭓 */ ud({ .x = 0, .y = 3 / 4_th }, { .x = 1, .y = 1 }); + case 0x1FB54: return /* 🭔 */ ud({ .x = 0, .y = 1 / 4_th }, { .x = 1 / 2_th, .y = 1 }); + case 0x1FB55: return /* 🭕 */ ud({ .x = 0, .y = 1 / 4_th }, { .x = 1, .y = 1 }); // XXX + case 0x1FB56: return /* 🭖 */ ud({ .x = 0, .y = 0 }, { .x = 1 / 2_th, .y = 1 }); + case 0x1FB57: return /* 🭗 */ ud({ .x = 0, .y = 1 / 4_th }, { .x = 1 / 4_th, .y = 0 }); + case 0x1FB58: return /* 🭘 */ ud({ .x = 0, .y = 1 / 4_th }, { .x = 1, .y = 0 }); + case 0x1FB59: return /* 🭙 */ ud({ .x = 0, .y = 3 / 4_th }, { .x = 1 / 2_th, .y = 0 }); + case 0x1FB5A: return /* 🭚 */ ud({ .x = 0, .y = 3 / 4_th }, { .x = 1, .y = 0 }); + case 0x1FB5B: return /* 🭛 */ ud({ .x = 0, .y = 1 }, { .x =1 / 2_th, .y = 0 }); + case 0x1FB5C: return /* 🭜 */ ud({ .x = 0, .y = 3 / 4_th }, { .x =1, .y = 1 / 4_th }); + case 0x1FB5D: return /* 🭝 */ ud({ .x = 1 / 2_th, .y = 1 }, { .x =1, .y = 3 / 4_th }); + case 0x1FB5E: return /* 🭞 */ ud({ .x = 0, .y = 1 }, { .x = 1, .y = 3 / 4_th }); + case 0x1FB5F: return /* 🭟 */ ud({ .x = 1 / 2_th, .y = 1 }, { .x = 1, .y = 1 / 4_th }); + case 0x1FB60: return /* 🭠 */ ud({ .x = 0, .y = 1 }, { .x = 1, .y = .25 }); + case 0x1FB61: return /* 🭡 */ ud({ .x = 1 / 2_th, .y = 1 }, { .x = 1, .y = 0 }); + case 0x1FB62: return /* 🭢 */ ud({ .x = 3 / 4_th, .y = 0 }, { .x = 1, .y = 1 / 4_th }); + case 0x1FB63: return /* 🭣 */ ud({ .x = 0, .y = 0 }, { .x = 1, .y = 1 / 4_th }); + case 0x1FB64: return /* 🭤 */ ud({ .x = 1 / 2_th, .y = 0 }, { .x = 1, .y = 3 / 4_th }); + case 0x1FB65: return /* 🭥 */ ud({ .x = 0, .y = 0 }, { .x = 1, .y = 3 / 4_th }); + case 0x1FB66: return /* 🭦 */ ud({ .x = 1 / 2_th, .y = 0 }, { .x = 1, .y = 1 }); + case 0x1FB67: return /* 🭧 */ ud({ .x = 0, .y = 1 / 4_th }, { .x = 1, .y = 3 / 4_th }); case 0x1FB68: return /* 🭨 */ triangle(size); case 0x1FB69: return /* 🭩 */ triangle(size); case 0x1FB6A: return /* 🭪 */ triangle(size); @@ -1424,64 +1428,64 @@ optional BoxDrawingRenderer::buildElements(char32_t codepoint) case 0x1FB9D: return blockElement<1>(size).fill(triChecker<2>(size)); case 0x1FB9E: return blockElement<1>(size).fill(triChecker<3>(size)); case 0x1FB9F: return blockElement<1>(size).fill(triChecker<4>(size)); - case 0x1FBA0: return lineArt().line({ 0, 1 / 2_th }, { 1 / 2_th, 0 }); - case 0x1FBA1: return lineArt().line({ 1 / 2_th, 0 }, { 1, 1 / 2_th }); - case 0x1FBA2: return lineArt().line({ 0, 1 / 2_th }, { 1 / 2_th, 1 }); - case 0x1FBA3: return lineArt().line({ 1 / 2_th, 1 }, { 1, 1 / 2_th }); + case 0x1FBA0: return lineArt().line({ .x=0, .y=1 / 2_th }, { .x=1 / 2_th, .y=0 }); + case 0x1FBA1: return lineArt().line({ .x=1 / 2_th, .y=0 }, { .x=1, .y=1 / 2_th }); + case 0x1FBA2: return lineArt().line({ .x=0, .y=1 / 2_th }, { .x=1 / 2_th, .y=1 }); + case 0x1FBA3: return lineArt().line({ .x=1 / 2_th, .y=1 }, { .x=1, .y=1 / 2_th }); case 0x1FBA4: - return lineArt().line({ 0, 1 / 2_th }, { 1 / 2_th, 0 }).line({ 0, 1 / 2_th }, { 1 / 2_th, 1 }); + return lineArt().line({ .x=0, .y=1 / 2_th }, { .x=1 / 2_th, .y=0 }).line({ .x=0, .y=1 / 2_th }, { .x=1 / 2_th, .y=1 }); case 0x1FBA5: - return lineArt().line({ 1 / 2_th, 0 }, { 1, 1 / 2_th }).line({ 1 / 2_th, 1 }, { 1, 1 / 2_th }); + return lineArt().line({ .x=1 / 2_th, .y=0 }, { .x=1, .y=1 / 2_th }).line({ .x=1 / 2_th, .y=1 }, { .x=1, .y=1 / 2_th }); case 0x1FBA6: - return lineArt().line({ 0, 1 / 2_th }, { 1 / 2_th, 1 }).line({ 1 / 2_th, 1 }, { 1, 1 / 2_th }); + return lineArt().line({ .x=0, .y=1 / 2_th }, { .x=1 / 2_th, .y=1 }).line({ .x=1 / 2_th, .y=1 }, { .x=1, .y=1 / 2_th }); case 0x1FBA7: - return lineArt().line({ 0, 1 / 2_th }, { 1 / 2_th, 0 }).line({ 1 / 2_th, 0 }, { 1, 1 / 2_th }); + return lineArt().line({ .x=0, .y=1 / 2_th }, { .x=1 / 2_th, .y=0 }).line({ .x=1 / 2_th, .y=0 }, { .x=1, .y=1 / 2_th }); case 0x1FBA8: - return lineArt().line({ 0, 1 / 2_th }, { 1 / 2_th, 0 }).line({ 1 / 2_th, 1 }, { 1, 1 / 2_th }); + return lineArt().line({ .x=0, .y=1 / 2_th }, { .x=1 / 2_th, .y=0 }).line({ .x=1 / 2_th, .y=1 }, { .x=1, .y=1 / 2_th }); case 0x1FBA9: - return lineArt().line({ 1 / 2_th, 0 }, { 1, 1 / 2_th }).line({ 0, 1 / 2_th }, { 1 / 2_th, 1 }); + return lineArt().line({ .x=1 / 2_th, .y=0 }, { .x=1, .y=1 / 2_th }).line({ .x=0, .y=1 / 2_th }, { .x=1 / 2_th, .y=1 }); case 0x1FBAA: return lineArt() . // line({0, 1/2_th}, {1/2_th, 0}). - line({ 1 / 2_th, 0 }, { 1, 1 / 2_th }) - .line({ 0, 1 / 2_th }, { 1 / 2_th, 1 }) - .line({ 1 / 2_th, 1 }, { 1, 1 / 2_th }) + line({ .x=1 / 2_th, .y=0 }, { .x=1, .y=1 / 2_th }) + .line({ .x=0, .y=1 / 2_th }, { .x=1 / 2_th, .y=1 }) + .line({ .x=1 / 2_th, .y=1 }, { .x=1, .y=1 / 2_th }) .take(); case 0x1FBAB: return lineArt() - .line({ 0, 1 / 2_th }, { 1 / 2_th, 0 }) + .line({ .x=0, .y=1 / 2_th }, { .x=1 / 2_th, .y=0 }) . // line({1/2_th, 0}, {1, 1/2_th}). - line({ 0, 1 / 2_th }, { 1 / 2_th, 1 }) - .line({ 1 / 2_th, 1 }, { 1, 1 / 2_th }) + line({ .x=0, .y=1 / 2_th }, { .x=1 / 2_th, .y=1 }) + .line({ .x=1 / 2_th, .y=1 }, { .x=1, .y=1 / 2_th }) .take(); case 0x1FBAC: return lineArt() - .line({ 0, 1 / 2_th }, { 1 / 2_th, 0 }) - .line({ 1 / 2_th, 0 }, { 1, 1 / 2_th }) + .line({ .x=0, .y=1 / 2_th }, { .x=1 / 2_th, .y=0 }) + .line({ .x=1 / 2_th, .y=0 }, { .x=1, .y=1 / 2_th }) . // line({0, 1/2_th}, {1/2_th, 1}). - line({ 1 / 2_th, 1 }, { 1, 1 / 2_th }) + line({ .x=1 / 2_th, .y=1 }, { .x=1, .y=1 / 2_th }) .take(); case 0x1FBAD: return lineArt() - .line({ 0, 1 / 2_th }, { 1 / 2_th, 0 }) - .line({ 1 / 2_th, 0 }, { 1, 1 / 2_th }) - .line({ 0, 1 / 2_th }, { 1 / 2_th, 1 }) + .line({ .x=0, .y=1 / 2_th }, { .x=1 / 2_th, .y=0 }) + .line({ .x=1 / 2_th, .y=0 }, { .x=1, .y=1 / 2_th }) + .line({ .x=0, .y=1 / 2_th }, { .x=1 / 2_th, .y=1 }) . // line({1/2_th, 1}, {1, 1/2_th}). take(); case 0x1FBAE: return lineArt() - .line({ 0, 1 / 2_th }, { 1 / 2_th, 0 }) - .line({ 1 / 2_th, 0 }, { 1, 1 / 2_th }) - .line({ 0, 1 / 2_th }, { 1 / 2_th, 1 }) - .line({ 1 / 2_th, 1 }, { 1, 1 / 2_th }) + .line({ .x=0, .y=1 / 2_th }, { .x=1 / 2_th, .y=0 }) + .line({ .x=1 / 2_th, .y=0 }, { .x=1, .y=1 / 2_th }) + .line({ .x=0, .y=1 / 2_th }, { .x=1 / 2_th, .y=1 }) + .line({ .x=1 / 2_th, .y=1 }, { .x=1, .y=1 / 2_th }) .take(); case 0x1FBAF: return lineArt() - .line({ 0, 1 / 2_th }, { 1, 1 / 2_th }) - .line({ 1 / 2_th, 3 / 8_th }, { 1 / 2_th, 5 / 8_th }) + .line({ .x=0, .y=1 / 2_th }, { .x=1, .y=1 / 2_th }) + .line({ .x=1 / 2_th, .y=3 / 8_th }, { .x=1 / 2_th, .y=5 / 8_th }) .take(); case 0x1FBF0: return segmentArt().segment_bar(1, 2, 4, 5, 6, 7); case 0x1FBF1: return segmentArt().segment_bar(2, 5); @@ -1499,9 +1503,9 @@ optional BoxDrawingRenderer::buildElements(char32_t codepoint) case 0xE0B2: return /*  */ triangle(size); case 0xE0B4: return /*  */ blockElement<2>(size).halfFilledCircleRight(); case 0xE0B6: return /*  */ blockElement<2>(size).halfFilledCircleLeft(); - case 0xE0BA: return /*  */ ld({ 0, 1 }, { 1, 0 }); - case 0xE0BC: return /*  */ ud({ 0, 1 }, { 1, 0 }); - case 0xE0BE: return /*  */ ud({ 0, 0 }, { 1, 1 }); + case 0xE0BA: return /*  */ ld({ .x=0, .y=1 }, { .x=1, .y=0 }); + case 0xE0BC: return /*  */ ud({ .x=0, .y=1 }, { .x=1, .y=0 }); + case 0xE0BE: return /*  */ ud({ .x=0, .y=0 }, { .x=1, .y=1 }); // PUA defines as introduced by FiraCode: https://github.com/tonsky/FiraCode/issues/1324 case 0xEE00: return progressBar().left(); @@ -1516,6 +1520,65 @@ optional BoxDrawingRenderer::buildElements(char32_t codepoint) return nullopt; } + +auto boxDashedHorizontal(auto& dashed, ImageSize size, int lineThickness){ + auto const height = size.height; + auto const width = size.width; + auto const lightThickness = (unsigned) lineThickness; + auto const heavyThickness = (unsigned) lineThickness * 2; + auto const [dashCount, thicknessMode] = *dashed; + auto const thickness = thicknessMode == detail::Thickness::Heavy ? heavyThickness : lightThickness; + auto image = atlas::Buffer(unbox(width) * unbox(height), 0x00); + + auto const y0 = (*height / 2) - ((unsigned) thickness / 2); + auto const w = (unsigned) thickness; + auto const p = unbox(width) / static_cast(dashCount * 2.0); + + auto x0 = round(p / 2.0); + for ([[maybe_unused]] auto const _: iota(0u, dashCount)) + { + auto const x0l = static_cast(round(x0)); + for (auto const y: iota(y0, y0 + w)) + for (auto const x: iota(x0l, x0l + static_cast(p))) + image[(y * unbox(width)) + unsigned(x)] = 0xFF; + x0 += unbox(width) / static_cast(dashCount); + } + + return image; + +} + + +auto boxDashedVertical(auto& dashed, ImageSize size, int lineThickness) +{ + auto const height = size.height; + auto const width = size.width; + auto const lightThickness = (unsigned) lineThickness; + auto const heavyThickness = (unsigned) lineThickness * 2; + auto image = atlas::Buffer(unbox(width) * unbox(height), 0x00); + auto const [dashCount, thicknessMode] = *dashed; + auto const thickness = thicknessMode == detail::Thickness::Heavy ? heavyThickness : lightThickness; + + auto const x0 = (*width / 2) - ((unsigned) thickness / 2); + auto const w = (unsigned) thickness; + auto const p = unbox(height) / static_cast(dashCount * 2.0); + + auto y0 = round(p / 2.0); + for ([[maybe_unused]] auto const i: iota(0u, dashCount)) + { + auto const y0l = static_cast(round(y0)); + for (auto const y: iota(y0l, y0l + static_cast(p))) + for (auto const x: iota(x0, x0 + w)) + image[(y * unbox(width)) + unsigned(x)] = 0xFF; + y0 += unbox(height) / static_cast(dashCount); + } + + return image; +} + + + + optional BoxDrawingRenderer::buildBoxElements(char32_t codepoint, ImageSize size, int lineThickness) @@ -1538,46 +1601,12 @@ optional BoxDrawingRenderer::buildBoxElements(char32_t codepoint, if (auto const dashed = box.get_dashed_horizontal()) { - auto const [dashCount, thicknessMode] = *dashed; - auto const thickness = thicknessMode == detail::Thickness::Heavy ? heavyThickness : lightThickness; - - auto const y0 = (*height / 2) - (unsigned) thickness / 2; - auto const w = (unsigned) thickness; - auto const p = unbox(width) / static_cast(dashCount * 2.0); - - auto x0 = round(p / 2.0); - for ([[maybe_unused]] auto const _: iota(0u, dashCount)) - { - auto const x0l = static_cast(round(x0)); - for (auto const y: iota(y0, y0 + w)) - for (auto const x: iota(x0l, x0l + static_cast(p))) - image[y * *width + unsigned(x)] = 0xFF; - x0 += unbox(width) / static_cast(dashCount); - } - - return image; + return boxDashedHorizontal(dashed, size, lineThickness); } if (auto const dashed = box.get_dashed_vertical()) { - auto const [dashCount, thicknessMode] = *dashed; - auto const thickness = thicknessMode == detail::Thickness::Heavy ? heavyThickness : lightThickness; - - auto const x0 = (*width / 2) - (unsigned) thickness / 2; - auto const w = (unsigned) thickness; - auto const p = unbox(height) / static_cast(dashCount * 2.0); - - auto y0 = round(p / 2.0); - for ([[maybe_unused]] auto const i: iota(0u, dashCount)) - { - auto const y0l = static_cast(round(y0)); - for (auto const y: iota(y0l, y0l + static_cast(p))) - for (auto const x: iota(x0, x0 + w)) - image[y * *width + unsigned(x)] = 0xFF; - y0 += unbox(height) / static_cast(dashCount); - } - - return image; + return boxDashedVertical(dashed, size, lineThickness); } // left & right @@ -1585,6 +1614,12 @@ optional BoxDrawingRenderer::buildBoxElements(char32_t codepoint, auto const left = tuple { box.leftval, 0u, *width / 2, true }; auto const right = tuple { box.rightval, *width / 2, *width, false }; auto const offset = horizontalOffset; + + auto fillImage = [&](auto ymax, auto xmax, auto x0, auto y0){ + for (auto const yi: iota(0u, ymax)) + for (auto const xi: iota(0u, xmax)) + image[((y0 + yi) * unbox(width)) + x0 + xi] = 0xFF; + }; for (auto const& pq: { left, right }) { auto const lm = get<0>(pq); @@ -1594,7 +1629,7 @@ optional BoxDrawingRenderer::buildBoxElements(char32_t codepoint, { case detail::NoLine: break; case detail::Light: { - auto const y0 = offset - lightThickness / 2; + auto const y0 = offset - (lightThickness / 2); // BoxDrawingLog()("{}: line:{}, x:{}..{}, y:{}..{}", // isFirst ? "left" : "right", // to_stringview(lm), @@ -1603,28 +1638,21 @@ optional BoxDrawingRenderer::buildBoxElements(char32_t codepoint, // y0, // y0 + lightThickness - 1, // offset); - for (auto const yi: iota(0u, lightThickness)) - for (auto const xi: iota(0u, x1 - x0)) - image[(y0 + yi) * *width + x0 + xi] = 0xFF; + fillImage(lightThickness, x1 - x0, x0, y0); + break; } case detail::Double: { - auto y0 = offset - lightThickness / 2 - lightThickness; - for (auto const yi: iota(0u, lightThickness)) - for (auto const xi: iota(0u, x1 - x0)) - image[(y0 + yi) * *width + x0 + xi] = 0xFF; + auto y0 = offset - (lightThickness / 2) - lightThickness; + fillImage(lightThickness, x1 - x0, x0, y0); y0 = offset + lightThickness / 2; - for (auto const yi: iota(0u, lightThickness)) - for (auto const xi: iota(0u, x1 - x0)) - image[(y0 + yi) * *width + x0 + xi] = 0xFF; + fillImage(lightThickness, x1 - x0, x0, y0); break; } case detail::Heavy: { - auto const y0 = offset - heavyThickness / 2; - for (auto const yi: iota(0u, heavyThickness)) - for (auto const xi: iota(0u, x1 - x0)) - image[(y0 + yi) * *width + x0 + xi] = 0xFF; + auto const y0 = offset - (heavyThickness / 2); + fillImage(heavyThickness, x1 - x0, x0, y0); break; } case detail::Light2: @@ -1646,6 +1674,11 @@ optional BoxDrawingRenderer::buildBoxElements(char32_t codepoint, auto const up = tuple { box.downval, 0u, *height / 2, true }; auto const down = tuple { box.upval, *height / 2, *height, false }; auto const offset = verticalOffset; + auto fillImage = [&](auto ymax, auto xmax, auto x0, auto y0){ + for (auto const yi: iota(0u, ymax)) + for (auto const xi: iota(0u, xmax)) + image[((y0 + yi) * unbox(width)) + x0 + xi] = 0xFF; + }; for (auto const& pq: { up, down }) { auto const lm = get<0>(pq); @@ -1656,29 +1689,21 @@ optional BoxDrawingRenderer::buildBoxElements(char32_t codepoint, { case detail::NoLine: break; case detail::Light: { - auto const x0 = offset - lightThickness / 2; - for (auto const yi: iota(0u, y1 - y0)) - for (auto const xi: iota(0u, lightThickness)) - image[(y0 + yi) * *width + x0 + xi] = 0xFF; + auto const x0 = offset - (lightThickness / 2); + fillImage(y1 - y0, lightThickness, x0, y0); break; } case detail::Double: { - auto x0 = offset - lightThickness / 2 - lightThickness; - for (auto const yi: iota(0u, y1 - y0)) - for (auto const xi: iota(0u, lightThickness)) - image[(y0 + yi) * *width + x0 + xi] = 0xFF; + auto x0 = offset - (lightThickness / 2) - lightThickness; + fillImage(y1 - y0, lightThickness, x0, y0); x0 = offset - lightThickness / 2 + lightThickness; - for (auto const yi: iota(0u, y1 - y0)) - for (auto const xi: iota(0u, lightThickness)) - image[(y0 + yi) * *width + x0 + xi] = 0xFF; + fillImage(y1 - y0, lightThickness, x0, y0); break; } case detail::Heavy: { - auto const x0 = offset - (lightThickness * 3) / 2; - for (auto const yi: iota(0u, y1 - y0)) - for (auto const xi: iota(0u, lightThickness * 3)) - image[(y0 + yi) * *width + x0 + xi] = 0xFF; + auto const x0 = offset - ((lightThickness * 3) / 2); + fillImage(y1 - y0, lightThickness * 3, x0, y0); break; } case detail::Light2: @@ -1702,7 +1727,7 @@ optional BoxDrawingRenderer::buildBoxElements(char32_t codepoint, { auto const x = int(double(y) * aInv); for (auto const xi: iota(-int(lineThickness) / 2, int(lineThickness) / 2)) - image[y * *width + (unsigned) max(0, min(x + xi, unbox(width) - 1))] = 0xFF; + image[(y * unbox(width)) + (unsigned) max(0, min(x + xi, unbox(width) - 1))] = 0xFF; } } if (unsigned(box.diagonalval) & unsigned(Diagonal::Backward)) @@ -1711,7 +1736,7 @@ optional BoxDrawingRenderer::buildBoxElements(char32_t codepoint, { auto const x = int(double(*height - y - 1) * aInv); for (auto const xi: iota(-int(lineThickness) / 2, int(lineThickness) / 2)) - image[y * *width + (unsigned) max(0, min(x + xi, unbox(width) - 1))] = 0xFF; + image[(y * unbox(width)) + (unsigned) max(0, min(x + xi, unbox(width) - 1))] = 0xFF; } } } diff --git a/src/vtrasterizer/CursorRenderer.cpp b/src/vtrasterizer/CursorRenderer.cpp index 10ab833681..2ddd95afe3 100644 --- a/src/vtrasterizer/CursorRenderer.cpp +++ b/src/vtrasterizer/CursorRenderer.cpp @@ -34,9 +34,9 @@ namespace uint32_t sliceIndex) noexcept { return static_cast(shape) + sliceIndex - + uint32_t(width - 1) - * (static_cast(std::numeric_limits::count()) - + static_cast(shape)); + + (uint32_t(width - 1) + * (static_cast(std::numeric_limits::count()) + + static_cast(shape))); } } // namespace @@ -129,8 +129,8 @@ auto CursorRenderer::createTileData(vtbackend::CursorShape cursorShape, assert(thickness <= static_cast(baseline)); for (auto y = size_t(0); y <= static_cast(thickness); ++y) for (size_t x = 0; x < *width; ++x) - image[(defaultBitmapSize.height.as() - 1 - baseY - unsigned(y)) - * unbox(width) + image[((defaultBitmapSize.height.as() - 1 - baseY - unsigned(y)) + * unbox(width)) + x] = 0xFF; return image; }); @@ -142,7 +142,7 @@ auto CursorRenderer::createTileData(vtbackend::CursorShape cursorShape, for (size_t x = 0; x < thickness; ++x) for (size_t y = 0; y < unbox(height); ++y) - image[y * *width + x] = 0xFF; + image[(y * unbox(width)) + x] = 0xFF; return image; }); case vtbackend::CursorShape::Rectangle: @@ -151,12 +151,12 @@ auto CursorRenderer::createTileData(vtbackend::CursorShape cursorShape, auto image = atlas::Buffer(unbox(width) * unbox(height), 0xFFu); auto const thickness = max(unbox(width) / 12, size_t { 1 }); - auto const innerWidth = unbox(width) - 2 * thickness; - auto const innerHeight = unbox(height) - 2 * thickness; + auto const innerWidth = unbox(width) - (2 * thickness); + auto const innerHeight = unbox(height) - (2 * thickness); for (size_t y = thickness; y <= innerHeight; ++y) for (size_t x = thickness; x <= innerWidth; ++x) - image[y * *width + x] = 0; + image[(y * unbox(width)) + x] = 0; return image; }); @@ -171,7 +171,7 @@ void CursorRenderer::render(crispy::point pos, int columnWidth, vtbackend::RGBCo { auto const directMappingIndex = toDirectMappingIndex(_shape, columnWidth, i); auto const tileIndex = _directMapping.toTileIndex(directMappingIndex); - auto const x = pos.x + int(i) * unbox(_gridMetrics.cellSize.width); + auto const x = pos.x + (int(i) * unbox(_gridMetrics.cellSize.width)); AtlasTileAttributes const& tileAttributes = _textureAtlas->directMapped(tileIndex); renderTile({ int(x) }, { pos.y }, color, tileAttributes); } diff --git a/src/vtrasterizer/DecorationRenderer.cpp b/src/vtrasterizer/DecorationRenderer.cpp index f383abc34c..9acf7030c8 100644 --- a/src/vtrasterizer/DecorationRenderer.cpp +++ b/src/vtrasterizer/DecorationRenderer.cpp @@ -96,7 +96,7 @@ void DecorationRenderer::renderLine(vtbackend::RenderLine const& line) for (auto const& mapping: CellFlagDecorationMappings) if (line.textAttributes.flags & mapping.first) renderDecoration(mapping.second, - _gridMetrics.mapBottomLeft(vtbackend::CellLocation { line.lineOffset }), + _gridMetrics.mapBottomLeft(vtbackend::CellLocation { .line = line.lineOffset }), line.usedColumns, line.textAttributes.decorationColor); } @@ -111,6 +111,7 @@ void DecorationRenderer::renderCell(vtbackend::RenderCell const& cell) cell.attributes.decorationColor); } +// NOLINTNEXTLINE(readability-function-cognitive-complexity) auto DecorationRenderer::createTileData(Decorator decoration, atlas::TileLocation tileLocation) -> TextureAtlas::TileCreateData { @@ -147,7 +148,7 @@ auto DecorationRenderer::createTileData(Decorator decoration, auto image = atlas::Buffer(imageSize.area(), 0); for (unsigned y = 1; y <= thickness; ++y) for (auto x: crispy::times(unbox(width))) - image[(unbox(height) - y0 - y) * unbox(width) + x] = 0xFF; + image[((unbox(height) - y0 - y) * unbox(width)) + x] = 0xFF; return image; }); } @@ -155,7 +156,7 @@ auto DecorationRenderer::createTileData(Decorator decoration, auto const thickness = max(1u, unsigned(ceil(double(underlineThickness()) * 2.0) / 3.0)); auto const y1 = max(0u, underlinePosition() + thickness); // y1 - 3 thickness can be negative - auto const y0 = max(0, static_cast(y1) - 3 * static_cast(thickness)); + auto const y0 = max(0, static_cast(y1) - (3 * static_cast(thickness))); auto const height = vtbackend::Height(y1 + thickness); auto const imageSize = ImageSize { width, height }; return create(imageSize, [&]() -> atlas::Buffer { @@ -164,8 +165,8 @@ auto DecorationRenderer::createTileData(Decorator decoration, { for (auto x: crispy::times(unbox(width))) { - image[(unbox(height) - y1 - y) * unbox(width) + x] = 0xFF; // top line - image[(unbox(height) - y0 - y) * unbox(width) + x] = 0xFF; // bottom line + image[((unbox(height) - y1 - y) * unbox(width)) + x] = 0xFF; // top line + image[((unbox(height) - y0 - y) * unbox(width)) + x] = 0xFF; // bottom line } } return image; @@ -231,8 +232,8 @@ auto DecorationRenderer::createTileData(Decorator decoration, auto image = atlas::Buffer(unbox(width) * unbox(height), 0); for (unsigned y = 1; y <= thickness; ++y) for (auto x: crispy::times(unbox(width))) - if (fabsf(float(x) / unbox(width) - 0.5f) >= 0.25f) - image[(unbox(height) - y0 - y) * unbox(width) + x] = 0xFF; + if (fabsf((float(x) / unbox(width)) - 0.5f) >= 0.25f) + image[((unbox(height) - y0 - y) * unbox(width)) + x] = 0xFF; return image; }); } @@ -247,16 +248,16 @@ auto DecorationRenderer::createTileData(Decorator decoration, for (unsigned y = gap; y < thickness + gap; ++y) for (unsigned x = gap; x < unbox(width) - gap; ++x) { - image[y * unbox(width) + x] = 0xFF; - image[(unbox(cellHeight) - 1 - y) * unbox(width) + x] = 0xFF; + image[(y * unbox(width)) + x] = 0xFF; + image[((unbox(cellHeight) - 1 - y) * unbox(width)) + x] = 0xFF; } // Draws the left and right vertical lines for (unsigned y = gap; y < unbox(cellHeight) - gap; y++) for (unsigned x = gap; x < thickness + gap; ++x) { - image[y * unbox(width) + x] = 0xFF; - image[y * unbox(width) + (unbox(width) - 1 - x)] = 0xFF; + image[(y * unbox(width)) + x] = 0xFF; + image[(y * unbox(width)) + (unbox(width) - 1 - x)] = 0xFF; } return image; }); @@ -269,7 +270,7 @@ auto DecorationRenderer::createTileData(Decorator decoration, auto image = atlas::Buffer(unbox(width) * unbox(cellHeight), 0); for (auto y: crispy::times(thickness)) for (auto x: crispy::times(unbox(width))) - image[y * unbox(width) + x] = 0xFF; + image[(y * unbox(width)) + x] = 0xFF; return image; }); } @@ -281,7 +282,7 @@ auto DecorationRenderer::createTileData(Decorator decoration, auto image = atlas::Buffer(unbox(width) * unbox(height), 0); for (unsigned y = 1; y <= thickness; ++y) for (auto x: crispy::times(unbox(width))) - image[y * unbox(width) + x] = 0xFF; + image[(y * unbox(width)) + x] = 0xFF; return image; }); } @@ -301,7 +302,7 @@ void DecorationRenderer::renderDecoration(Decorator decoration, auto const tileLocation = _textureAtlas->tileLocation(tileIndex); auto const tileData = createTileData(decoration, tileLocation); AtlasTileAttributes const& tileAttributes = _textureAtlas->directMapped(tileIndex); - renderTile({ pos.x + unbox(i) * unbox(_gridMetrics.cellSize.width) }, + renderTile({ pos.x + (unbox(i) * unbox(_gridMetrics.cellSize.width)) }, { pos.y - unbox(tileAttributes.bitmapSize.height) }, color, tileAttributes); diff --git a/src/vtrasterizer/ImageRenderer.cpp b/src/vtrasterizer/ImageRenderer.cpp index 2c12e06ff0..b5f3e865be 100644 --- a/src/vtrasterizer/ImageRenderer.cpp +++ b/src/vtrasterizer/ImageRenderer.cpp @@ -89,9 +89,9 @@ Renderable::AtlasTileAttributes const* ImageRenderer::getOrCreateCachedTileAttri // * fragment.offset().column.value * fragment.offset().line.value // * fragment.rasterizedImage().cellSize().width.value // * fragment.rasterizedImage().cellSize().height.value; - auto const key = ImageFragmentKey { fragment.rasterizedImage().image().id(), - fragment.offset(), - fragment.rasterizedImage().cellSize() }; + auto const key = ImageFragmentKey { .imageId = fragment.rasterizedImage().image().id(), + .offset = fragment.offset(), + .size = fragment.rasterizedImage().cellSize() }; auto const hash = crispy::strong_hash::compute(key); return textureAtlas().get_or_try_emplace( diff --git a/src/vtrasterizer/Pixmap.cpp b/src/vtrasterizer/Pixmap.cpp index db68d98f40..dc5000fe48 100644 --- a/src/vtrasterizer/Pixmap.cpp +++ b/src/vtrasterizer/Pixmap.cpp @@ -86,12 +86,12 @@ Pixmap& Pixmap::halfFilledCircleLeft() paint(xi, yf, 0xFF); }; auto const putAbove = [&](int x, int y) { - putpixel(x, y - h / 2); + putpixel(x, y - (h / 2)); }; auto const putBelow = [&](int x, int y) { - putpixel(x, y + h / 2); + putpixel(x, y + (h / 2)); }; - auto const radius = crispy::point { w, h / 2 }; + auto const radius = crispy::point { .x = w, .y = h / 2 }; drawEllipseArc(putAbove, size, radius, Arc::BottomLeft); drawEllipseArc(putBelow, size, radius, Arc::TopLeft); return *this; @@ -107,12 +107,12 @@ Pixmap& Pixmap::halfFilledCircleRight() paint(x, y, 0xFF); }; auto const putAbove = [&](int x, int y) { - putpixel(x, y - h / 2); + putpixel(x, y - (h / 2)); }; auto const putBelow = [&](int x, int y) { - putpixel(x, y + h / 2); + putpixel(x, y + (h / 2)); }; - auto const radius = crispy::point { w, h / 2 }; + auto const radius = crispy::point { .x = w, .y = h / 2 }; drawEllipseArc(putAbove, size, radius, Arc::BottomRight); drawEllipseArc(putBelow, size, radius, Arc::TopRight); return *this; @@ -134,8 +134,8 @@ Pixmap& Pixmap::segment_bar(int which) auto const r = unbox(size.width) - z; auto const t = static_cast(ceil(unbox(size.height) * (1 / 8_th))); // Z; - auto const b = unbox(size.height) - baseLine - z / 2; - auto const m = t + (b - t) / 2; + auto const b = unbox(size.height) - baseLine - (z / 2); + auto const m = t + ((b - t) / 2); // clang-format off switch (which) diff --git a/src/vtrasterizer/RenderTarget.cpp b/src/vtrasterizer/RenderTarget.cpp index ec44053391..92f4020249 100644 --- a/src/vtrasterizer/RenderTarget.cpp +++ b/src/vtrasterizer/RenderTarget.cpp @@ -62,9 +62,9 @@ auto Renderable::sliceTileData(Renderable::TextureAtlas::TileCreateData const& c bitmap.resize(subSize.area() * colorComponentCount); for (uintptr_t rowIndex = 0; rowIndex < unbox(subSize.height); ++rowIndex) { - uint8_t* targetRow = bitmap.data() + rowIndex * subPitch; - uint8_t const* sourceRow = - createData.bitmap.data() + rowIndex * pitch + uintptr_t(sliceIndex.beginX) * colorComponentCount; + uint8_t* targetRow = bitmap.data() + (rowIndex * subPitch); + uint8_t const* sourceRow = createData.bitmap.data() + (rowIndex * pitch) + + (uintptr_t(sliceIndex.beginX) * colorComponentCount); Require(sourceRow + subPitch <= createData.bitmap.data() + createData.bitmap.size()); std::copy_n(sourceRow, subPitch, targetRow); } diff --git a/src/vtrasterizer/Renderer.cpp b/src/vtrasterizer/Renderer.cpp index 1f96cbb492..959a67a9d4 100644 --- a/src/vtrasterizer/Renderer.cpp +++ b/src/vtrasterizer/Renderer.cpp @@ -53,8 +53,10 @@ namespace auto gm = GridMetrics {}; gm.pageSize = pageSize; - gm.cellMargin = { 0, 0, 0, 0 }; // TODO (pass as args, and make use of them) - gm.pageMargin = { 0, 0, 0 }; // TODO (fill early) + gm.cellMargin = { + .top = 0, .left = 0, .bottom = 0, .right = 0 + }; // TODO (pass as args, and make use of them) + gm.pageMargin = { .left = 0, .top = 0, .bottom = 0 }; // TODO (fill early) loadGridMetricsFromFont(font, gm, textShaper); @@ -155,7 +157,8 @@ void Renderer::setRenderTarget(RenderTarget& renderTarget) _renderTarget = &renderTarget; // Reset DirectMappingAllocator (also skipping zero-tile). - _directMappingAllocator = atlas::DirectMappingAllocator { 1 }; + _directMappingAllocator = + atlas::DirectMappingAllocator { .currentlyAllocatedCount = 1 }; // Explicitly enable direct mapping for everything BUT the text renderer. // Only the text renderer's direct mapping is configurable (for simplicity for now). @@ -174,11 +177,12 @@ void Renderer::configureTextureAtlas() Require(_renderTarget); auto const atlasCellSize = _gridMetrics.cellSize; - auto atlasProperties = atlas::AtlasProperties { atlas::Format::RGBA, - atlasCellSize, - _atlasHashtableSlotCount, - _atlasTileCount, - _directMappingAllocator.currentlyAllocatedCount }; + auto atlasProperties = + atlas::AtlasProperties { .format = atlas::Format::RGBA, + .tileSize = atlasCellSize, + .hashCount = _atlasHashtableSlotCount, + .tileCount = _atlasTileCount, + .directMappingCount = _directMappingAllocator.currentlyAllocatedCount }; Require(atlasProperties.tileCount.value > 0); diff --git a/src/vtrasterizer/TextClusterGrouper.cpp b/src/vtrasterizer/TextClusterGrouper.cpp index 7afc64c96b..0fcb7be3b9 100644 --- a/src/vtrasterizer/TextClusterGrouper.cpp +++ b/src/vtrasterizer/TextClusterGrouper.cpp @@ -46,16 +46,16 @@ void TextClusterGrouper::renderLine(std::string_view text, auto graphemeClusterSegmenter = unicode::utf8_grapheme_segmenter(text); auto columnOffset = vtbackend::ColumnOffset(0); - _initialPenPosition = vtbackend::CellLocation { lineOffset, columnOffset }; + _initialPenPosition = vtbackend::CellLocation { .line = lineOffset, .column = columnOffset }; for (auto const& graphemeCluster: graphemeClusterSegmenter) { - auto const gridPosition = vtbackend::CellLocation { lineOffset, columnOffset }; + auto const gridPosition = vtbackend::CellLocation { .line = lineOffset, .column = columnOffset }; auto const width = graphemeClusterWidth(graphemeCluster); renderCell(gridPosition, graphemeCluster, style, foregroundColor); for (int i = 1; i < width; ++i) - renderCell(vtbackend::CellLocation { gridPosition.line, columnOffset + i }, + renderCell(vtbackend::CellLocation { .line = gridPosition.line, .column = columnOffset + i }, U" ", style, foregroundColor); diff --git a/src/vtrasterizer/TextClusterGrouper_test.cpp b/src/vtrasterizer/TextClusterGrouper_test.cpp index bb9a39ed9e..42ffa89713 100644 --- a/src/vtrasterizer/TextClusterGrouper_test.cpp +++ b/src/vtrasterizer/TextClusterGrouper_test.cpp @@ -162,15 +162,19 @@ struct EventRecorder final: public TextClusterGrouper::Events TextStyle style, vtbackend::RGBColor color) override { - events.emplace_back(TextClusterGroup { - std::u32string(codepoints), to_vector(clusters), initialPenPosition, style, color }); + events.emplace_back(TextClusterGroup { .codepoints = std::u32string(codepoints), + .clusters = to_vector(clusters), + .initialPenPosition = initialPenPosition, + .style = style, + .color = color }); } bool renderBoxDrawingCell(vtbackend::CellLocation position, char32_t codepoint, vtbackend::RGBColor foregroundColor) override { - events.emplace_back(BoxDrawingCell { position, codepoint, foregroundColor }); + events.emplace_back(BoxDrawingCell { + .position = position, .codepoint = codepoint, .foregroundColor = foregroundColor }); return true; } }; diff --git a/src/vtrasterizer/TextRenderer.cpp b/src/vtrasterizer/TextRenderer.cpp index 0be837b4d7..f28bb2f89f 100644 --- a/src/vtrasterizer/TextRenderer.cpp +++ b/src/vtrasterizer/TextRenderer.cpp @@ -346,8 +346,8 @@ void TextRenderer::restrictToTileSize(TextureAtlas::TileCreateData& tileCreateDa for (auto const rowIndex: ranges::views::iota(uintptr_t { 0 }, unbox(targetSize.height))) { - uint8_t* targetRow = slicedBitmap.data() + rowIndex * targetPitch; - uint8_t const* sourceRow = tileCreateData.bitmap.data() + rowIndex * sourcePitch; + uint8_t* targetRow = slicedBitmap.data() + (rowIndex * targetPitch); + uint8_t const* sourceRow = tileCreateData.bitmap.data() + (rowIndex * sourcePitch); Require(sourceRow + targetPitch <= tileCreateData.bitmap.data() + tileCreateData.bitmap.size()); std::copy_n(sourceRow, targetPitch, targetRow); } @@ -496,7 +496,7 @@ point TextRenderer::applyGlyphPositionToPen(point pen, // tileAttributes.bitmapSize.height, // gpos.presentation); - return point { x, y }; + return point { .x = x, .y = y }; } /** @@ -662,9 +662,9 @@ auto TextRenderer::createSlicedRasterizedGlyph(atlas::TileLocation tileLocation, auto bitmap = vector(subSize.area() * colorComponentCount); for (uintptr_t rowIndex = 0; rowIndex < unbox(subSize.height); ++rowIndex) { - uint8_t* targetRow = bitmap.data() + rowIndex * subPitch; - uint8_t const* sourceRow = createData.bitmap.data() + rowIndex * pitch - + uintptr_t(xOffset) * colorComponentCount; + uint8_t* targetRow = bitmap.data() + (rowIndex * subPitch); + uint8_t const* sourceRow = createData.bitmap.data() + (rowIndex * pitch) + + (uintptr_t(xOffset) * colorComponentCount); Require(sourceRow + subPitch <= createData.bitmap.data() + createData.bitmap.size()); std::memcpy(targetRow, sourceRow, subPitch); } @@ -686,9 +686,9 @@ auto TextRenderer::createSlicedRasterizedGlyph(atlas::TileLocation tileLocation, auto const headPitch = unbox(headWidth) * colorComponentCount; auto headBitmap = vector(headSize.area() * colorComponentCount); for (uintptr_t rowIndex = 0; rowIndex < unbox(headSize.height); ++rowIndex) - std::memcpy(headBitmap.data() + rowIndex * headPitch, // target - createData.bitmap.data() + rowIndex * pitch, // source - headPitch); // sub-image line length + std::memcpy(headBitmap.data() + (rowIndex * headPitch), // target + createData.bitmap.data() + (rowIndex * pitch), // source + headPitch); // sub-image line length return { createTileData(tileLocation, std::move(headBitmap), @@ -836,8 +836,8 @@ text::shape_result TextRenderer::createTextShapedGlyphPositions(u32string_view c auto run = unicode::run_segmenter::range {}; auto rs = unicode::run_segmenter(codepoints); // TODO Consider moving run segmentation to text grouper while (rs.consume(out(run))) - for (text::glyph_position& glyphPosition: shapeTextRun(run, codepoints, clusters, style)) - glyphPositions.emplace_back(std::move(glyphPosition)); + for (text::glyph_position const& glyphPosition: shapeTextRun(run, codepoints, clusters, style)) + glyphPositions.emplace_back(glyphPosition); return glyphPositions; } diff --git a/src/vtrasterizer/utils.cpp b/src/vtrasterizer/utils.cpp index 35d7389322..bf15958935 100644 --- a/src/vtrasterizer/utils.cpp +++ b/src/vtrasterizer/utils.cpp @@ -43,7 +43,7 @@ vector downsampleRGBA(vector const& bitmap, unsigned int count = 0; for (unsigned y = sr; y < min(sr + factor, size.height.as()); y++) { - uint8_t const* p = bitmap.data() + (y * *size.width * 4) + sc * 4; + uint8_t const* p = bitmap.data() + (y * unbox(size.width) * 4) + (sc * 4); for (unsigned x = sc; x < min(sc + factor, size.width.as()); x++, count++) { b += *(p++); @@ -101,7 +101,7 @@ vector downsample(vector const& bitmap, unsigned count = 0; // number of pixels being averaged for (auto y = sr; y < min(sr + factor, size.height.as()); y++) { - uint8_t const* p = bitmap.data() + (y * *size.width * numComponents) + sc * numComponents; + uint8_t const* p = bitmap.data() + (y * *size.width * numComponents) + (sc * numComponents); for (auto x = sc; x < min(sc + factor, size.width.as()); x++, count++) for (auto const k: ::ranges::views::iota(0u, numComponents)) values.at(k) += *(p++);