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