File indexing completed on 2024-03-24 04:00:21
0001 /* 0002 SPDX-FileCopyrightText: 2005 Hamish Rodda <rodda@kde.org> 0003 SPDX-FileCopyrightText: 2008-2018 Dominik Haumann <dhaumann@kde.org> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #ifndef KATELAYOUTCACHE_H 0009 #define KATELAYOUTCACHE_H 0010 0011 #include <QPair> 0012 0013 #include <ktexteditor/range.h> 0014 0015 #include "katetextlayout.h" 0016 0017 class KateRenderer; 0018 0019 class KateLineLayoutMap 0020 { 0021 public: 0022 void clear(); 0023 0024 void insert(int realLine, std::unique_ptr<KateLineLayout> lineLayoutPtr); 0025 0026 void relayoutLines(int startRealLine, int endRealLine); 0027 0028 void slotEditDone(int fromLine, int toLine, int shiftAmount, std::vector<KateTextLayout> &textLayouts); 0029 0030 KateLineLayout *find(int i); 0031 0032 typedef std::pair<int, std::unique_ptr<KateLineLayout>> LineLayoutPair; 0033 0034 private: 0035 typedef std::vector<LineLayoutPair> LineLayoutMap; 0036 LineLayoutMap m_lineLayouts; 0037 }; 0038 0039 /** 0040 * This class handles Kate's caching of layouting information (in KateLineLayout 0041 * and KateTextLayout). This information is used primarily by both the view and 0042 * the renderer. 0043 * 0044 * We outsource the hardcore layouting logic to the renderer, but other than 0045 * that, this class handles all manipulation of the layout objects. 0046 * 0047 * This is separate from the renderer 1) for clarity 2) so you can have separate 0048 * caches for separate views of the same document, even for view and printer 0049 * (if the renderer is made to support rendering onto different targets). 0050 * 0051 * @author Hamish Rodda \<rodda@kde.org\> 0052 */ 0053 0054 class KateLayoutCache : public QObject 0055 { 0056 public: 0057 explicit KateLayoutCache(KateRenderer *renderer, QObject *parent); 0058 0059 void clear(); 0060 0061 int viewWidth() const; 0062 void setViewWidth(int width); 0063 0064 bool wrap() const; 0065 void setWrap(bool wrap); 0066 0067 bool acceptDirtyLayouts() const; 0068 void setAcceptDirtyLayouts(bool accept); 0069 0070 // BEGIN generic methods to get/set layouts 0071 /** 0072 * Returns the KateLineLayout for the specified line. 0073 * 0074 * If one does not exist, it will be created and laid out. 0075 * Layouts which are not directly part of the view will be kept until the 0076 * cache is full or until they are invalidated by other means (eg. the text 0077 * changes). 0078 * 0079 * This function shall never return null 0080 * 0081 * \param realLine real line number of the layout to retrieve. 0082 * \param virtualLine virtual line number. only needed if you think it may have changed 0083 * (ie. basically internal to KateLayoutCache) 0084 */ 0085 KateLineLayout *line(int realLine, int virtualLine = -1); 0086 0087 /// Returns the layout describing the text line which is occupied by \p realCursor. 0088 KateTextLayout textLayout(const KTextEditor::Cursor realCursor); 0089 0090 /// Returns the layout of the specified realLine + viewLine. 0091 /// if viewLine is -1, return the last. 0092 KateTextLayout textLayout(uint realLine, int viewLine); 0093 // END 0094 0095 // BEGIN methods to do with the caching of lines visible within a view 0096 /// Returns the layout of the corresponding line in the view 0097 KateTextLayout &viewLine(int viewLine); 0098 0099 /** 0100 * Find the view line of the cursor, relative to the display (0 = top line of view, 1 = second line, etc.) 0101 * 0102 * If @p limitToVisible is true, the function can return -2 for lines below the view. The idea is to get extra 0103 * information about where the line lies when its out of the view so the clients doesn't have to make second 0104 * call of this function with limitToVisible = false and potentionaly rerendering the whole document. 0105 * 0106 * \param virtualCursor cursor position 0107 * \param limitToVisible if true, limit the search to only visible lines 0108 * 0109 * @return line number relative to the display. If @p limitToVisible is true, 0110 * then valid values are only positive, negative values are invalid cursors for -1 and -2 for cursor is 0111 * below the view. 0112 */ 0113 int displayViewLine(const KTextEditor::Cursor virtualCursor, bool limitToVisible = false); 0114 0115 int viewCacheLineCount() const; 0116 KTextEditor::Cursor viewCacheStart() const; 0117 KTextEditor::Cursor viewCacheEnd() const; 0118 void updateViewCache(const KTextEditor::Cursor startPos, int newViewLineCount = -1, int viewLinesScrolled = 0); 0119 0120 void relayoutLines(int startRealLine, int endRealLine); 0121 0122 // find the index of the last view line for a specific line 0123 int lastViewLine(int realLine); 0124 // find the view line of cursor c (0 = same line, 1 = down one, etc.) 0125 int viewLine(const KTextEditor::Cursor realCursor); 0126 int viewLineCount(int realLine); 0127 0128 void viewCacheDebugOutput() const; 0129 // END 0130 0131 private: 0132 void wrapLine(KTextEditor::Document *, const KTextEditor::Cursor position); 0133 void unwrapLine(KTextEditor::Document *, int line); 0134 void insertText(KTextEditor::Document *, const KTextEditor::Cursor position, const QString &text); 0135 void removeText(KTextEditor::Document *, KTextEditor::Range range, const QString &); 0136 0137 private: 0138 KateRenderer *m_renderer; 0139 0140 /** 0141 * The master cache of all line layouts. 0142 * 0143 * Layouts which are not within the current view cache and whose 0144 * refcount == 1 are only known to the cache and can be safely deleted. 0145 */ 0146 KateLineLayoutMap m_lineLayouts; 0147 0148 // Convenience vector for quick direct access to the specific text layout 0149 KTextEditor::Cursor m_startPos = KTextEditor::Cursor::invalid(); 0150 0151 std::vector<KateTextLayout> m_textLayouts; 0152 0153 int m_viewWidth = 0; 0154 bool m_wrap = false; 0155 bool m_acceptDirtyLayouts = false; 0156 }; 0157 0158 #endif