KTextEditor

katerenderer.h
1/*
2 This file is part of the KDE libraries
3 SPDX-FileCopyrightText: 2007 Mirko Stocker <me@misto.ch>
4 SPDX-FileCopyrightText: 2003-2005 Hamish Rodda <rodda@kde.org>
5 SPDX-FileCopyrightText: 2001 Christoph Cullmann <cullmann@kde.org>
6 SPDX-FileCopyrightText: 2001 Joseph Wenninger <jowenn@kde.org>
7 SPDX-FileCopyrightText: 1999 Jochen Wilhelmy <digisnap@cs.tu-berlin.de>
8
9 SPDX-License-Identifier: LGPL-2.0-only
10*/
11
12#ifndef KATE_RENDERER_H
13#define KATE_RENDERER_H
14
15#include "kateconfig.h"
16#include "ktexteditor/range.h"
17
18#include <QFlags>
19#include <QFont>
20#include <QFontMetricsF>
21#include <QTextLine>
22
23namespace KTextEditor
24{
25class DocumentPrivate;
26class ViewPrivate;
27class Attribute;
28}
29class KateRendererConfig;
30namespace Kate
31{
32class TextFolding;
33class TextLine;
34}
35
36class KateTextLayout;
37class KateLineLayout;
39
40namespace KTextEditor
41{
42enum class caretStyles {
43 Line,
44 Block,
45 Underline,
46 Half,
47};
48}
49
50/**
51 * Handles all of the work of rendering the text
52 * (used for the views and printing)
53 *
54 **/
56{
57public:
58 /**
59 * Style of Caret
60 *
61 * The caret is displayed as a vertical bar (Line), a filled box
62 * (Block), a horizontal bar (Underline), or a half-height filled
63 * box (Half). The default is Line.
64 *
65 * Line Block Underline Half
66 *
67 * ## _ ######### _ _
68 * ## __| | #####| |# __| | __| |
69 * ## / _' | ##/ _' |# / _' | / _' |
70 * ##| (_| | #| (#| |# | (_| | #| (#| |#
71 * ## \__,_| ##\__,_|# \__,_| ##\__,_|#
72 * ## ######### ######### #########
73 */
74
75 /**
76 * Constructor
77 * @param doc document to render
78 * @param folding folding information
79 * @param view view which is output (0 for example for rendering to print)
80 */
81 explicit KateRenderer(KTextEditor::DocumentPrivate *doc, Kate::TextFolding &folding, KTextEditor::ViewPrivate *view = nullptr);
82
83 KateRenderer(const KateRenderer &) = delete;
84 KateRenderer &operator=(const KateRenderer &) = delete;
85
86 /**
87 * Returns the document to which this renderer is bound
88 */
89 KTextEditor::DocumentPrivate *doc() const
90 {
91 return m_doc;
92 }
93
94 /**
95 * Returns the folding info to which this renderer is bound
96 * @return folding info
97 */
99 {
100 return m_folding;
101 }
102
103 /**
104 * Returns the view to which this renderer is bound
105 */
106 KTextEditor::ViewPrivate *view() const
107 {
108 return m_view;
109 }
110
111 /**
112 * update the highlighting attributes
113 * (for example after an hl change or after hl config changed)
114 */
115 void updateAttributes();
116
117 /**
118 * Determine whether the caret (text cursor) will be drawn.
119 * @return should it be drawn?
120 */
121 inline bool drawCaret() const
122 {
123 return m_drawCaret;
124 }
125
126 /**
127 * Set whether the caret (text cursor) will be drawn.
128 * @param drawCaret should caret be drawn?
129 */
130 void setDrawCaret(bool drawCaret);
131
132 /**
133 * The style of the caret (text cursor) to be painted.
134 * @return caretStyle
135 */
136 inline KTextEditor::caretStyles caretStyle() const
137 {
138 return m_caretStyle;
139 }
140
141 /**
142 * Set the style of caret to be painted.
143 * @param style style to set
144 */
145 void setCaretStyle(KTextEditor::caretStyles style);
146
147 /**
148 * Set a \a brush with which to override drawing of the caret. Set to QColor() to clear.
149 */
150 void setCaretOverrideColor(const QColor &color);
151
152 /**
153 * @returns whether tabs should be shown (ie. a small mark
154 * drawn to identify a tab)
155 * @return tabs should be shown
156 */
157 inline bool showTabs() const
158 {
159 return m_showTabs;
160 }
161
162 /**
163 * Set whether a mark should be painted to help identifying tabs.
164 * @param showTabs show the tabs?
165 */
166 void setShowTabs(bool showTabs);
167
168 /**
169 * Set which spaces should be rendered
170 */
171 void setShowSpaces(KateDocumentConfig::WhitespaceRendering showSpaces);
172
173 /**
174 * @returns whether which spaces should be rendered
175 */
176 inline KateDocumentConfig::WhitespaceRendering showSpaces() const
177 {
178 return m_showSpaces;
179 }
180
181 /**
182 * Update marker size shown.
183 */
184 void updateMarkerSize();
185
186 /**
187 * @returns whether non-printable spaces should be shown
188 */
189 inline bool showNonPrintableSpaces() const
190 {
191 return m_showNonPrintableSpaces;
192 }
193
194 /**
195 * Set whether box should be drawn around non-printable spaces
196 */
198
199 /**
200 * Sets the width of the tab. Helps performance.
201 * @param tabWidth new tab width
202 */
203 void setTabWidth(int tabWidth);
204
205 /**
206 * @returns whether indent lines should be shown
207 * @return indent lines should be shown
208 */
209 bool showIndentLines() const;
210
211 /**
212 * Set whether a guide should be painted to help identifying indent lines.
213 * @param showLines show the indent lines?
214 */
215 void setShowIndentLines(bool showLines);
216
217 /**
218 * Sets the width of the tab. Helps performance.
219 * @param indentWidth new indent width
220 */
221 void setIndentWidth(int indentWidth);
222
223 /**
224 * Show the view's selection?
225 * @return show sels?
226 */
227 inline bool showSelections() const
228 {
229 return m_showSelections;
230 }
231
232 /**
233 * Set whether the view's selections should be shown.
234 * The default is true.
235 * @param showSelections show the selections?
236 */
238
239 /**
240 * Change to a different font (soon to be font set?)
241 */
242 void increaseFontSizes(qreal step = 1.0) const;
243 void decreaseFontSizes(qreal step = 1.0) const;
244 void resetFontSizes() const;
245
246 /**
247 * Access currently used font.
248 * @return current font
249 */
250 const QFont &currentFont() const
251 {
252 return m_font;
253 }
254
255 /**
256 * Access currently used font metrics.
257 * @return current font metrics
258 */
260 {
261 return m_fontMetrics;
262 }
263
264 /**
265 * @return whether the renderer is configured to paint in a
266 * printer-friendly fashion.
267 */
268 bool isPrinterFriendly() const;
269
270 /**
271 * Configure this renderer to paint in a printer-friendly fashion.
272 *
273 * Sets the other options appropriately if true.
274 */
275 void setPrinterFriendly(bool printerFriendly);
276
277 /**
278 * Text width & height calculation functions...
279 */
280 void layoutLine(KateLineLayout *line, int maxwidth = -1, bool cacheLayout = false) const;
281
282 /**
283 * This is a smaller QString::isRightToLeft(). It's also marked as internal to kate
284 * instead of internal to Qt, so we can modify. This method searches for the first
285 * strong character in the paragraph and then returns its direction. In case of a
286 * line without any strong characters, the direction is forced to be LTR.
287 *
288 * Back in KDE 4.1 this method counted chars, which lead to unwanted side effects.
289 * (see https://bugs.kde.org/show_bug.cgi?id=178594). As this function is internal
290 * the way it work will probably change between releases. Be warned!
291 */
292 static bool isLineRightToLeft(QStringView str);
293
294 /**
295 * The ultimate decoration creation function.
296 *
297 * \param selectionsOnly return decorations for selections and/or dynamic highlighting.
298 */
299 QList<QTextLayout::FormatRange> decorationsForLine(const Kate::TextLine &textLine, int line, bool selectionsOnly = false) const;
300
301 // Width calculators
302 qreal spaceWidth() const;
303
304 /**
305 * Returns the x position of cursor \p col on the line \p range.
306 */
307 int cursorToX(const KateTextLayout &range, int col, bool returnPastLine = false) const;
308 /// \overload
309 int cursorToX(const KateTextLayout &range, const KTextEditor::Cursor pos, bool returnPastLine = false) const;
310
311 /**
312 * Returns the real cursor which is occupied by the specified x value, or that closest to it.
313 * If \p returnPastLine is true, the column will be extrapolated out with the assumption
314 * that the extra characters are spaces.
315 */
316 KTextEditor::Cursor xToCursor(const KateTextLayout &range, int x, bool returnPastLine = false) const;
317
318 // Font height
319 uint fontHeight() const;
320
321 // Line height
322 int lineHeight() const;
323
324 // Document height
325 uint documentHeight() const;
326
327 // Selection boundaries
328 bool getSelectionBounds(int line, int lineLength, int &start, int &end) const;
329
330 /**
331 * Flags to customize the paintTextLine function behavior
332 */
334 /**
335 * Skip drawing the dashed underline at the start of a folded block of text?
336 */
338 /**
339 * Skip drawing the line selection
340 * This is useful when we are drawing the draggable pixmap for drag event
341 */
343 };
344 Q_DECLARE_FLAGS(PaintTextLineFlags, PaintTextLineFlag)
345
346 /**
347 * This is the ultimate function to perform painting of a text line.
348 *
349 * The text line is painted from the upper limit of (0,0). To move that,
350 * apply a transform to your painter.
351 *
352 * @param paint painter to use
353 * @param range layout to use in painting this line
354 * @param textClipRect clip rect for text to not paint lines outside the visible area.
355 * @param xStart starting width in pixels.
356 * @param xEnd ending width in pixels.
357 * @param cursor position of the caret, if placed on the current line.
358 * @param flags flags for customizing the drawing of the line
359 */
360 void paintTextLine(QPainter &paint,
361 KateLineLayout *range,
362 int xStart,
363 int xEnd,
364 const QRectF &textClipRect = QRectF(),
365 const KTextEditor::Cursor *cursor = nullptr,
366 PaintTextLineFlags flags = PaintTextLineFlags());
367
368 /**
369 * Paint the background of a line
370 *
371 * Split off from the main @ref paintTextLine method to make it smaller. As it's being
372 * called only once per line it shouldn't noticably affect performance and it
373 * helps readability a LOT.
374 *
375 * @param paint painter to use
376 * @param layout layout to use in painting this line
377 * @param currentViewLine if one of the view lines is the current line, set
378 * this to the index; otherwise -1.
379 * @param xStart starting width in pixels.
380 * @param xEnd ending width in pixels.
381 */
382 void paintTextLineBackground(QPainter &paint, KateLineLayout *layout, int currentViewLine, int xStart, int xEnd);
383
384 void paintTextBackground(QPainter &paint, KateLineLayout *layout, const QList<QTextLayout::FormatRange> &selRanges, const QBrush &br, int xStart) const;
385
386 /**
387 * This takes an in index, and returns all the attributes for it.
388 * For example, if you have a ktextline, and want the KTextEditor::Attribute
389 * for a given position, do:
390 *
391 * attribute(myktextline->attribute(position));
392 */
393 const AttributePtr &attribute(uint pos) const;
394 AttributePtr specificAttribute(int context) const;
395
396 /**
397 * Paints a range of text into @a d. This function is mainly used to paint the pixmap
398 * when dragging text.
399 *
400 * Please note that this will not paint the selection background but only the text.
401 *
402 * @param d the paint device
403 * @param startLine start line
404 * @param xStart start pos on @a startLine in pixels
405 * @param endLine end line
406 * @param xEnd end pos on @a endLine in pixels
407 * @param scale the amount of scaling to apply. Default is 1.0, negative values are not supported
408 */
409 void paintSelection(QPaintDevice *d, int startLine, int xStart, int endLine, int xEnd, qreal scale = 1.0);
410
411private:
412 /**
413 * Paint a trailing space on position (x, y).
414 */
415 void paintSpaces(QPainter &paint, const QPointF *points, const int count) const;
416 /**
417 * Paint a tab stop marker on position (x, y).
418 */
419 void paintTabstop(QPainter &paint, qreal x, qreal y) const;
420
421 /**
422 * Paint a non-breaking space marker on position (x, y).
423 */
424 void paintNonBreakSpace(QPainter &paint, qreal x, qreal y) const;
425
426 /**
427 * Paint non printable spaces bounding box
428 */
429 void paintNonPrintableSpaces(QPainter &paint, qreal x, qreal y, const QChar &chr);
430
431 /** Paint a SciTE-like indent marker. */
432 void paintIndentMarker(QPainter &paint, uint x, int line);
433
434 static void assignSelectionBrushesFromAttribute(QTextLayout::FormatRange &target, const KTextEditor::Attribute &attribute);
435
436 void paintCaret(KTextEditor::Cursor cursor, KateLineLayout *range, QPainter &paint, int xStart, int xEnd);
437
438 // update font height
439 void updateFontHeight();
440
441 bool hasCustomLineHeight() const;
442
443 KTextEditor::DocumentPrivate *const m_doc;
444 Kate::TextFolding &m_folding;
445 KTextEditor::ViewPrivate *const m_view;
446
447 // cache of config values
448 int m_tabWidth;
449 int m_indentWidth;
450 int m_fontHeight;
451 float m_fontAscent;
452
453 // if we are at bracket, this will have the X for the opener
454 int m_currentBracketX = -1;
455
456 // The bracket range, if we are at a bracket
457 KTextEditor::Range m_currentBracketRange = KTextEditor::Range::invalid();
458
459 // some internal flags
460 KTextEditor::caretStyles m_caretStyle;
461 bool m_drawCaret;
462 bool m_showSelections;
463 bool m_showTabs;
464 KateDocumentConfig::WhitespaceRendering m_showSpaces = KateDocumentConfig::None;
465 float m_markerSize;
466 bool m_showNonPrintableSpaces;
467 bool m_printerFriendly;
468 QColor m_caretOverrideColor;
469
470 QList<AttributePtr> m_attributes;
471
472 /**
473 * Configuration
474 */
475public:
476 void updateConfig();
477
478 inline KateRendererConfig *config() const
479 {
480 return m_config.get();
481 }
482
483private:
484 std::unique_ptr<KateRendererConfig> const m_config;
485
486 /**
487 * cached font, was perhaps adjusted for current DPIs
488 */
489 QFont m_font;
490
491 /**
492 * cached font metrics
493 */
494 QFontMetricsF m_fontMetrics;
495};
496
497#endif
A class which provides customized text decorations.
Definition attribute.h:51
The Cursor represents a position in a Document.
Definition cursor.h:75
An object representing a section of text, from one Cursor to another.
static constexpr Range invalid() noexcept
Returns an invalid range.
Handles all of the work of rendering the text (used for the views and printing)
void increaseFontSizes(qreal step=1.0) const
Change to a different font (soon to be font set?)
Kate::TextFolding & folding() const
Returns the folding info to which this renderer is bound.
void paintSelection(QPaintDevice *d, int startLine, int xStart, int endLine, int xEnd, qreal scale=1.0)
Paints a range of text into d.
void setShowTabs(bool showTabs)
Set whether a mark should be painted to help identifying tabs.
const QFont & currentFont() const
Access currently used font.
bool showNonPrintableSpaces() const
KateRenderer(KTextEditor::DocumentPrivate *doc, Kate::TextFolding &folding, KTextEditor::ViewPrivate *view=nullptr)
Style of Caret.
void setIndentWidth(int indentWidth)
Sets the width of the tab.
void setShowSelections(bool showSelections)
Set whether the view's selections should be shown.
const AttributePtr & attribute(uint pos) const
This takes an in index, and returns all the attributes for it.
KTextEditor::caretStyles caretStyle() const
The style of the caret (text cursor) to be painted.
void setDrawCaret(bool drawCaret)
Set whether the caret (text cursor) will be drawn.
static bool isLineRightToLeft(QStringView str)
This is a smaller QString::isRightToLeft().
bool isPrinterFriendly() const
int cursorToX(const KateTextLayout &range, int col, bool returnPastLine=false) const
Returns the x position of cursor col on the line range.
KTextEditor::Cursor xToCursor(const KateTextLayout &range, int x, bool returnPastLine=false) const
Returns the real cursor which is occupied by the specified x value, or that closest to it.
void setPrinterFriendly(bool printerFriendly)
Configure this renderer to paint in a printer-friendly fashion.
bool showIndentLines() const
KTextEditor::ViewPrivate * view() const
Returns the view to which this renderer is bound.
void setShowSpaces(KateDocumentConfig::WhitespaceRendering showSpaces)
Set which spaces should be rendered.
bool showTabs() const
QList< QTextLayout::FormatRange > decorationsForLine(const Kate::TextLine &textLine, int line, bool selectionsOnly=false) const
The ultimate decoration creation function.
KateDocumentConfig::WhitespaceRendering showSpaces() const
bool drawCaret() const
Determine whether the caret (text cursor) will be drawn.
PaintTextLineFlag
Flags to customize the paintTextLine function behavior.
@ SkipDrawLineSelection
Skip drawing the line selection This is useful when we are drawing the draggable pixmap for drag even...
@ SkipDrawFirstInvisibleLineUnderlined
Skip drawing the dashed underline at the start of a folded block of text?
void setShowNonPrintableSpaces(const bool showNonPrintableSpaces)
Set whether box should be drawn around non-printable spaces.
bool showSelections() const
Show the view's selection?
const QFontMetricsF & currentFontMetrics() const
Access currently used font metrics.
void setTabWidth(int tabWidth)
Sets the width of the tab.
void setCaretOverrideColor(const QColor &color)
Set a brush with which to override drawing of the caret.
void updateConfig()
Configuration.
void setCaretStyle(KTextEditor::caretStyles style)
Set the style of caret to be painted.
KTextEditor::DocumentPrivate * doc() const
Returns the document to which this renderer is bound.
void setShowIndentLines(bool showLines)
Set whether a guide should be painted to help identifying indent lines.
void updateAttributes()
update the highlighting attributes (for example after an hl change or after hl config changed)
void layoutLine(KateLineLayout *line, int maxwidth=-1, bool cacheLayout=false) const
Text width & height calculation functions...
void paintTextLineBackground(QPainter &paint, KateLineLayout *layout, int currentViewLine, int xStart, int xEnd)
Paint the background of a line.
void updateMarkerSize()
Update marker size shown.
void paintTextLine(QPainter &paint, KateLineLayout *range, int xStart, int xEnd, const QRectF &textClipRect=QRectF(), const KTextEditor::Cursor *cursor=nullptr, PaintTextLineFlags flags=PaintTextLineFlags())
This is the ultimate function to perform painting of a text line.
This class represents one visible line of text; with dynamic wrapping, many KateTextLayouts can be ne...
Class representing the folding information for a TextBuffer.
Class representing a single text line.
Q_SCRIPTABLE Q_NOREPLY void start()
The KTextEditor namespace contains all the public API that is required to use the KTextEditor compone...
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:15:44 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.