00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "katerenderer.h"
00023
00024 #include "katelinerange.h"
00025 #include "katedocument.h"
00026 #include "katearbitraryhighlight.h"
00027 #include "kateconfig.h"
00028 #include "katehighlight.h"
00029 #include "katefactory.h"
00030 #include "kateview.h"
00031
00032 #include <kdebug.h>
00033
00034 #include <qpainter.h>
00035 #include <qpopupmenu.h>
00036
00037 static const QChar tabChar('\t');
00038 static const QChar spaceChar(' ');
00039
00040 KateRenderer::KateRenderer(KateDocument* doc, KateView *view)
00041 : m_doc(doc), m_view (view), m_caretStyle(KateRenderer::Insert)
00042 , m_drawCaret(true)
00043 , m_showSelections(true)
00044 , m_showTabs(true)
00045 , m_printerFriendly(false)
00046 {
00047 KateFactory::self()->registerRenderer ( this );
00048 m_config = new KateRendererConfig (this);
00049
00050 m_tabWidth = m_doc->config()->tabWidth();
00051
00052 updateAttributes ();
00053 }
00054
00055 KateRenderer::~KateRenderer()
00056 {
00057 delete m_config;
00058 KateFactory::self()->deregisterRenderer ( this );
00059 }
00060
00061 void KateRenderer::updateAttributes ()
00062 {
00063 m_schema = config()->schema ();
00064 m_attributes = m_doc->highlight()->attributes (m_schema);
00065 }
00066
00067 KateAttribute* KateRenderer::attribute(uint pos)
00068 {
00069 if (pos < m_attributes->size())
00070 return &m_attributes->at(pos);
00071
00072 return &m_attributes->at(0);
00073 }
00074
00075 void KateRenderer::setDrawCaret(bool drawCaret)
00076 {
00077 m_drawCaret = drawCaret;
00078 }
00079
00080 void KateRenderer::setCaretStyle(KateRenderer::caretStyles style)
00081 {
00082 m_caretStyle = style;
00083 }
00084
00085 void KateRenderer::setShowTabs(bool showTabs)
00086 {
00087 m_showTabs = showTabs;
00088 }
00089
00090 void KateRenderer::setTabWidth(int tabWidth)
00091 {
00092 m_tabWidth = tabWidth;
00093 }
00094
00095 void KateRenderer::setShowSelections(bool showSelections)
00096 {
00097 m_showSelections = showSelections;
00098 }
00099
00100 void KateRenderer::increaseFontSizes()
00101 {
00102 QFont f ( *config()->font () );
00103 f.setPointSize (f.pointSize ()+1);
00104
00105 config()->setFont (f);
00106 }
00107
00108 void KateRenderer::decreaseFontSizes()
00109 {
00110 QFont f ( *config()->font () );
00111
00112 if ((f.pointSize ()-1) > 0)
00113 f.setPointSize (f.pointSize ()-1);
00114
00115 config()->setFont (f);
00116 }
00117
00118 bool KateRenderer::isPrinterFriendly() const
00119 {
00120 return m_printerFriendly;
00121 }
00122
00123 void KateRenderer::setPrinterFriendly(bool printerFriendly)
00124 {
00125 m_printerFriendly = printerFriendly;
00126 setShowTabs(false);
00127 setShowSelections(false);
00128 setDrawCaret(false);
00129 }
00130
00131 bool KateRenderer::paintTextLineBackground(QPainter& paint, int line, bool isCurrentLine, int xStart, int xEnd)
00132 {
00133 if (isPrinterFriendly())
00134 return false;
00135
00136
00137 KateFontStruct *fs = config()->fontStruct();
00138
00139
00140 QColor backgroundColor( config()->backgroundColor() );
00141
00142 bool selectionPainted = false;
00143 if (showSelections() && m_doc->lineSelected(line))
00144 {
00145 backgroundColor = config()->selectionColor();
00146 selectionPainted = true;
00147 }
00148 else
00149 {
00150
00151 if (isCurrentLine)
00152 backgroundColor = config()->highlightedLineColor();
00153
00154
00155 int markRed = 0, markGreen = 0, markBlue = 0, markCount = 0;
00156
00157
00158 uint mrk = m_doc->mark( line );
00159 if (mrk)
00160 {
00161 for (uint bit = 0; bit < 32; bit++)
00162 {
00163 KTextEditor::MarkInterface::MarkTypes markType = (KTextEditor::MarkInterface::MarkTypes)(1<<bit);
00164 if (mrk & markType)
00165 {
00166 QColor markColor = config()->lineMarkerColor(markType);
00167
00168 if (markColor.isValid()) {
00169 markCount++;
00170 markRed += markColor.red();
00171 markGreen += markColor.green();
00172 markBlue += markColor.blue();
00173 }
00174 }
00175 }
00176 }
00177
00178 if (markCount) {
00179 markRed /= markCount;
00180 markGreen /= markCount;
00181 markBlue /= markCount;
00182 backgroundColor.setRgb(
00183 int((backgroundColor.red() * 0.9) + (markRed * 0.1)),
00184 int((backgroundColor.green() * 0.9) + (markGreen * 0.1)),
00185 int((backgroundColor.blue() * 0.9) + (markBlue * 0.1))
00186 );
00187 }
00188 }
00189
00190
00191 paint.fillRect(0, 0, xEnd - xStart, fs->fontHeight, backgroundColor);
00192
00193 return selectionPainted;
00194 }
00195
00196 void KateRenderer::paintWhitespaceMarker(QPainter &paint, uint x, uint y)
00197 {
00198 QPen penBackup( paint.pen() );
00199 paint.setPen( config()->tabMarkerColor() );
00200 paint.drawPoint(x, y);
00201 paint.drawPoint(x + 1, y);
00202 paint.drawPoint(x, y - 1);
00203 paint.setPen( penBackup );
00204 }
00205
00206 void KateRenderer::paintTextLine(QPainter& paint, const KateLineRange* range, int xStart, int xEnd, const KateTextCursor* cursor, const KateTextRange* bracketmark)
00207 {
00208 int line = range->line;
00209
00210
00211 KateTextLine::Ptr textLine = m_doc->kateTextLine(line);
00212 if (!textLine)
00213 return;
00214
00215 bool showCursor = drawCaret() && cursor && range->includesCursor(*cursor);
00216
00217 KateSuperRangeList& superRanges = m_doc->arbitraryHL()->rangesIncluding(range->line, 0);
00218
00219
00220
00221
00222 KateArbitraryHighlightRange* bracketStartRange (0L);
00223 KateArbitraryHighlightRange* bracketEndRange (0L);
00224 if (bracketmark && bracketmark->isValid()) {
00225 if (range->includesCursor(bracketmark->start())) {
00226 KateTextCursor startend = bracketmark->start();
00227 startend.setCol(startend.col()+1);
00228 bracketStartRange = new KateArbitraryHighlightRange(m_doc, bracketmark->start(), startend);
00229 bracketStartRange->setBGColor(config()->highlightedBracketColor());
00230 superRanges.append(bracketStartRange);
00231 }
00232
00233 if (range->includesCursor(bracketmark->end())) {
00234 KateTextCursor endend = bracketmark->end();
00235 endend.setCol(endend.col()+1);
00236 bracketEndRange = new KateArbitraryHighlightRange(m_doc, bracketmark->end(), endend);
00237 bracketEndRange->setBGColor(config()->highlightedBracketColor());
00238 superRanges.append(bracketEndRange);
00239 }
00240 }
00241
00242
00243 uint len = textLine->length();
00244 uint oldLen = len;
00245
00246
00247 bool cursorVisible = false;
00248 int cursorMaxWidth = 0;
00249
00250
00251 KateFontStruct * fs = config()->fontStruct();
00252
00253
00254
00255 bool hasSel = false;
00256 uint startSel = 0;
00257 uint endSel = 0;
00258
00259
00260 bool selectionPainted = false;
00261 bool isCurrentLine = (cursor && range->includesCursor(*cursor));
00262 selectionPainted = paintTextLineBackground(paint, line, isCurrentLine, xStart, xEnd);
00263 if (selectionPainted)
00264 {
00265 hasSel = true;
00266 startSel = 0;
00267 endSel = len + 1;
00268 }
00269
00270 int startcol = range->startCol;
00271 if (startcol > (int)len)
00272 startcol = len;
00273
00274 if (startcol < 0)
00275 startcol = 0;
00276
00277 int endcol = range->wrap ? range->endCol : -1;
00278 if (endcol < 0)
00279 len = len - startcol;
00280 else
00281 len = endcol - startcol;
00282
00283
00284 KateAttribute* attr = m_doc->highlight()->attributes(m_schema)->data();
00285
00286 const QColor *cursorColor = &attr[0].textColor();
00287
00288
00289 KateTextCursor currentPos(line, startcol);
00290 superRanges.firstBoundary(¤tPos);
00291
00292 if (showSelections() && !selectionPainted)
00293 hasSel = getSelectionBounds(line, oldLen, startSel, endSel);
00294
00295
00296 if (range->startsInvisibleBlock) {
00297 paint.setPen(QPen(config()->wordWrapMarkerColor(), 1, Qt::DashLine));
00298 paint.drawLine(0, fs->fontHeight - 1, xEnd - xStart, fs->fontHeight - 1);
00299 }
00300
00301
00302 if (range->xOffset() && range->xOffset() > xStart)
00303 {
00304 paint.fillRect(0, 0, range->xOffset() - xStart, fs->fontHeight,
00305 QBrush(config()->wordWrapMarkerColor(), QBrush::DiagCrossPattern));
00306 }
00307
00308
00309 uint xPos = range->xOffset();
00310 int cursorXPos = 0;
00311
00312
00313 if (len < 1)
00314 {
00315 if (showCursor && (cursor->col() >= int(startcol)))
00316 {
00317 cursorVisible = true;
00318 cursorXPos = xPos + cursor->col() * fs->myFontMetrics.width(spaceChar);
00319 }
00320 }
00321 else
00322 {
00323 bool isIMSel = false;
00324 bool isIMEdit = false;
00325
00326 bool isSel = false;
00327
00328 KateAttribute customHL;
00329
00330 const QColor *curColor = 0;
00331 const QColor *oldColor = 0;
00332
00333 KateAttribute* oldAt = &attr[0];
00334
00335 uint oldXPos = xPos;
00336 uint xPosAfter = xPos;
00337
00338 KateAttribute currentHL;
00339
00340 uint blockStartCol = startcol;
00341 uint curCol = startcol;
00342 uint nextCol = curCol + 1;
00343
00344
00345 const uchar *textAttributes = textLine->attributes ();
00346 bool noAttribs = !textAttributes;
00347
00348
00349 textAttributes = textAttributes + startcol;
00350
00351 uint atLen = m_doc->highlight()->attributes(m_schema)->size();
00352
00353
00354
00355 uint trailingWhitespaceColumn = textLine->lastChar() + 1;
00356
00357 while (curCol - startcol < len)
00358 {
00359 QChar curChar = textLine->string()[curCol];
00360
00361
00362 bool isTab = curChar == tabChar;
00363
00364
00365
00366 KateAttribute* curAt = (noAttribs || ((*textAttributes) >= atLen)) ? &attr[0] : &attr[*textAttributes];
00367
00368
00369
00370 xPosAfter += curAt->width(*fs, curChar, m_tabWidth);
00371
00372
00373 if (isTab)
00374 xPosAfter -= (xPosAfter % curAt->width(*fs, curChar, m_tabWidth));
00375
00376
00377
00378 if ((int)xPosAfter >= xStart)
00379 {
00380
00381 isSel = (showSelections() && hasSel && (curCol >= startSel) && (curCol < endSel));
00382
00383
00384 isIMEdit = m_doc->isIMEdit( line, curCol );
00385
00386
00387 isIMSel = m_doc->isIMSelection( line, curCol );
00388
00389
00390 curColor = isSel ? &(curAt->selectedTextColor()) : &(curAt->textColor());
00391
00392
00393 if (curAt != oldAt || curColor != oldColor || (superRanges.count() && superRanges.currentBoundary() && *(superRanges.currentBoundary()) == currentPos)) {
00394 if (superRanges.count() && superRanges.currentBoundary() && *(superRanges.currentBoundary()) == currentPos)
00395 customHL = KateArbitraryHighlightRange::merge(superRanges.rangesIncluding(currentPos));
00396
00397 KateAttribute hl = customHL;
00398
00399 hl += *curAt;
00400
00401
00402 if (!hl.itemSet(KateAttribute::TextColor))
00403 hl.setTextColor(*curColor);
00404
00405 if (!isSel)
00406 paint.setPen(hl.textColor());
00407 else
00408 paint.setPen(hl.selectedTextColor());
00409
00410 paint.setFont(hl.font(*currentFont()));
00411
00412 if (superRanges.currentBoundary() && *(superRanges.currentBoundary()) == currentPos)
00413 superRanges.nextBoundary();
00414
00415 currentHL = hl;
00416 }
00417
00418
00419
00420
00421
00422
00423 bool renderNow = false;
00424 if ((isTab)
00425
00426 || (superRanges.count() && superRanges.currentBoundary() && *(superRanges.currentBoundary()) == KateTextCursor(line, nextCol))
00427
00428
00429 || (curCol >= len - 1)
00430
00431
00432 || (curCol + 1 >= trailingWhitespaceColumn)
00433
00434
00435 || ((int)xPos > xEnd)
00436
00437
00438 || (!noAttribs && curAt != &attr[*(textAttributes+1)])
00439
00440
00441 || (isSel != (hasSel && (nextCol >= startSel) && (nextCol < endSel)))
00442
00443
00444
00445 || (textLine->string()[nextCol] == tabChar)
00446
00447
00448 || ( isIMEdit != m_doc->isIMEdit( line, nextCol ) )
00449
00450
00451 || ( isIMSel != m_doc->isIMSelection( line, nextCol ) )
00452 )
00453 {
00454 renderNow = true;
00455 }
00456
00457 if (renderNow)
00458 {
00459 if (!isPrinterFriendly())
00460 {
00461 bool paintBackground = true;
00462 uint width = xPosAfter - oldXPos;
00463 QColor fillColor;
00464
00465 if (isIMSel && !isTab)
00466 {
00467
00468 fillColor = m_view->colorGroup().color(QColorGroup::Foreground);
00469 }
00470 else if (isIMEdit && !isTab)
00471 {
00472
00473
00474 const QColorGroup& cg = m_view->colorGroup();
00475 int h1, s1, v1, h2, s2, v2;
00476 cg.color( QColorGroup::Base ).hsv( &h1, &s1, &v1 );
00477 cg.color( QColorGroup::Background ).hsv( &h2, &s2, &v2 );
00478 fillColor.setHsv( h1, s1, ( v1 + v2 ) / 2 );
00479 }
00480 else if (!selectionPainted && (isSel || currentHL.itemSet(KateAttribute::BGColor)))
00481 {
00482 if (isSel)
00483 {
00484 fillColor = config()->selectionColor();
00485
00486
00487
00488 if ((curCol >= len - 1) && m_doc->lineEndSelected (line, endcol))
00489 width = xEnd - oldXPos;
00490 }
00491 else
00492 {
00493 fillColor = currentHL.bgColor();
00494 }
00495 }
00496 else
00497 {
00498 paintBackground = false;
00499 }
00500
00501 if (paintBackground)
00502 paint.fillRect(oldXPos - xStart, 0, width, fs->fontHeight, fillColor);
00503
00504 if (isIMSel && paintBackground && !isTab)
00505 {
00506 paint.save();
00507 paint.setPen( m_view->colorGroup().color( QColorGroup::BrightText ) );
00508 }
00509 }
00510
00511
00512 int y = fs->fontAscent;
00513
00514
00515
00516 if (isTab || (curCol >= trailingWhitespaceColumn))
00517 {
00518
00519 static QString spaces;
00520 if (int(spaces.length()) != m_tabWidth)
00521 spaces.fill(' ', m_tabWidth);
00522
00523 paint.drawText(oldXPos-xStart, y, isTab ? spaces : QString(" "));
00524
00525 if (showTabs())
00526 paintWhitespaceMarker(paint, xPos - xStart, y);
00527
00528
00529 blockStartCol = nextCol;
00530 oldXPos = xPosAfter;
00531 }
00532 else
00533 {
00534
00535 paint.drawText(oldXPos-xStart, y, textLine->string(), blockStartCol, nextCol-blockStartCol);
00536
00537
00538 if (isIMEdit) {
00539 QRect r( oldXPos - xStart, 0, xPosAfter - oldXPos, fs->fontHeight );
00540 paint.drawLine( r.bottomLeft(), r.bottomRight() );
00541 }
00542
00543
00544 if (isIMSel) paint.restore();
00545
00546
00547 if ((int)xPos > xEnd)
00548 break;
00549
00550
00551 blockStartCol = nextCol;
00552 oldXPos = xPosAfter;
00553
00554 }
00555 }
00556
00557
00558 if (showCursor && (cursor->col() == int(curCol)))
00559 {
00560 cursorVisible = true;
00561 cursorXPos = xPos;
00562 cursorMaxWidth = xPosAfter - xPos;
00563 cursorColor = &curAt->textColor();
00564 }
00565 }
00566 else
00567 {
00568
00569 blockStartCol = nextCol;
00570 oldXPos = xPosAfter;
00571 }
00572
00573
00574 xPos = xPosAfter;
00575
00576
00577 textAttributes++;
00578
00579
00580 oldAt = curAt;
00581 oldColor = curColor;
00582
00583
00584 curCol++;
00585 nextCol++;
00586 currentPos.setCol(currentPos.col() + 1);
00587 }
00588
00589
00590 if (showCursor && (cursor->col() >= int(curCol)))
00591 {
00592 cursorVisible = true;
00593 cursorXPos = xPos + (cursor->col() - int(curCol)) * fs->myFontMetrics.width(spaceChar);
00594 cursorMaxWidth = xPosAfter - xPos;
00595 cursorColor = &oldAt->textColor();
00596 }
00597 }
00598
00599
00600 if (cursorVisible)
00601 {
00602 uint cursorWidth = (caretStyle() == Replace && (cursorMaxWidth > 2)) ? cursorMaxWidth : 2;
00603 paint.fillRect(cursorXPos-xStart, 0, cursorWidth, fs->fontHeight, *cursorColor);
00604 }
00605
00606
00607 if (!isPrinterFriendly() && config()->wordWrapMarker() && fs->fixedPitch())
00608 {
00609 paint.setPen( config()->wordWrapMarkerColor() );
00610 int _x = m_doc->config()->wordWrapAt() * fs->myFontMetrics.width('x') - xStart;
00611 paint.drawLine( _x,0,_x,fs->fontHeight );
00612 }
00613
00614
00615 delete bracketStartRange;
00616 delete bracketEndRange;
00617 }
00618
00619 uint KateRenderer::textWidth(const KateTextLine::Ptr &textLine, int cursorCol)
00620 {
00621 if (!textLine)
00622 return 0;
00623
00624 int len = textLine->length();
00625
00626 if (cursorCol < 0)
00627 cursorCol = len;
00628
00629 KateFontStruct *fs = config()->fontStruct();
00630
00631 int x = 0;
00632 int width;
00633 for (int z = 0; z < cursorCol; z++) {
00634 KateAttribute* a = attribute(textLine->attribute(z));
00635
00636 if (z < len) {
00637 width = a->width(*fs, textLine->string(), z, m_tabWidth);
00638 } else {
00639
00640
00641 width = a->width(*fs, spaceChar, m_tabWidth);
00642 }
00643
00644 x += width;
00645
00646 if (textLine->getChar(z) == tabChar)
00647 x -= x % width;
00648 }
00649
00650 return x;
00651 }
00652
00653 uint KateRenderer::textWidth(const KateTextLine::Ptr &textLine, uint startcol, uint maxwidth, bool *needWrap, int *endX)
00654 {
00655 KateFontStruct *fs = config()->fontStruct();
00656 uint x = 0;
00657 uint endcol = startcol;
00658 int endX2 = 0;
00659 int lastWhiteSpace = -1;
00660 int lastWhiteSpaceX = -1;
00661
00662
00663
00664 bool foundNonWhitespace = startcol != 0;
00665 bool foundWhitespaceAfterNonWhitespace = startcol != 0;
00666
00667 *needWrap = false;
00668
00669 uint z = startcol;
00670 for (; z < textLine->length(); z++)
00671 {
00672 KateAttribute* a = attribute(textLine->attribute(z));
00673 int width = a->width(*fs, textLine->string(), z, m_tabWidth);
00674 Q_ASSERT(width);
00675 x += width;
00676
00677 if (textLine->getChar(z).isSpace())
00678 {
00679 lastWhiteSpace = z+1;
00680 lastWhiteSpaceX = x;
00681
00682 if (foundNonWhitespace)
00683 foundWhitespaceAfterNonWhitespace = true;
00684 }
00685 else
00686 {
00687 if (!foundWhitespaceAfterNonWhitespace) {
00688 foundNonWhitespace = true;
00689
00690 lastWhiteSpace = z+1;
00691 lastWhiteSpaceX = x;
00692 }
00693 }
00694
00695
00696
00697 if (textLine->getChar(z) == tabChar)
00698 x -= x % width;
00699
00700 if (x <= maxwidth)
00701 {
00702 if (lastWhiteSpace > -1)
00703 {
00704 endcol = lastWhiteSpace;
00705 endX2 = lastWhiteSpaceX;
00706 }
00707 else
00708 {
00709 endcol = z+1;
00710 endX2 = x;
00711 }
00712 }
00713 else if (z == startcol)
00714 {
00715
00716
00717 endcol = z+1;
00718 endX2 = x;
00719 }
00720
00721 if (x >= maxwidth)
00722 {
00723 *needWrap = true;
00724 break;
00725 }
00726 }
00727
00728 if (*needWrap)
00729 {
00730 if (endX)
00731 *endX = endX2;
00732
00733 return endcol;
00734 }
00735 else
00736 {
00737 if (endX)
00738 *endX = x;
00739
00740 return z+1;
00741 }
00742 }
00743
00744 uint KateRenderer::textWidth(const KateTextCursor &cursor)
00745 {
00746 int line = QMIN(QMAX(0, cursor.line()), (int)m_doc->numLines() - 1);
00747 int col = QMAX(0, cursor.col());
00748
00749 return textWidth(m_doc->kateTextLine(line), col);
00750 }
00751
00752 uint KateRenderer::textWidth( KateTextCursor &cursor, int xPos, uint startCol)
00753 {
00754 bool wrapCursor = m_doc->wrapCursor();
00755 int len;
00756 int x, oldX;
00757
00758 KateFontStruct *fs = config()->fontStruct();
00759
00760 if (cursor.line() < 0) cursor.setLine(0);
00761 if (cursor.line() > (int)m_doc->lastLine()) cursor.setLine(m_doc->lastLine());
00762 KateTextLine::Ptr textLine = m_doc->kateTextLine(cursor.line());
00763
00764 if (!textLine) return 0;
00765
00766 len = textLine->length();
00767
00768 x = oldX = 0;
00769 int z = startCol;
00770 while (x < xPos && (!wrapCursor || z < len)) {
00771 oldX = x;
00772
00773 KateAttribute* a = attribute(textLine->attribute(z));
00774
00775 int width = 0;
00776
00777 if (z < len)
00778 width = a->width(*fs, textLine->string(), z, m_tabWidth);
00779 else
00780 width = a->width(*fs, spaceChar, m_tabWidth);
00781
00782 x += width;
00783
00784 if (textLine->getChar(z) == tabChar)
00785 x -= x % width;
00786
00787 z++;
00788 }
00789 if (xPos - oldX < x - xPos && z > 0) {
00790 z--;
00791 x = oldX;
00792 }
00793 cursor.setCol(z);
00794 return x;
00795 }
00796
00797 const QFont *KateRenderer::currentFont()
00798 {
00799 return config()->font();
00800 }
00801
00802 const QFontMetrics* KateRenderer::currentFontMetrics()
00803 {
00804 return config()->fontMetrics();
00805 }
00806
00807 uint KateRenderer::textPos(uint line, int xPos, uint startCol, bool nearest)
00808 {
00809 return textPos(m_doc->kateTextLine(line), xPos, startCol, nearest);
00810 }
00811
00812 uint KateRenderer::textPos(const KateTextLine::Ptr &textLine, int xPos, uint startCol, bool nearest)
00813 {
00814 Q_ASSERT(textLine);
00815 if (!textLine)
00816 return 0;
00817
00818 KateFontStruct *fs = config()->fontStruct();
00819
00820 int x, oldX;
00821 x = oldX = 0;
00822
00823 uint z = startCol;
00824 uint len= textLine->length();
00825 while ( (x < xPos) && (z < len)) {
00826 oldX = x;
00827
00828 KateAttribute* a = attribute(textLine->attribute(z));
00829 x += a->width(*fs, textLine->string(), z, m_tabWidth);
00830
00831 z++;
00832 }
00833 if ( ( (! nearest) || xPos - oldX < x - xPos ) && z > 0 ) {
00834 z--;
00835
00836 }
00837 return z;
00838 }
00839
00840 uint KateRenderer::fontHeight()
00841 {
00842 return config()->fontStruct ()->fontHeight;
00843 }
00844
00845 uint KateRenderer::documentHeight()
00846 {
00847 return m_doc->numLines() * fontHeight();
00848 }
00849
00850 bool KateRenderer::getSelectionBounds(uint line, uint lineLength, uint &start, uint &end)
00851 {
00852 bool hasSel = false;
00853
00854 if (m_doc->hasSelection() && !m_doc->blockSelect)
00855 {
00856 if (m_doc->lineIsSelection(line))
00857 {
00858 start = m_doc->selectStart.col();
00859 end = m_doc->selectEnd.col();
00860 hasSel = true;
00861 }
00862 else if ((int)line == m_doc->selectStart.line())
00863 {
00864 start = m_doc->selectStart.col();
00865 end = lineLength;
00866 hasSel = true;
00867 }
00868 else if ((int)line == m_doc->selectEnd.line())
00869 {
00870 start = 0;
00871 end = m_doc->selectEnd.col();
00872 hasSel = true;
00873 }
00874 }
00875 else if (m_doc->lineHasSelected(line))
00876 {
00877 start = m_doc->selectStart.col();
00878 end = m_doc->selectEnd.col();
00879 hasSel = true;
00880 }
00881
00882 if (start > end) {
00883 int temp = end;
00884 end = start;
00885 start = temp;
00886 }
00887
00888 return hasSel;
00889 }
00890
00891 void KateRenderer::updateConfig ()
00892 {
00893
00894 updateAttributes ();
00895
00896 if (m_view)
00897 m_view->updateRendererConfig();
00898 }
00899
00900 uint KateRenderer::spaceWidth()
00901 {
00902 return attribute(0)->width(*config()->fontStruct(), spaceChar, m_tabWidth);
00903 }
00904
00905