• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • kate
 

kate

  • kate
  • part
katerenderer.cpp
1/* This file is part of the KDE libraries
2 Copyright (C) 2003 Hamish Rodda <rodda@kde.org>
3 Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org>
4 Copyright (C) 2001 Joseph Wenninger <jowenn@kde.org>
5 Copyright (C) 1999 Jochen Wilhelmy <digisnap@cs.tu-berlin.de>
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Library General Public
9 License version 2 as published by the Free Software Foundation.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
15
16 You should have received a copy of the GNU Library General Public License
17 along with this library; see the file COPYING.LIB. If not, write to
18 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA.
20*/
21
22#include "katerenderer.h"
23
24#include "katelinerange.h"
25#include "katedocument.h"
26#include "katearbitraryhighlight.h"
27#include "kateconfig.h"
28#include "katehighlight.h"
29#include "katefactory.h"
30#include "kateview.h"
31
32#include <kdebug.h>
33
34#include <tqpainter.h>
35#include <tqpopupmenu.h>
36
37KateRenderer::KateRenderer(KateDocument* doc, KateView *view)
38 : m_doc(doc), m_view (view), m_caretStyle(KateRenderer::Insert)
39 , m_drawCaret(true)
40 , m_showSelections(true)
41 , m_showTabs(true)
42 , m_printerFriendly(false)
43{
44 KateFactory::self()->registerRenderer ( this );
45 m_config = new KateRendererConfig (this);
46
47 m_tabWidth = m_doc->config()->tabWidth();
48 m_indentWidth = m_tabWidth;
49 if (m_doc->config()->configFlags() & KateDocumentConfig::cfSpaceIndent)
50 {
51 m_indentWidth = m_doc->config()->indentationWidth();
52 }
53
54 updateAttributes ();
55}
56
57KateRenderer::~KateRenderer()
58{
59 delete m_config;
60 KateFactory::self()->deregisterRenderer ( this );
61}
62
63void KateRenderer::updateAttributes ()
64{
65 m_schema = config()->schema ();
66 m_attributes = m_doc->highlight()->attributes (m_schema);
67}
68
69KateAttribute* KateRenderer::attribute(uint pos)
70{
71 if (pos < m_attributes->size())
72 return &m_attributes->at(pos);
73
74 return &m_attributes->at(0);
75}
76
77void KateRenderer::setDrawCaret(bool drawCaret)
78{
79 m_drawCaret = drawCaret;
80}
81
82void KateRenderer::setCaretStyle(KateRenderer::caretStyles style)
83{
84 m_caretStyle = style;
85}
86
87void KateRenderer::setShowTabs(bool showTabs)
88{
89 m_showTabs = showTabs;
90}
91
92void KateRenderer::setTabWidth(int tabWidth)
93{
94 m_tabWidth = tabWidth;
95}
96
97bool KateRenderer::showIndentLines() const
98{
99 return m_config->showIndentationLines();
100}
101
102void KateRenderer::setShowIndentLines(bool showIndentLines)
103{
104 m_config->setShowIndentationLines(showIndentLines);
105}
106
107void KateRenderer::setIndentWidth(int indentWidth)
108{
109 m_indentWidth = m_tabWidth;
110 if (m_doc->config()->configFlags() & KateDocumentConfig::cfSpaceIndent)
111 {
112 m_indentWidth = indentWidth;
113 }
114}
115
116void KateRenderer::setShowSelections(bool showSelections)
117{
118 m_showSelections = showSelections;
119}
120
121void KateRenderer::increaseFontSizes()
122{
123 TQFont f ( *config()->font () );
124 f.setPointSize (f.pointSize ()+1);
125
126 config()->setFont (f);
127}
128
129void KateRenderer::decreaseFontSizes()
130{
131 TQFont f ( *config()->font () );
132
133 if ((f.pointSize ()-1) > 0)
134 f.setPointSize (f.pointSize ()-1);
135
136 config()->setFont (f);
137}
138
139bool KateRenderer::isPrinterFriendly() const
140{
141 return m_printerFriendly;
142}
143
144void KateRenderer::setPrinterFriendly(bool printerFriendly)
145{
146 m_printerFriendly = printerFriendly;
147 setShowTabs(false);
148 setShowSelections(false);
149 setDrawCaret(false);
150}
151
152bool KateRenderer::paintTextLineBackground(TQPainter& paint, int line, bool isCurrentLine, int xStart, int xEnd)
153{
154 if (isPrinterFriendly())
155 return false;
156
157 // font data
158 KateFontStruct *fs = config()->fontStruct();
159
160 // Normal background color
161 TQColor backgroundColor( config()->backgroundColor() );
162
163 bool selectionPainted = false;
164 if (showSelections() && m_view->lineSelected(line))
165 {
166 backgroundColor = config()->selectionColor();
167 selectionPainted = true;
168 }
169 else
170 {
171 // paint the current line background if we're on the current line
172 if (isCurrentLine)
173 backgroundColor = config()->highlightedLineColor();
174
175 // Check for mark background
176 int markRed = 0, markGreen = 0, markBlue = 0, markCount = 0;
177
178 // Retrieve marks for this line
179 uint mrk = m_doc->mark( line );
180 if (mrk)
181 {
182 for (uint bit = 0; bit < 32; bit++)
183 {
184 KTextEditor::MarkInterface::MarkTypes markType = (KTextEditor::MarkInterface::MarkTypes)(1<<bit);
185 if (mrk & markType)
186 {
187 TQColor markColor = config()->lineMarkerColor(markType);
188
189 if (markColor.isValid()) {
190 markCount++;
191 markRed += markColor.red();
192 markGreen += markColor.green();
193 markBlue += markColor.blue();
194 }
195 }
196 } // for
197 } // Marks
198
199 if (markCount) {
200 markRed /= markCount;
201 markGreen /= markCount;
202 markBlue /= markCount;
203 backgroundColor.setRgb(
204 int((backgroundColor.red() * 0.9) + (markRed * 0.1)),
205 int((backgroundColor.green() * 0.9) + (markGreen * 0.1)),
206 int((backgroundColor.blue() * 0.9) + (markBlue * 0.1))
207 );
208 }
209 } // background preprocessing
210
211 // Draw line background
212 paint.fillRect(0, 0, xEnd - xStart, fs->fontHeight, backgroundColor);
213
214 return selectionPainted;
215}
216
217void KateRenderer::paintWhitespaceMarker(TQPainter &paint, uint x, uint y)
218{
219 TQPen penBackup( paint.pen() );
220 paint.setPen( config()->tabMarkerColor() );
221 paint.drawPoint(x, y);
222 paint.drawPoint(x + 1, y);
223 paint.drawPoint(x, y - 1);
224 paint.setPen( penBackup );
225}
226
227
228void KateRenderer::paintIndentMarker(TQPainter &paint, uint x, uint row)
229{
230 TQPen penBackup( paint.pen() );
231 paint.setPen( config()->tabMarkerColor() );
232
233 const int top = paint.window().top();
234 const int bottom = paint.window().bottom();
235 const int h = bottom - top + 1;
236
237 // Dot padding.
238 int pad = 0;
239 if(row & 1 && h & 1) pad = 1;
240
241 for(int i = top; i <= bottom; i++)
242 {
243 if((i + pad) & 1)
244 {
245 paint.drawPoint(x + 2, i);
246 }
247 }
248
249 paint.setPen( penBackup );
250}
251
252
253void KateRenderer::paintTextLine(TQPainter& paint, const KateLineRange* range, int xStart, int xEnd, const KateTextCursor* cursor, const KateBracketRange* bracketmark)
254{
255 int line = range->line;
256
257 // textline
258 KateTextLine::Ptr textLine = m_doc->kateTextLine(line);
259 if (!textLine)
260 return;
261
262 bool showCursor = drawCaret() && cursor && range->includesCursor(*cursor);
263
264 KateSuperRangeList& superRanges = m_doc->arbitraryHL()->rangesIncluding(range->line, 0);
265
266 int minIndent = 0;
267
268 // A bit too verbose for my tastes
269 // Re-write a bracketmark class? put into its own function? add more helper constructors to the range stuff?
270 // Also, need a light-weight arbitraryhighlightrange class for static stuff
271 KateArbitraryHighlightRange* bracketStartRange (0L);
272 KateArbitraryHighlightRange* bracketEndRange (0L);
273 if (bracketmark && bracketmark->isValid()) {
274 if (range->includesCursor(bracketmark->start())) {
275 KateTextCursor startend = bracketmark->start();
276 startend.setCol(startend.col()+1);
277 bracketStartRange = new KateArbitraryHighlightRange(m_doc, bracketmark->start(), startend);
278 bracketStartRange->setBGColor(config()->highlightedBracketColor());
279 bracketStartRange->setBold(true);
280 superRanges.append(bracketStartRange);
281 }
282
283 if (range->includesCursor(bracketmark->end())) {
284 KateTextCursor endend = bracketmark->end();
285 endend.setCol(endend.col()+1);
286 bracketEndRange = new KateArbitraryHighlightRange(m_doc, bracketmark->end(), endend);
287 bracketEndRange->setBGColor(config()->highlightedBracketColor());
288 bracketEndRange->setBold(true);
289 superRanges.append(bracketEndRange);
290 }
291
292 Q_ASSERT(bracketmark->start().line() <= bracketmark->end().line());
293 if (bracketmark->start().line() < line && bracketmark->end().line() >= line)
294 {
295 minIndent = bracketmark->getMinIndent();
296 }
297 }
298
299
300 // length, chars + raw attribs
301 uint len = textLine->length();
302 uint oldLen = len;
303
304 // should the cursor be painted (if it is in the current xstart - xend range)
305 bool cursorVisible = false;
306 int cursorMaxWidth = 0;
307
308 // font data
309 KateFontStruct * fs = config()->fontStruct();
310
311 // Paint selection background as the whole line is selected
312 // selection startcol/endcol calc
313 bool hasSel = false;
314 uint startSel = 0;
315 uint endSel = 0;
316
317 // was the selection background already completely painted ?
318 bool selectionPainted = false;
319 bool isCurrentLine = (cursor && range->includesCursor(*cursor));
320 selectionPainted = paintTextLineBackground(paint, line, isCurrentLine, xStart, xEnd);
321 if (selectionPainted)
322 {
323 hasSel = true;
324 startSel = 0;
325 endSel = len + 1;
326 }
327
328 int startcol = range->startCol;
329 if (startcol > (int)len)
330 startcol = len;
331
332 if (startcol < 0)
333 startcol = 0;
334
335 int endcol = range->wrap ? range->endCol : -1;
336 if (endcol < 0)
337 len = len - startcol;
338 else
339 len = endcol - startcol;
340
341 // text attribs font/style data
342 KateAttribute* attr = m_doc->highlight()->attributes(m_schema)->data();
343
344 const TQColor *cursorColor = &attr[0].textColor();
345
346 // Start arbitrary highlighting
347 KateTextCursor currentPos(line, startcol);
348 superRanges.firstBoundary(&currentPos);
349
350 if (showSelections() && !selectionPainted)
351 hasSel = getSelectionBounds(line, oldLen, startSel, endSel);
352
353 // Draws the dashed underline at the start of a folded block of text.
354 if (range->startsInvisibleBlock) {
355 paint.setPen(TQPen(config()->wordWrapMarkerColor(), 1, TQt::DashLine));
356 paint.drawLine(0, fs->fontHeight - 1, xEnd - xStart, fs->fontHeight - 1);
357 }
358
359 // draw word-wrap-honor-indent filling
360 if (range->xOffset() && range->xOffset() > xStart)
361 {
362 paint.fillRect(0, 0, range->xOffset() - xStart, fs->fontHeight,
363 TQBrush(config()->wordWrapMarkerColor(), TQBrush::DiagCrossPattern));
364 }
365
366 // painting loop
367 uint xPos = range->xOffset();
368 int cursorXPos = 0;
369
370 // Optimisation to quickly draw an empty line of text
371 if (len < 1)
372 {
373 if (showCursor && (cursor->col() >= int(startcol)))
374 {
375 cursorVisible = true;
376 cursorXPos = xPos + cursor->col() * fs->myFontMetrics.width(TQChar(' '));
377 }
378 }
379 else
380 {
381 bool isIMSel = false;
382 bool isIMEdit = false;
383
384 bool isSel = false;
385
386 KateAttribute customHL;
387
388 const TQColor *curColor = 0;
389 const TQColor *oldColor = 0;
390
391 KateAttribute* oldAt = &attr[0];
392
393 uint oldXPos = xPos;
394 uint xPosAfter = xPos;
395
396 KateAttribute currentHL;
397
398 uint blockStartCol = startcol;
399 uint curCol = startcol;
400 uint nextCol = curCol + 1;
401
402 // text + attrib data from line
403 const uchar *textAttributes = textLine->attributes ();
404 bool noAttribs = !textAttributes;
405
406 // adjust to startcol ;)
407 textAttributes = textAttributes + startcol;
408
409 uint atLen = m_doc->highlight()->attributes(m_schema)->size();
410
411 // Determine if we have trailing whitespace and store the column
412 // if lastChar == -1, set to 0, if lastChar exists, increase by one
413 uint trailingWhitespaceColumn = textLine->lastChar() + 1;
414 const uint lastIndentColumn = textLine->firstChar();
415
416 // Could be precomputed.
417 const uint spaceWidth = fs->width (TQChar(' '), false, false, m_tabWidth);
418
419 // Get current x position.
420 int curPos = textLine->cursorX(curCol, m_tabWidth);
421
422 while (curCol - startcol < len)
423 {
424 // make sure curPos is updated correctly.
425 // ### if uncommented, causes an O(n^2) behaviour
426 //Q_ASSERT(curPos == textLine->cursorX(curCol, m_tabWidth));
427
428 TQChar curChar = textLine->string()[curCol];
429 // Decide if this character is a tab - we treat the spacing differently
430 // TODO: move tab width calculation elsewhere?
431 bool isTab = curChar == TQChar('\t');
432
433 // Determine current syntax highlighting attribute
434 // A bit legacy but doesn't need to change
435 KateAttribute* curAt = (noAttribs || ((*textAttributes) >= atLen)) ? &attr[0] : &attr[*textAttributes];
436
437 // X position calculation. Incorrect for fonts with non-zero leftBearing() and rightBearing() results.
438 // TODO: make internal charWidth() function, use TQFontMetrics::charWidth().
439 xPosAfter += curAt->width(*fs, curChar, m_tabWidth);
440
441 // Tab special treatment, move to charWidth().
442 if (isTab)
443 xPosAfter -= (xPosAfter % curAt->width(*fs, curChar, m_tabWidth));
444
445 // Only draw after the starting X value
446 // Haha, this was always wrong, due to the use of individual char width calculations...?? :(
447 if ((int)xPosAfter >= xStart)
448 {
449 // Determine if we're in a selection and should be drawing it
450 isSel = (showSelections() && hasSel && (curCol >= startSel) && (curCol < endSel));
451
452 // input method edit area
453 isIMEdit = m_view && m_view->isIMEdit( line, curCol );
454
455 // input method selection
456 isIMSel = m_view && m_view->isIMSelection( line, curCol );
457
458 // Determine current color, taking into account selection
459 curColor = isSel ? &(curAt->selectedTextColor()) : &(curAt->textColor());
460
461 // Incorporate in arbitrary highlighting
462 if (curAt != oldAt || curColor != oldColor || (superRanges.count() && superRanges.currentBoundary() && *(superRanges.currentBoundary()) == currentPos)) {
463 if (superRanges.count() && superRanges.currentBoundary() && *(superRanges.currentBoundary()) == currentPos)
464 customHL = KateArbitraryHighlightRange::merge(superRanges.rangesIncluding(currentPos));
465
466 KateAttribute hl = customHL;
467
468 hl += *curAt;
469
470 // use default highlighting color if we haven't defined one above.
471 if (!hl.itemSet(KateAttribute::TextColor))
472 hl.setTextColor(*curColor);
473
474 if (!isSel)
475 paint.setPen(hl.textColor());
476 else
477 paint.setPen(hl.selectedTextColor());
478
479 paint.setFont(hl.font(*currentFont()));
480
481 if (superRanges.currentBoundary() && *(superRanges.currentBoundary()) == currentPos)
482 superRanges.nextBoundary();
483
484 currentHL = hl;
485 }
486
487 // Determine whether we can delay painting to draw a block of similarly formatted
488 // characters or not
489 // Reasons for NOT delaying the drawing until the next character
490 // You have to detect the change one character in advance.
491 // TODO: KateAttribute::canBatchRender()
492 bool renderNow = false;
493 if ((isTab)
494 // formatting has changed OR
495 || (superRanges.count() && superRanges.currentBoundary() && *(superRanges.currentBoundary()) == KateTextCursor(line, nextCol))
496
497 // it is the end of the line OR
498 || (curCol - startcol >= len - 1)
499
500 // the rest of the line is trailing whitespace OR
501 || (curCol + 1 >= trailingWhitespaceColumn)
502
503 // indentation lines OR
504 || (showIndentLines() && curCol < lastIndentColumn)
505
506 // the x position is past the end OR
507 || ((int)xPos > xEnd)
508
509 // it is a different attribute OR
510 || (!noAttribs && curAt != &attr[*(textAttributes+1)])
511
512 // the selection boundary was crossed OR
513 || (isSel != (hasSel && (nextCol >= startSel) && (nextCol < endSel)))
514
515 // the next char is a tab (removed the "and this isn't" because that's dealt with above)
516 // i.e. we have to draw the current text so the tab can be rendered as above.
517 || (textLine->string()[nextCol] == TQChar('\t'))
518
519 // input method edit area
520 || ( m_view && (isIMEdit != m_view->isIMEdit( line, nextCol )) )
521
522 // input method selection
523 || ( m_view && (isIMSel != m_view->isIMSelection( line, nextCol )) )
524 )
525 {
526 renderNow = true;
527 }
528
529 if (renderNow)
530 {
531 if (!isPrinterFriendly())
532 {
533 bool paintBackground = true;
534 uint width = xPosAfter - oldXPos;
535 TQColor fillColor;
536
537 if (isIMSel && !isTab)
538 {
539 // input method selection
540 fillColor = m_view->colorGroup().color(TQColorGroup::Foreground);
541 }
542 else if (isIMEdit && !isTab)
543 {
544 // XIM support
545 // input method edit area
546 const TQColorGroup& cg = m_view->colorGroup();
547 int h1, s1, v1, h2, s2, v2;
548 TQColor(cg.color( TQColorGroup::Base )).hsv( &h1, &s1, &v1 );
549 TQColor(cg.color( TQColorGroup::Background )).hsv( &h2, &s2, &v2 );
550 fillColor.setHsv( h1, s1, ( v1 + v2 ) / 2 );
551 }
552 else if (!selectionPainted && (isSel || currentHL.itemSet(KateAttribute::BGColor)))
553 {
554 if (isSel)
555 {
556 fillColor = config()->selectionColor();
557
558 // If this is the last block of text, fill up to the end of the line if the
559 // selection stretches that far
560 if ((curCol >= len - 1) && m_view->lineEndSelected (line, endcol))
561 width = xEnd - oldXPos;
562 }
563 else
564 {
565 fillColor = currentHL.bgColor();
566 }
567 }
568 else
569 {
570 paintBackground = false;
571 }
572
573 if (paintBackground)
574 paint.fillRect(oldXPos - xStart, 0, width, fs->fontHeight, fillColor);
575
576 if (isIMSel && paintBackground && !isTab)
577 {
578 paint.save();
579 paint.setPen( m_view->colorGroup().color( TQColorGroup::BrightText ) );
580 }
581
582 // Draw indentation markers.
583 if (showIndentLines() && curCol < lastIndentColumn)
584 {
585 // Draw multiple guides when tab width greater than indent width.
586 const int charWidth = isTab ? m_tabWidth - curPos % m_tabWidth : 1;
587
588 // Do not draw indent guides on the first line.
589 int i = 0;
590 if (curPos == 0 || curPos % m_indentWidth > 0)
591 i = m_indentWidth - curPos % m_indentWidth;
592
593 for (; i < charWidth; i += m_indentWidth)
594 {
595 // In most cases this is done one or zero times.
596 paintIndentMarker(paint, xPos - xStart + i * spaceWidth, line);
597
598 // Draw highlighted line.
599 if (curPos+i == minIndent)
600 {
601 paintIndentMarker(paint, xPos - xStart + 1 + i * spaceWidth, line+1);
602 }
603 }
604 }
605 }
606
607 // or we will see no text ;)
608 int y = fs->fontAscent;
609
610 // make sure we redraw the right character groups on attrib/selection changes
611 // Special case... de-special case some of it
612 if (isTab || (curCol >= trailingWhitespaceColumn))
613 {
614 // Draw spaces too, because it might be eg. underlined
615 static TQString spaces;
616 if (int(spaces.length()) != m_tabWidth)
617 spaces.fill(' ', m_tabWidth);
618
619 paint.drawText(oldXPos-xStart, y, isTab ? spaces : TQString(" "));
620
621 if (showTabs())
622 {
623 // trailing spaces and tabs may also have to be different options.
624 // if( curCol >= lastIndentColumn )
625 paintWhitespaceMarker(paint, xPos - xStart, y);
626 }
627
628 // variable advancement
629 blockStartCol = nextCol;
630 oldXPos = xPosAfter;
631 }
632 else
633 {
634 // Here's where the money is...
635 paint.drawText(oldXPos-xStart, y, textLine->string(), blockStartCol, nextCol-blockStartCol);
636
637 // Draw preedit's underline
638 if (isIMEdit) {
639 TQRect r( oldXPos - xStart, 0, xPosAfter - oldXPos, fs->fontHeight );
640 paint.drawLine( r.bottomLeft(), r.bottomRight() );
641 }
642
643 // Put pen color back
644 if (isIMSel) paint.restore();
645
646 // We're done drawing?
647 if ((int)xPos > xEnd)
648 break;
649
650 // variable advancement
651 blockStartCol = nextCol;
652 oldXPos = xPosAfter;
653 //oldS = s+1;
654 }
655 } // renderNow
656
657 // determine cursor X position
658 if (showCursor && (cursor->col() == int(curCol)))
659 {
660 cursorVisible = true;
661 cursorXPos = xPos;
662 cursorMaxWidth = xPosAfter - xPos;
663 cursorColor = &curAt->textColor();
664 }
665 } // xPosAfter >= xStart
666 else
667 {
668 // variable advancement
669 blockStartCol = nextCol;
670 oldXPos = xPosAfter;
671 }
672
673 // increase xPos
674 xPos = xPosAfter;
675
676 // increase attribs pos
677 textAttributes++;
678
679 // to only switch font/color if needed
680 oldAt = curAt;
681 oldColor = curColor;
682
683 // col move
684 curCol++;
685 nextCol++;
686 currentPos.setCol(currentPos.col() + 1);
687
688 // Update the current indentation pos.
689 if (isTab)
690 {
691 curPos += m_tabWidth - (curPos % m_tabWidth);
692 }
693 else
694 {
695 curPos++;
696 }
697 }
698
699 // If this line has a partial selection that's the start of a multi-line selection,
700 // we have to fill areas on the right side of the text with the selection color.
701 if (showSelections() && hasSel && !selectionPainted && xStart >= (int)xPos && m_view->lineEndSelected(line, -1))
702 {
703 paint.fillRect(0, 0, xEnd-xStart, fs->fontHeight, config()->selectionColor());
704 }
705
706 // Determine cursor position (if it is not within the range being drawn)
707 if (showCursor && (cursor->col() >= int(curCol)))
708 {
709 cursorVisible = true;
710 cursorXPos = xPos + (cursor->col() - int(curCol)) * fs->myFontMetrics.width(TQChar(' '));
711 cursorMaxWidth = xPosAfter - xPos;
712 cursorColor = &oldAt->textColor();
713 }
714 }
715
716 // Paint cursor
717 if (cursorVisible)
718 {
719 uint cursorWidth = (caretStyle() == Replace && (cursorMaxWidth > 2)) ? cursorMaxWidth : 2;
720 paint.fillRect(cursorXPos-xStart, 0, cursorWidth, fs->fontHeight, *cursorColor);
721 }
722
723 // show word wrap marker if desirable
724 if (!isPrinterFriendly() && config()->wordWrapMarker() && fs->fixedPitch())
725 {
726 paint.setPen( config()->wordWrapMarkerColor() );
727 int _x = m_doc->config()->wordWrapAt() * fs->myFontMetrics.width('x') - xStart;
728 paint.drawLine( _x,0,_x,fs->fontHeight );
729 }
730
731 // cleanup ;)
732 delete bracketStartRange;
733 delete bracketEndRange;
734}
735
736uint KateRenderer::textWidth(const KateTextLine::Ptr &textLine, int cursorCol)
737{
738 if (!textLine)
739 return 0;
740
741 const int len = textLine->length();
742
743 if (cursorCol < 0)
744 cursorCol = len;
745
746 KateFontStruct *fs = config()->fontStruct();
747
748 const TQChar *unicode = textLine->text();
749 const TQString &textString = textLine->string();
750
751 int x = 0;
752 int width;
753 for (int z = 0; z < cursorCol; z++) {
754 KateAttribute* a = attribute(textLine->attribute(z));
755
756 if (z < len) {
757 width = a->width(*fs, textString, z, m_tabWidth);
758 } else {
759 // DF: commented out. It happens all the time.
760 //Q_ASSERT(!m_doc->wrapCursor());
761 width = a->width(*fs, TQChar(' '), m_tabWidth);
762 }
763
764 x += width;
765
766 if (z < len && unicode[z] == TQChar('\t'))
767 x -= x % width;
768 }
769
770 return x;
771}
772
773uint KateRenderer::textWidth(const KateTextLine::Ptr &textLine, uint startcol, uint maxwidth, bool *needWrap, int *endX)
774{
775 KateFontStruct *fs = config()->fontStruct();
776 uint x = 0;
777 uint endcol = startcol;
778 int endX2 = 0;
779 int lastWhiteSpace = -1;
780 int lastWhiteSpaceX = -1;
781
782 // used to not wrap a solitary word off the first line, ie. the
783 // first line should not wrap until some characters have been displayed if possible
784 bool foundNonWhitespace = startcol != 0;
785 bool foundWhitespaceAfterNonWhitespace = startcol != 0;
786
787 *needWrap = false;
788
789 const uint len = textLine->length();
790 const TQChar *unicode = textLine->text();
791 const TQString &textString = textLine->string();
792
793 uint z = startcol;
794 for (; z < len; z++)
795 {
796 KateAttribute* a = attribute(textLine->attribute(z));
797 int width = a->width(*fs, textString, z, m_tabWidth);
798 Q_ASSERT(width);
799 x += width;
800
801 // How should tabs be treated when they word-wrap on a print-out?
802 // if startcol != 0, this messes up (then again, word wrapping messes up anyway)
803 if (unicode[z] == TQChar('\t'))
804 x -= x % width;
805
806 if (unicode[z].isSpace())
807 {
808 lastWhiteSpace = z+1;
809 lastWhiteSpaceX = x;
810
811 if (foundNonWhitespace)
812 foundWhitespaceAfterNonWhitespace = true;
813 }
814 else
815 {
816 if (!foundWhitespaceAfterNonWhitespace) {
817 foundNonWhitespace = true;
818
819 lastWhiteSpace = z+1;
820 lastWhiteSpaceX = x;
821 }
822 }
823
824 if (x <= maxwidth)
825 {
826 if (lastWhiteSpace > -1)
827 {
828 endcol = lastWhiteSpace;
829 endX2 = lastWhiteSpaceX;
830 }
831 else
832 {
833 endcol = z+1;
834 endX2 = x;
835 }
836 }
837 else if (z == startcol)
838 {
839 // require a minimum of 1 character advancement per call, even if it means drawing gets cut off
840 // (geez gideon causes troubles with starting the views very small)
841 endcol = z+1;
842 endX2 = x;
843 }
844
845 if (x >= maxwidth)
846 {
847 *needWrap = true;
848 break;
849 }
850 }
851
852 if (*needWrap)
853 {
854 if (endX)
855 *endX = endX2;
856
857 return endcol;
858 }
859 else
860 {
861 if (endX)
862 *endX = x;
863
864 return z+1;
865 }
866}
867
868uint KateRenderer::textWidth(const KateTextCursor &cursor)
869{
870 int line = kMin(kMax(0, cursor.line()), (int)m_doc->numLines() - 1);
871 int col = kMax(0, cursor.col());
872
873 return textWidth(m_doc->kateTextLine(line), col);
874}
875
876uint KateRenderer::textWidth( KateTextCursor &cursor, int xPos, uint startCol)
877{
878 bool wrapCursor = m_view->wrapCursor();
879 int x, oldX;
880
881 KateFontStruct *fs = config()->fontStruct();
882
883 if (cursor.line() < 0) cursor.setLine(0);
884 if (cursor.line() > (int)m_doc->lastLine()) cursor.setLine(m_doc->lastLine());
885 KateTextLine::Ptr textLine = m_doc->kateTextLine(cursor.line());
886
887 if (!textLine) return 0;
888
889 const uint len = textLine->length();
890 const TQChar *unicode = textLine->text();
891 const TQString &textString = textLine->string();
892
893 x = oldX = 0;
894 uint z = startCol;
895 while (x < xPos && (!wrapCursor || z < len)) {
896 oldX = x;
897
898 KateAttribute* a = attribute(textLine->attribute(z));
899
900 int width = 0;
901
902 if (z < len)
903 width = a->width(*fs, textString, z, m_tabWidth);
904 else
905 width = a->width(*fs, TQChar(' '), m_tabWidth);
906
907 x += width;
908
909 if (z < len && unicode[z] == TQChar('\t'))
910 x -= x % width;
911
912 z++;
913 }
914 if (xPos - oldX < x - xPos && z > 0) {
915 z--;
916 x = oldX;
917 }
918 cursor.setCol(z);
919 return x;
920}
921
922const TQFont *KateRenderer::currentFont()
923{
924 return config()->font();
925}
926
927const TQFontMetrics* KateRenderer::currentFontMetrics()
928{
929 return config()->fontMetrics();
930}
931
932uint KateRenderer::textPos(uint line, int xPos, uint startCol, bool nearest)
933{
934 return textPos(m_doc->kateTextLine(line), xPos, startCol, nearest);
935}
936
937uint KateRenderer::textPos(const KateTextLine::Ptr &textLine, int xPos, uint startCol, bool nearest)
938{
939 Q_ASSERT(textLine);
940 if (!textLine)
941 return 0;
942
943 KateFontStruct *fs = config()->fontStruct();
944
945 int x, oldX;
946 x = oldX = 0;
947
948 uint z = startCol;
949 const uint len = textLine->length();
950 const TQString &textString = textLine->string();
951
952 while ( (x < xPos) && (z < len)) {
953 oldX = x;
954
955 KateAttribute* a = attribute(textLine->attribute(z));
956 x += a->width(*fs, textString, z, m_tabWidth);
957
958 z++;
959 }
960 if ( ( (! nearest) || xPos - oldX < x - xPos ) && z > 0 ) {
961 z--;
962 // newXPos = oldX;
963 }// else newXPos = x;
964 return z;
965}
966
967uint KateRenderer::fontHeight()
968{
969 return config()->fontStruct ()->fontHeight;
970}
971
972uint KateRenderer::documentHeight()
973{
974 return m_doc->numLines() * fontHeight();
975}
976
977bool KateRenderer::getSelectionBounds(uint line, uint lineLength, uint &start, uint &end)
978{
979 bool hasSel = false;
980
981 if (m_view->hasSelection() && !m_view->blockSelectionMode())
982 {
983 if (m_view->lineIsSelection(line))
984 {
985 start = m_view->selStartCol();
986 end = m_view->selEndCol();
987 hasSel = true;
988 }
989 else if ((int)line == m_view->selStartLine())
990 {
991 start = m_view->selStartCol();
992 end = lineLength;
993 hasSel = true;
994 }
995 else if ((int)line == m_view->selEndLine())
996 {
997 start = 0;
998 end = m_view->selEndCol();
999 hasSel = true;
1000 }
1001 }
1002 else if (m_view->lineHasSelected(line))
1003 {
1004 start = m_view->selStartCol();
1005 end = m_view->selEndCol();
1006 hasSel = true;
1007 }
1008
1009 if (start > end) {
1010 int temp = end;
1011 end = start;
1012 start = temp;
1013 }
1014
1015 return hasSel;
1016}
1017
1018void KateRenderer::updateConfig ()
1019{
1020 // update the attibute list pointer
1021 updateAttributes ();
1022
1023 if (m_view)
1024 m_view->updateRendererConfig();
1025}
1026
1027uint KateRenderer::spaceWidth()
1028{
1029 return attribute(0)->width(*config()->fontStruct(), TQChar(' '), m_tabWidth);
1030}
KateAttribute
The Attribute class incorporates all text decorations supported by Kate.
Definition: kateattribute.h:33
KateRenderer
Handles all of the work of rendering the text (used for the views and printing)
Definition: katerenderer.h:43
KateRenderer::setShowTabs
void setShowTabs(bool showTabs)
Set whether a mark should be painted to help identifying tabs.
Definition: katerenderer.cpp:87
KateRenderer::setIndentWidth
void setIndentWidth(int indentWidth)
Sets the width of the tab.
Definition: katerenderer.cpp:107
KateRenderer::setShowSelections
void setShowSelections(bool showSelections)
Set whether the view's selections should be shown.
Definition: katerenderer.cpp:116
KateRenderer::config
KateRendererConfig * config()
Configuration.
Definition: katerenderer.h:264
KateRenderer::caretStyle
KateRenderer::caretStyles caretStyle() const
The style of the caret (text cursor) to be painted.
Definition: katerenderer.h:87
KateRenderer::setDrawCaret
void setDrawCaret(bool drawCaret)
Set whether the caret (text cursor) will be drawn.
Definition: katerenderer.cpp:77
KateRenderer::isPrinterFriendly
bool isPrinterFriendly() const
Definition: katerenderer.cpp:139
KateRenderer::textPos
uint textPos(uint line, int xPos, uint startCol=0, bool nearest=true)
Definition: katerenderer.cpp:932
KateRenderer::setPrinterFriendly
void setPrinterFriendly(bool printerFriendly)
Configure this renderer to paint in a printer-friendly fashion.
Definition: katerenderer.cpp:144
KateRenderer::showIndentLines
bool showIndentLines() const
Definition: katerenderer.cpp:97
KateRenderer::paintTextLineBackground
bool paintTextLineBackground(TQPainter &paint, int line, bool isCurrentLine, int xStart, int xEnd)
Paint the background of a line.
Definition: katerenderer.cpp:152
KateRenderer::attribute
KateAttribute * attribute(uint pos)
This takes an in index, and returns all the attributes for it.
Definition: katerenderer.cpp:69
KateRenderer::showTabs
bool showTabs() const
Definition: katerenderer.h:100
KateRenderer::drawCaret
bool drawCaret() const
Determine whether the caret (text cursor) will be drawn.
Definition: katerenderer.h:75
KateRenderer::showSelections
bool showSelections() const
Show the view's selection?
Definition: katerenderer.h:136
KateRenderer::paintTextLine
void paintTextLine(TQPainter &paint, const KateLineRange *range, int xStart, int xEnd, const KateTextCursor *cursor=0L, const KateBracketRange *bracketmark=0L)
This is the ultimate function to perform painting of a text line.
Definition: katerenderer.cpp:253
KateRenderer::setTabWidth
void setTabWidth(int tabWidth)
Sets the width of the tab.
Definition: katerenderer.cpp:92
KateRenderer::caretStyles
caretStyles
Style of Caret (Insert or Replace mode)
Definition: katerenderer.h:48
KateRenderer::KateRenderer
KateRenderer(KateDocument *doc, KateView *view=0)
Constructor.
Definition: katerenderer.cpp:37
KateRenderer::increaseFontSizes
void increaseFontSizes()
Change to a different font (soon to be font set?)
Definition: katerenderer.cpp:121
KateRenderer::setCaretStyle
void setCaretStyle(KateRenderer::caretStyles style)
Set the style of caret to be painted.
Definition: katerenderer.cpp:82
KateRenderer::setShowIndentLines
void setShowIndentLines(bool showLines)
Set whether a guide should be painted to help identifying indent lines.
Definition: katerenderer.cpp:102
KateRenderer::updateAttributes
void updateAttributes()
update the highlighting attributes (for example after an hl change or after hl config changed)
Definition: katerenderer.cpp:63
KateRenderer::~KateRenderer
~KateRenderer()
Destructor.
Definition: katerenderer.cpp:57
KateRenderer::spaceWidth
uint spaceWidth()
Text width & height calculation functions...
Definition: katerenderer.cpp:1027
KateTextCursor
Simple cursor class with no document pointer.
Definition: katecursor.h:34
TDESharedPtr
TDEStdAccel::end
const TDEShortcut & end()

kate

Skip menu "kate"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kate

Skip menu "kate"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for kate by doxygen 1.9.4
This website is maintained by Timothy Pearson.