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