init
Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
Close stale issues and PRs / stale (push) Has been cancelled
Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
Close stale issues and PRs / stale (push) Has been cancelled
This commit is contained in:
220
Telegram/lib_ui/ui/text/text_renderer.h
Normal file
220
Telegram/lib_ui/ui/text/text_renderer.h
Normal file
@@ -0,0 +1,220 @@
|
||||
// This file is part of Desktop App Toolkit,
|
||||
// a set of libraries for developing nice desktop applications.
|
||||
//
|
||||
// For license and copyright information please follow this link:
|
||||
// https://github.com/desktop-app/legal/blob/master/LEGAL
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#include "ui/text/text.h"
|
||||
#include "ui/text/text_block.h"
|
||||
#include "ui/text/text_custom_emoji.h"
|
||||
|
||||
#include <private/qtextengine_p.h>
|
||||
|
||||
class QTextItemInt;
|
||||
struct QScriptAnalysis;
|
||||
struct QScriptLine;
|
||||
struct QScriptItem;
|
||||
|
||||
namespace Ui::Text {
|
||||
|
||||
inline constexpr auto kQuoteCollapsedLines = 3;
|
||||
|
||||
class AbstractBlock;
|
||||
|
||||
struct FixedRange {
|
||||
QFixed from;
|
||||
QFixed till;
|
||||
|
||||
[[nodiscard]] bool empty() const {
|
||||
return (till <= from);
|
||||
}
|
||||
};
|
||||
|
||||
[[nodiscard]] FixedRange Intersected(FixedRange a, FixedRange b);
|
||||
[[nodiscard]] bool Intersects(FixedRange a, FixedRange b);
|
||||
[[nodiscard]] FixedRange United(FixedRange a, FixedRange b);
|
||||
[[nodiscard]] bool Distinct(FixedRange a, FixedRange b);
|
||||
|
||||
class Renderer final {
|
||||
public:
|
||||
explicit Renderer(const Ui::Text::String &t);
|
||||
~Renderer();
|
||||
|
||||
void draw(QPainter &p, const PaintContext &context);
|
||||
[[nodiscard]] StateResult getState(
|
||||
QPoint point,
|
||||
GeometryDescriptor geometry,
|
||||
StateRequest request);
|
||||
|
||||
private:
|
||||
static constexpr int kSpoilersRectsSize = 512;
|
||||
|
||||
struct BidiControl;
|
||||
|
||||
void enumerate();
|
||||
|
||||
[[nodiscard]] crl::time now() const;
|
||||
void initNextParagraph(
|
||||
Blocks::const_iterator i,
|
||||
int16 paragraphIndex,
|
||||
Qt::LayoutDirection direction);
|
||||
void initNextLine();
|
||||
void initParagraphBidi();
|
||||
bool drawLine(
|
||||
uint16 lineEnd,
|
||||
Blocks::const_iterator blocksEnd);
|
||||
[[nodiscard]] FixedRange findSelectEmojiRange(
|
||||
const QScriptItem &si,
|
||||
std::vector<Block>::const_iterator blockIt,
|
||||
QFixed x,
|
||||
TextSelection selection) const;
|
||||
[[nodiscard]] FixedRange findSelectTextRange(
|
||||
const QScriptItem &si,
|
||||
int itemStart,
|
||||
int itemEnd,
|
||||
QFixed x,
|
||||
QFixed itemWidth,
|
||||
const QTextItemInt &gf,
|
||||
TextSelection selection) const;
|
||||
void fillSelectRange(FixedRange range);
|
||||
void pushHighlightRange(FixedRange range);
|
||||
void pushSpoilerRange(
|
||||
FixedRange range,
|
||||
FixedRange selected,
|
||||
bool isElidedItem,
|
||||
bool rtl);
|
||||
void fillRectsFromRanges();
|
||||
void fillRectsFromRanges(
|
||||
QVarLengthArray<QRect, kSpoilersRectsSize> &rects,
|
||||
QVarLengthArray<FixedRange> &ranges);
|
||||
void paintSpoilerRects();
|
||||
void paintSpoilerRects(
|
||||
const QVarLengthArray<QRect, kSpoilersRectsSize> &rects,
|
||||
const style::color &color,
|
||||
int index);
|
||||
void composeHighlightPath();
|
||||
[[nodiscard]] const AbstractBlock *markBlockForElisionGetEnd(
|
||||
int blockIndex);
|
||||
void setElideBidi(int elideStart);
|
||||
void prepareElidedLine(
|
||||
QString &lineText,
|
||||
int lineStart,
|
||||
int &lineLength,
|
||||
const AbstractBlock *&endBlock,
|
||||
int recursed = 0);
|
||||
void prepareElisionAt(
|
||||
QString &lineText,
|
||||
int &lineLength,
|
||||
uint16 position);
|
||||
void restoreAfterElided();
|
||||
|
||||
void fillParagraphBg(int paddingBottom);
|
||||
|
||||
void applyBlockProperties(
|
||||
QTextEngine &e,
|
||||
not_null<const AbstractBlock*> block);
|
||||
[[nodiscard]] ClickHandlerPtr lookupLink(
|
||||
const AbstractBlock *block) const;
|
||||
|
||||
const String *_t = nullptr;
|
||||
GeometryDescriptor _geometry;
|
||||
SpoilerData *_spoiler = nullptr;
|
||||
SpoilerMessCache *_spoilerCache = nullptr;
|
||||
QPainter *_p = nullptr;
|
||||
const style::TextPalette *_palette = nullptr;
|
||||
std::span<SpecialColor> _colors;
|
||||
bool _pausedEmoji = false;
|
||||
bool _pausedSpoiler = false;
|
||||
style::align _align = style::al_topleft;
|
||||
QPen _originalPen;
|
||||
QPen _originalPenSelected;
|
||||
QPen _quoteLinkPenOverride;
|
||||
const QPen *_currentPen = nullptr;
|
||||
const QPen *_currentPenSelected = nullptr;
|
||||
struct {
|
||||
bool spoiler = false;
|
||||
bool selectActiveBlock = false; // For monospace.
|
||||
} _background;
|
||||
int _yFrom = 0;
|
||||
int _yTo = 0;
|
||||
TextSelection _selection = { 0, 0 };
|
||||
bool _fullWidthSelection = true;
|
||||
HighlightInfoRequest *_highlight = nullptr;
|
||||
const QChar *_str = nullptr;
|
||||
mutable crl::time _cachedNow = 0;
|
||||
float64 _spoilerOpacity = 0.;
|
||||
QVarLengthArray<FixedRange> _spoilerRanges;
|
||||
QVarLengthArray<FixedRange> _spoilerSelectedRanges;
|
||||
QVarLengthArray<FixedRange> _highlightRanges;
|
||||
QVarLengthArray<QRect, kSpoilersRectsSize> _spoilerRects;
|
||||
QVarLengthArray<QRect, kSpoilersRectsSize> _spoilerSelectedRects;
|
||||
QVarLengthArray<QRect, kSpoilersRectsSize> _highlightRects;
|
||||
|
||||
std::optional<CustomEmoji::Context> _customEmojiContext;
|
||||
int _customEmojiSkip = 0;
|
||||
int _indexOfElidedBlock = -1; // For spoilers.
|
||||
|
||||
// current paragraph data
|
||||
Blocks::const_iterator _paragraphStartBlock;
|
||||
Qt::LayoutDirection _paragraphDirection = Qt::LayoutDirectionAuto;
|
||||
int _paragraphStart = 0;
|
||||
int _paragraphLength = 0;
|
||||
QVarLengthArray<QScriptAnalysis, 4096> _paragraphAnalysis;
|
||||
|
||||
// current quote data
|
||||
QuoteDetails *_quote = nullptr;
|
||||
Qt::LayoutDirection _quoteDirection = Qt::LayoutDirectionAuto;
|
||||
int _quoteShift = 0;
|
||||
int _quoteIndex = 0;
|
||||
QMargins _quotePadding;
|
||||
int _quoteLinesLeft = -1;
|
||||
int _quoteTop = 0;
|
||||
int _quoteLineTop = 0;
|
||||
QuotePaintCache *_quotePreCache = nullptr;
|
||||
QuotePaintCache *_quoteBlockquoteCache = nullptr;
|
||||
bool _quotePreValid = false;
|
||||
bool _quoteBlockquoteValid = false;
|
||||
|
||||
ClickHandlerPtr _quoteExpandLink;
|
||||
bool _quoteExpandLinkLookup = false;
|
||||
|
||||
// current line data
|
||||
style::font _f;
|
||||
int _startLeft = 0;
|
||||
int _startTop = 0;
|
||||
int _startLineWidth = 0;
|
||||
QFixed _x, _wLeft, _last_rPadding;
|
||||
int _y = 0;
|
||||
int _yDelta = 0;
|
||||
int _lineIndex = 0;
|
||||
int _lineHeight = 0;
|
||||
int _fontHeight = 0;
|
||||
bool _breakEverywhere = false;
|
||||
bool _elidedLine = false;
|
||||
|
||||
// elided hack support
|
||||
int _blocksSize = 0;
|
||||
int _elideSavedIndex = 0;
|
||||
std::optional<Block> _elideSavedBlock;
|
||||
|
||||
int _lineStart = 0;
|
||||
int _localFrom = 0;
|
||||
int _lineStartBlock = 0;
|
||||
QFixed _lineStartPadding = 0;
|
||||
QFixed _lineWidth = 0;
|
||||
|
||||
// link and symbol resolve
|
||||
QFixed _lookupX = 0;
|
||||
int _lookupY = 0;
|
||||
bool _lookupSymbol = false;
|
||||
bool _lookupLink = false;
|
||||
StateRequest _lookupRequest;
|
||||
StateResult _lookupResult;
|
||||
|
||||
bool _elisionMiddle = false;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Ui::Text
|
||||
Reference in New Issue
Block a user