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