File indexing completed on 2024-04-14 03:55:15

0001 /*
0002     SPDX-FileCopyrightText: 2002-2005 Hamish Rodda <rodda@kde.org>
0003     SPDX-FileCopyrightText: 2003 Anakim Border <aborder@sources.sourceforge.net>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #include "katetextlayout.h"
0009 
0010 #include "katepartdebug.h"
0011 
0012 KateTextLayout::KateTextLayout(KateLineLayout *line, int viewLine)
0013     : m_lineLayout(line)
0014     , m_viewLine(viewLine)
0015     , m_startX(m_viewLine ? -1 : 0)
0016 {
0017     if (isValid()) {
0018         m_textLayout = m_lineLayout->layout()->lineAt(m_viewLine);
0019     }
0020 }
0021 
0022 bool KateTextLayout::isDirty() const
0023 {
0024     if (!isValid()) {
0025         return m_invalidDirty;
0026     }
0027 
0028     return m_lineLayout->isDirty(viewLine());
0029 }
0030 
0031 bool KateTextLayout::setDirty(bool dirty)
0032 {
0033     if (!isValid()) {
0034         return (m_invalidDirty = dirty);
0035     }
0036 
0037     return m_lineLayout->setDirty(viewLine(), dirty);
0038 }
0039 
0040 bool KateTextLayout::includesCursor(const KTextEditor::Cursor realCursor) const
0041 {
0042     return realCursor.line() == line() && realCursor.column() >= startCol() && (!wrap() || realCursor.column() < endCol());
0043 }
0044 
0045 int KateTextLayout::xOffset() const
0046 {
0047     if (!isValid()) {
0048         return 0;
0049     }
0050 
0051     return startX() ? m_lineLayout->shiftX : 0;
0052 }
0053 
0054 void KateTextLayout::debugOutput() const
0055 {
0056     qCDebug(LOG_KTE) << "KateTextLayout: " << m_lineLayout << " valid " << isValid() << " line " << m_lineLayout->line() << " (" << line() << ") cols ["
0057                      << startCol() << " -> " << endCol() << "] x [" << startX() << " -> " << endX() << " off " << m_lineLayout->shiftX << "] wrap " << wrap();
0058 }
0059 
0060 bool operator>(const KateTextLayout &r, const KTextEditor::Cursor c)
0061 {
0062     return r.line() > c.line() || r.endCol() > c.column();
0063 }
0064 
0065 bool operator>=(const KateTextLayout &r, const KTextEditor::Cursor c)
0066 {
0067     return r.line() > c.line() || r.endCol() >= c.column();
0068 }
0069 
0070 bool operator<(const KateTextLayout &r, const KTextEditor::Cursor c)
0071 {
0072     return r.line() < c.line() || r.startCol() < c.column();
0073 }
0074 
0075 bool operator<=(const KateTextLayout &r, const KTextEditor::Cursor c)
0076 {
0077     return r.line() < c.line() || r.startCol() <= c.column();
0078 }
0079 
0080 bool KateTextLayout::isValid() const
0081 {
0082     return m_lineLayout && m_lineLayout->isValid() && m_viewLine >= 0 && m_viewLine < m_lineLayout->viewLineCount();
0083 }
0084 
0085 int KateTextLayout::line() const
0086 {
0087     if (!isValid()) {
0088         return -1;
0089     }
0090 
0091     return m_lineLayout->line();
0092 }
0093 
0094 int KateTextLayout::virtualLine() const
0095 {
0096     if (!isValid()) {
0097         return -1;
0098     }
0099 
0100     return m_lineLayout->virtualLine();
0101 }
0102 
0103 int KateTextLayout::viewLine() const
0104 {
0105     if (!isValid()) {
0106         return 0;
0107     }
0108 
0109     return m_viewLine;
0110 }
0111 
0112 const QTextLine &KateTextLayout::lineLayout() const
0113 {
0114     return m_textLayout;
0115 }
0116 
0117 KateLineLayout *KateTextLayout::kateLineLayout() const
0118 {
0119     return m_lineLayout;
0120 }
0121 
0122 int KateTextLayout::startCol() const
0123 {
0124     if (!isValid()) {
0125         return 0;
0126     }
0127 
0128     return lineLayout().textStart();
0129 }
0130 
0131 KTextEditor::Cursor KateTextLayout::start() const
0132 {
0133     return KTextEditor::Cursor(line(), startCol());
0134 }
0135 
0136 int KateTextLayout::endCol(bool indicateEOL) const
0137 {
0138     if (!isValid()) {
0139         return 0;
0140     }
0141 
0142     if (indicateEOL) {
0143         if (viewLine() == kateLineLayout()->viewLineCount() - 1) {
0144             return -1;
0145         }
0146     }
0147 
0148     return startCol() + m_textLayout.textLength();
0149 }
0150 
0151 KTextEditor::Cursor KateTextLayout::end(bool indicateEOL) const
0152 {
0153     return KTextEditor::Cursor(line(), endCol(indicateEOL));
0154 }
0155 
0156 int KateTextLayout::length() const
0157 {
0158     if (!isValid()) {
0159         return 0;
0160     }
0161 
0162     return m_textLayout.textLength();
0163 }
0164 
0165 bool KateTextLayout::isEmpty() const
0166 {
0167     if (!isValid()) {
0168         return true;
0169     }
0170 
0171     return startCol() == 0 && endCol() == 0;
0172 }
0173 
0174 bool KateTextLayout::wrap() const
0175 {
0176     if (!isValid()) {
0177         return false;
0178     }
0179 
0180     return viewLine() < m_lineLayout->viewLineCount() - 1;
0181 }
0182 
0183 int KateTextLayout::startX() const
0184 {
0185     if (!isValid()) {
0186         return 0;
0187     }
0188 
0189     if (m_startX == -1) {
0190         // viewLine is already > 0, from the constructor
0191         for (int i = 0; i < viewLine(); ++i) {
0192             m_startX += (int)m_lineLayout->layout()->lineAt(i).naturalTextWidth();
0193         }
0194     }
0195 
0196     return m_startX;
0197 }
0198 
0199 int KateTextLayout::endX() const
0200 {
0201     if (!isValid()) {
0202         return 0;
0203     }
0204 
0205     return startX() + (int)m_textLayout.naturalTextWidth();
0206 }
0207 
0208 int KateTextLayout::width() const
0209 {
0210     if (!isValid()) {
0211         return 0;
0212     }
0213 
0214     return (int)m_textLayout.naturalTextWidth();
0215 }
0216 
0217 KateTextLayout KateTextLayout::invalid()
0218 {
0219     return KateTextLayout();
0220 }
0221 
0222 bool KateTextLayout::isRightToLeft() const
0223 {
0224     if (m_lineLayout) {
0225         return m_lineLayout->isRightToLeft();
0226     }
0227 
0228     return false;
0229 }