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
17class KateRenderer;
18
19class KateLineLayoutMap
20{
21public:
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
34private:
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
54class KateLayoutCache : public QObject
55{
56public:
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
131private:
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
137private:
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

source code of ktexteditor/src/render/katelayoutcache.h