File indexing completed on 2024-04-21 11:36:22

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