1 | /* |
2 | SPDX-FileCopyrightText: 2005 Hamish Rodda <rodda@kde.org> |
3 | SPDX-FileCopyrightText: 2008-2018 Dominik Haumann <dhaumann@kde.org> |
4 | |
5 | SPDX-License-Identifier: LGPL-2.0-or-later |
6 | */ |
7 | |
8 | #ifndef KATELAYOUTCACHE_H |
9 | #define KATELAYOUTCACHE_H |
10 | |
11 | #include <QPair> |
12 | |
13 | #include <ktexteditor/range.h> |
14 | |
15 | #include "katetextlayout.h" |
16 | |
17 | class KateRenderer; |
18 | |
19 | class KateLineLayoutMap |
20 | { |
21 | public: |
22 | void clear(); |
23 | |
24 | void insert(int realLine, std::unique_ptr<KateLineLayout> lineLayoutPtr); |
25 | |
26 | void relayoutLines(int startRealLine, int endRealLine); |
27 | |
28 | void slotEditDone(int fromLine, int toLine, int shiftAmount, std::vector<KateTextLayout> &textLayouts); |
29 | |
30 | KateLineLayout *find(int i); |
31 | |
32 | typedef std::pair<int, std::unique_ptr<KateLineLayout>> LineLayoutPair; |
33 | |
34 | private: |
35 | typedef std::vector<LineLayoutPair> LineLayoutMap; |
36 | LineLayoutMap m_lineLayouts; |
37 | }; |
38 | |
39 | /** |
40 | * This class handles Kate's caching of layouting information (in KateLineLayout |
41 | * and KateTextLayout). This information is used primarily by both the view and |
42 | * the renderer. |
43 | * |
44 | * We outsource the hardcore layouting logic to the renderer, but other than |
45 | * that, this class handles all manipulation of the layout objects. |
46 | * |
47 | * This is separate from the renderer 1) for clarity 2) so you can have separate |
48 | * caches for separate views of the same document, even for view and printer |
49 | * (if the renderer is made to support rendering onto different targets). |
50 | * |
51 | * @author Hamish Rodda \<rodda@kde.org\> |
52 | */ |
53 | |
54 | class KateLayoutCache : public QObject |
55 | { |
56 | public: |
57 | explicit KateLayoutCache(KateRenderer *renderer, QObject *parent); |
58 | |
59 | void clear(); |
60 | |
61 | int viewWidth() const; |
62 | void setViewWidth(int width); |
63 | |
64 | bool wrap() const; |
65 | void setWrap(bool wrap); |
66 | |
67 | bool acceptDirtyLayouts() const; |
68 | void setAcceptDirtyLayouts(bool accept); |
69 | |
70 | // BEGIN generic methods to get/set layouts |
71 | /** |
72 | * Returns the KateLineLayout for the specified line. |
73 | * |
74 | * If one does not exist, it will be created and laid out. |
75 | * Layouts which are not directly part of the view will be kept until the |
76 | * cache is full or until they are invalidated by other means (eg. the text |
77 | * changes). |
78 | * |
79 | * This function shall never return null |
80 | * |
81 | * \param realLine real line number of the layout to retrieve. |
82 | * \param virtualLine virtual line number. only needed if you think it may have changed |
83 | * (ie. basically internal to KateLayoutCache) |
84 | */ |
85 | KateLineLayout *line(int realLine, int virtualLine = -1); |
86 | |
87 | /// Returns the layout describing the text line which is occupied by \p realCursor. |
88 | KateTextLayout textLayout(const KTextEditor::Cursor realCursor); |
89 | |
90 | /// Returns the layout of the specified realLine + viewLine. |
91 | /// if viewLine is -1, return the last. |
92 | KateTextLayout textLayout(uint realLine, int viewLine); |
93 | // END |
94 | |
95 | // BEGIN methods to do with the caching of lines visible within a view |
96 | /// Returns the layout of the corresponding line in the view |
97 | KateTextLayout &viewLine(int viewLine); |
98 | |
99 | /** |
100 | * Find the view line of the cursor, relative to the display (0 = top line of view, 1 = second line, etc.) |
101 | * |
102 | * If @p limitToVisible is true, the function can return -2 for lines below the view. The idea is to get extra |
103 | * information about where the line lies when its out of the view so the clients doesn't have to make second |
104 | * call of this function with limitToVisible = false and potentionaly rerendering the whole document. |
105 | * |
106 | * \param virtualCursor cursor position |
107 | * \param limitToVisible if true, limit the search to only visible lines |
108 | * |
109 | * @return line number relative to the display. If @p limitToVisible is true, |
110 | * then valid values are only positive, negative values are invalid cursors for -1 and -2 for cursor is |
111 | * below the view. |
112 | */ |
113 | int displayViewLine(const KTextEditor::Cursor virtualCursor, bool limitToVisible = false); |
114 | |
115 | int viewCacheLineCount() const; |
116 | KTextEditor::Cursor viewCacheStart() const; |
117 | KTextEditor::Cursor viewCacheEnd() const; |
118 | void updateViewCache(const KTextEditor::Cursor startPos, int newViewLineCount = -1, int viewLinesScrolled = 0); |
119 | |
120 | void relayoutLines(int startRealLine, int endRealLine); |
121 | |
122 | // find the index of the last view line for a specific line |
123 | int lastViewLine(int realLine); |
124 | // find the view line of cursor c (0 = same line, 1 = down one, etc.) |
125 | int viewLine(const KTextEditor::Cursor realCursor); |
126 | int viewLineCount(int realLine); |
127 | |
128 | void viewCacheDebugOutput() const; |
129 | // END |
130 | |
131 | private: |
132 | void wrapLine(KTextEditor::Document *, const KTextEditor::Cursor position); |
133 | void unwrapLine(KTextEditor::Document *, int line); |
134 | void insertText(KTextEditor::Document *, const KTextEditor::Cursor position, const QString &text); |
135 | void removeText(KTextEditor::Document *, KTextEditor::Range range, const QString &); |
136 | |
137 | private: |
138 | KateRenderer *m_renderer; |
139 | |
140 | /** |
141 | * The master cache of all line layouts. |
142 | * |
143 | * Layouts which are not within the current view cache and whose |
144 | * refcount == 1 are only known to the cache and can be safely deleted. |
145 | */ |
146 | KateLineLayoutMap m_lineLayouts; |
147 | |
148 | // Convenience vector for quick direct access to the specific text layout |
149 | KTextEditor::Cursor m_startPos = KTextEditor::Cursor::invalid(); |
150 | |
151 | std::vector<KateTextLayout> m_textLayouts; |
152 | |
153 | int m_viewWidth = 0; |
154 | bool m_wrap = false; |
155 | bool m_acceptDirtyLayouts = false; |
156 | }; |
157 | |
158 | #endif |
159 | |