// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #include "Lines.hpp" #include "TextLineCursor.hpp" #include "Text.hpp" #include "RawFont.hpp" #if DEBUG_GUI_TEXT_LINES == 1 #define debug_text_lines(...) LOG_DEBUG(__VA_ARGS__) #else #define debug_text_lines(...) #endif namespace gui { void Lines::addToInvisibleLines(TextLine line) { line.setVisible(false); emplace(std::move(line)); } auto Lines::linesVAlign(Length parentSize) -> void { for (auto &line : lines) { line.alignV(text->getAlignment(Axis::Y), parentSize, linesHeight()); } } auto Lines::linesHAlign(Length parentSize) -> void { for (auto &line : lines) { line.alignH(text->getAlignment(Axis::X), parentSize); } } auto Lines::draw(BlockCursor &drawCursor, Length w, Length h, Position lineYPosition, Position lineXPosition) -> void { Position initialTopPadding = lineYPosition; while (true) { auto textLine = gui::TextLine(drawCursor, w); if (textLine.length() == 0 && textLine.getLineEnd()) { debug_text_lines("cant show more text from this document"); stopCondition = LinesDrawStop::OutOfText; break; } if ((lineYPosition + textLine.height()) > (h + initialTopPadding)) { // no more space for next line debug_text_lines("no more space for next text_line: %d + %" PRIu32 " > %" PRIu32, lineYPosition, textLine.height(), h); stopCondition = LinesDrawStop::OutOfSpace; addToInvisibleLines(std::move(textLine)); break; } emplace(std::move(textLine)); auto &line = last(); line.setParent(text); line.setPosition(lineXPosition, lineYPosition); lineYPosition += line.height(); } } auto Lines::draw(BlockCursor &drawCursor, Length w, Length h, Position lineYPosition, Position lineXPosition, unsigned int linesCount) -> void { Position initialTopPadding = lineYPosition; Length initHeight = text->getTextFormat().getFont()->info.line_height; while (true) { auto textLine = gui::TextLine(drawCursor, w, initHeight, underLineProperties); if ((textLine.height() > 0) && initHeight != textLine.height()) { initHeight = textLine.height(); } if (!previousLinesStart.empty() && (textLine.length() == 0) && textLine.getLineEnd()) { stopCondition = LinesDrawStop::OutOfText; break; } if ((lineYPosition + initHeight) > (h + initialTopPadding)) { if ((textLine.length() == 0) && textLine.getLineEnd()) { stopCondition = LinesDrawStop::OutOfText; break; } else { stopCondition = LinesDrawStop::OutOfSpace; addToInvisibleLines(std::move(textLine)); break; } } if (lines.size() >= linesCount) { if ((textLine.length() == 0) && textLine.getLineEnd()) { stopCondition = LinesDrawStop::OutOfText; break; } else { stopCondition = LinesDrawStop::OutOfSpace; addToInvisibleLines(std::move(textLine)); break; } } emplace(std::move(textLine)); auto &line = last(); line.setParent(text); line.setPosition(lineXPosition, lineYPosition); lineYPosition += line.height() + linesSpacing; } } TextLine *Lines::getLine(unsigned int lineNr) { if (lines.empty() || lineNr >= lines.size()) { return nullptr; } auto it = std::next(lines.begin(), lineNr); return &*it; } auto Lines::addToPreviousLinesStartList(unsigned int lineStartBlockNumber, unsigned int lineStartBlockPosition) -> void { auto it = std::find_if( previousLinesStart.begin(), previousLinesStart.end(), [&lineStartBlockNumber, &lineStartBlockPosition](const std::tuple &lineStart) { return std::get<0>(lineStart) == lineStartBlockNumber && std::get<1>(lineStart) == lineStartBlockPosition; }); if (it == previousLinesStart.end()) { previousLinesStart.emplace_back(lineStartBlockNumber, lineStartBlockPosition); } } } // namespace gui