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 bracketStartRange->setBold(
true);
00231 superRanges.append(bracketStartRange);
00232 }
00233
00234
if (range->includesCursor(bracketmark->end())) {
00235
KateTextCursor endend = bracketmark->end();
00236 endend.
setCol(endend.
col()+1);
00237 bracketEndRange =
new KateArbitraryHighlightRange(m_doc, bracketmark->end(), endend);
00238 bracketEndRange->setBGColor(
config()->highlightedBracketColor());
00239 bracketEndRange->setBold(
true);
00240 superRanges.append(bracketEndRange);
00241 }
00242 }
00243
00244
00245 uint len = textLine->length();
00246 uint oldLen = len;
00247
00248
00249
bool cursorVisible =
false;
00250
int cursorMaxWidth = 0;
00251
00252
00253 KateFontStruct * fs =
config()->fontStruct();
00254
00255
00256
00257
bool hasSel =
false;
00258 uint startSel = 0;
00259 uint endSel = 0;
00260
00261
00262
bool selectionPainted =
false;
00263
bool isCurrentLine = (cursor && range->includesCursor(*cursor));
00264 selectionPainted =
paintTextLineBackground(paint, line, isCurrentLine, xStart, xEnd);
00265
if (selectionPainted)
00266 {
00267 hasSel =
true;
00268 startSel = 0;
00269 endSel = len + 1;
00270 }
00271
00272
int startcol = range->startCol;
00273
if (startcol > (
int)len)
00274 startcol = len;
00275
00276
if (startcol < 0)
00277 startcol = 0;
00278
00279
int endcol = range->wrap ? range->endCol : -1;
00280
if (endcol < 0)
00281 len = len - startcol;
00282
else
00283 len = endcol - startcol;
00284
00285
00286
KateAttribute* attr = m_doc->highlight()->attributes(m_schema)->data();
00287
00288
const QColor *cursorColor = &attr[0].
textColor();
00289
00290
00291
KateTextCursor currentPos(line, startcol);
00292 superRanges.firstBoundary(¤tPos);
00293
00294
if (
showSelections() && !selectionPainted)
00295 hasSel = getSelectionBounds(line, oldLen, startSel, endSel);
00296
00297
00298
if (range->startsInvisibleBlock) {
00299 paint.
setPen(
QPen(
config()->wordWrapMarkerColor(), 1, Qt::DashLine));
00300 paint.
drawLine(0, fs->fontHeight - 1, xEnd - xStart, fs->fontHeight - 1);
00301 }
00302
00303
00304
if (range->xOffset() && range->xOffset() > xStart)
00305 {
00306 paint.
fillRect(0, 0, range->xOffset() - xStart, fs->fontHeight,
00307
QBrush(
config()->wordWrapMarkerColor(), QBrush::DiagCrossPattern));
00308 }
00309
00310
00311 uint xPos = range->xOffset();
00312
int cursorXPos = 0;
00313
00314
00315
if (len < 1)
00316 {
00317
if (showCursor && (cursor->
col() >= int(startcol)))
00318 {
00319 cursorVisible =
true;
00320 cursorXPos = xPos + cursor->
col() * fs->myFontMetrics.width(spaceChar);
00321 }
00322 }
00323
else
00324 {
00325
bool isIMSel =
false;
00326
bool isIMEdit =
false;
00327
00328
bool isSel =
false;
00329
00330
KateAttribute customHL;
00331
00332
const QColor *curColor = 0;
00333
const QColor *oldColor = 0;
00334
00335
KateAttribute* oldAt = &attr[0];
00336
00337 uint oldXPos = xPos;
00338 uint xPosAfter = xPos;
00339
00340
KateAttribute currentHL;
00341
00342 uint blockStartCol = startcol;
00343 uint curCol = startcol;
00344 uint nextCol = curCol + 1;
00345
00346
00347
const uchar *textAttributes = textLine->attributes ();
00348
bool noAttribs = !textAttributes;
00349
00350
00351 textAttributes = textAttributes + startcol;
00352
00353 uint atLen = m_doc->highlight()->attributes(m_schema)->size();
00354
00355
00356
00357 uint trailingWhitespaceColumn = textLine->lastChar() + 1;
00358
00359
while (curCol - startcol < len)
00360 {
00361
QChar curChar = textLine->string()[curCol];
00362
00363
00364
bool isTab = curChar == tabChar;
00365
00366
00367
00368
KateAttribute* curAt = (noAttribs || ((*textAttributes) >= atLen)) ? &attr[0] : &attr[*textAttributes];
00369
00370
00371
00372 xPosAfter += curAt->
width(*fs, curChar, m_tabWidth);
00373
00374
00375
if (isTab)
00376 xPosAfter -= (xPosAfter % curAt->
width(*fs, curChar, m_tabWidth));
00377
00378
00379
00380
if ((
int)xPosAfter >= xStart)
00381 {
00382
00383 isSel = (
showSelections() && hasSel && (curCol >= startSel) && (curCol < endSel));
00384
00385
00386 isIMEdit = m_doc->isIMEdit( line, curCol );
00387
00388
00389 isIMSel = m_doc->isIMSelection( line, curCol );
00390
00391
00392 curColor = isSel ? &(curAt->
selectedTextColor()) : &(curAt->
textColor());
00393
00394
00395
if (curAt != oldAt || curColor != oldColor || (superRanges.count() && superRanges.currentBoundary() && *(superRanges.currentBoundary()) == currentPos)) {
00396
if (superRanges.count() && superRanges.currentBoundary() && *(superRanges.currentBoundary()) == currentPos)
00397 customHL = KateArbitraryHighlightRange::merge(superRanges.rangesIncluding(currentPos));
00398
00399
KateAttribute hl = customHL;
00400
00401 hl += *curAt;
00402
00403
00404
if (!hl.
itemSet(KateAttribute::TextColor))
00405 hl.
setTextColor(*curColor);
00406
00407
if (!isSel)
00408 paint.
setPen(hl.
textColor());
00409
else
00410 paint.
setPen(hl.
selectedTextColor());
00411
00412 paint.
setFont(hl.
font(*currentFont()));
00413
00414
if (superRanges.currentBoundary() && *(superRanges.currentBoundary()) == currentPos)
00415 superRanges.nextBoundary();
00416
00417 currentHL = hl;
00418 }
00419
00420
00421
00422
00423
00424
00425
bool renderNow =
false;
00426
if ((isTab)
00427
00428 || (superRanges.count() && superRanges.currentBoundary() && *(superRanges.currentBoundary()) ==
KateTextCursor(line, nextCol))
00429
00430
00431 || (curCol >= len - 1)
00432
00433
00434 || (curCol + 1 >= trailingWhitespaceColumn)
00435
00436
00437 || ((
int)xPos > xEnd)
00438
00439
00440 || (!noAttribs && curAt != &attr[*(textAttributes+1)])
00441
00442
00443 || (isSel != (hasSel && (nextCol >= startSel) && (nextCol < endSel)))
00444
00445
00446
00447 || (textLine->string()[nextCol] == tabChar)
00448
00449
00450 || ( isIMEdit != m_doc->isIMEdit( line, nextCol ) )
00451
00452
00453 || ( isIMSel != m_doc->isIMSelection( line, nextCol ) )
00454 )
00455 {
00456 renderNow =
true;
00457 }
00458
00459
if (renderNow)
00460 {
00461
if (!
isPrinterFriendly())
00462 {
00463
bool paintBackground =
true;
00464 uint width = xPosAfter - oldXPos;
00465
QColor fillColor;
00466
00467
if (isIMSel && !isTab)
00468 {
00469
00470 fillColor = m_view->colorGroup().color(QColorGroup::Foreground);
00471 }
00472
else if (isIMEdit && !isTab)
00473 {
00474
00475
00476
const QColorGroup& cg = m_view->colorGroup();
00477
int h1, s1, v1, h2, s2, v2;
00478 cg.
color( QColorGroup::Base ).hsv( &h1, &s1, &v1 );
00479 cg.
color( QColorGroup::Background ).hsv( &h2, &s2, &v2 );
00480 fillColor.
setHsv( h1, s1, ( v1 + v2 ) / 2 );
00481 }
00482
else if (!selectionPainted && (isSel || currentHL.
itemSet(KateAttribute::BGColor)))
00483 {
00484
if (isSel)
00485 {
00486 fillColor =
config()->selectionColor();
00487
00488
00489
00490
if ((curCol >= len - 1) && m_doc->lineEndSelected (line, endcol))
00491 width = xEnd - oldXPos;
00492 }
00493
else
00494 {
00495 fillColor = currentHL.
bgColor();
00496 }
00497 }
00498
else
00499 {
00500 paintBackground =
false;
00501 }
00502
00503
if (paintBackground)
00504 paint.
fillRect(oldXPos - xStart, 0, width, fs->fontHeight, fillColor);
00505
00506
if (isIMSel && paintBackground && !isTab)
00507 {
00508 paint.
save();
00509 paint.
setPen( m_view->colorGroup().color( QColorGroup::BrightText ) );
00510 }
00511 }
00512
00513
00514
int y = fs->fontAscent;
00515
00516
00517
00518
if (isTab || (curCol >= trailingWhitespaceColumn))
00519 {
00520
00521
static QString spaces;
00522
if (int(spaces.
length()) != m_tabWidth)
00523 spaces.
fill(
' ', m_tabWidth);
00524
00525 paint.
drawText(oldXPos-xStart, y, isTab ? spaces :
QString(
" "));
00526
00527
if (
showTabs())
00528 paintWhitespaceMarker(paint, xPos - xStart, y);
00529
00530
00531 blockStartCol = nextCol;
00532 oldXPos = xPosAfter;
00533 }
00534
else
00535 {
00536
00537 paint.
drawText(oldXPos-xStart, y, textLine->string(), blockStartCol, nextCol-blockStartCol);
00538
00539
00540
if (isIMEdit) {
00541
QRect r( oldXPos - xStart, 0, xPosAfter - oldXPos, fs->fontHeight );
00542 paint.
drawLine( r.
bottomLeft(), r.
bottomRight() );
00543 }
00544
00545
00546
if (isIMSel) paint.
restore();
00547
00548
00549
if ((
int)xPos > xEnd)
00550
break;
00551
00552
00553 blockStartCol = nextCol;
00554 oldXPos = xPosAfter;
00555
00556 }
00557 }
00558
00559
00560
if (showCursor && (cursor->
col() == int(curCol)))
00561 {
00562 cursorVisible =
true;
00563 cursorXPos = xPos;
00564 cursorMaxWidth = xPosAfter - xPos;
00565 cursorColor = &curAt->
textColor();
00566 }
00567 }
00568
else
00569 {
00570
00571 blockStartCol = nextCol;
00572 oldXPos = xPosAfter;
00573 }
00574
00575
00576 xPos = xPosAfter;
00577
00578
00579 textAttributes++;
00580
00581
00582 oldAt = curAt;
00583 oldColor = curColor;
00584
00585
00586 curCol++;
00587 nextCol++;
00588 currentPos.
setCol(currentPos.
col() + 1);
00589 }
00590
00591
00592
if (showCursor && (cursor->
col() >= int(curCol)))
00593 {
00594 cursorVisible =
true;
00595 cursorXPos = xPos + (cursor->
col() - int(curCol)) * fs->myFontMetrics.width(spaceChar);
00596 cursorMaxWidth = xPosAfter - xPos;
00597 cursorColor = &oldAt->
textColor();
00598 }
00599 }
00600
00601
00602
if (cursorVisible)
00603 {
00604 uint cursorWidth = (
caretStyle() == Replace && (cursorMaxWidth > 2)) ? cursorMaxWidth : 2;
00605 paint.
fillRect(cursorXPos-xStart, 0, cursorWidth, fs->fontHeight, *cursorColor);
00606 }
00607
00608
00609
if (!
isPrinterFriendly() &&
config()->wordWrapMarker() && fs->fixedPitch())
00610 {
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 KateTextLine::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 KateFontStruct *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
00642
00643 width = a->
width(*fs, spaceChar, m_tabWidth);
00644 }
00645
00646 x += width;
00647
00648
if (textLine->getChar(z) == tabChar)
00649 x -= x % width;
00650 }
00651
00652
return x;
00653 }
00654
00655 uint KateRenderer::textWidth(
const KateTextLine::Ptr &textLine, uint startcol, uint maxwidth,
bool *needWrap,
int *endX)
00656 {
00657 KateFontStruct *fs =
config()->fontStruct();
00658 uint x = 0;
00659 uint endcol = startcol;
00660
int endX2 = 0;
00661
int lastWhiteSpace = -1;
00662
int lastWhiteSpaceX = -1;
00663
00664
00665
00666
bool foundNonWhitespace = startcol != 0;
00667
bool foundWhitespaceAfterNonWhitespace = startcol != 0;
00668
00669 *needWrap =
false;
00670
00671 uint z = startcol;
00672
for (; z < textLine->length(); z++)
00673 {
00674
KateAttribute* a =
attribute(textLine->attribute(z));
00675
int width = a->
width(*fs, textLine->string(), z, m_tabWidth);
00676 Q_ASSERT(width);
00677 x += width;
00678
00679
if (textLine->getChar(z).isSpace())
00680 {
00681 lastWhiteSpace = z+1;
00682 lastWhiteSpaceX = x;
00683
00684
if (foundNonWhitespace)
00685 foundWhitespaceAfterNonWhitespace =
true;
00686 }
00687
else
00688 {
00689
if (!foundWhitespaceAfterNonWhitespace) {
00690 foundNonWhitespace =
true;
00691
00692 lastWhiteSpace = z+1;
00693 lastWhiteSpaceX = x;
00694 }
00695 }
00696
00697
00698
00699
if (textLine->getChar(z) == tabChar)
00700 x -= x % width;
00701
00702
if (x <= maxwidth)
00703 {
00704
if (lastWhiteSpace > -1)
00705 {
00706 endcol = lastWhiteSpace;
00707 endX2 = lastWhiteSpaceX;
00708 }
00709
else
00710 {
00711 endcol = z+1;
00712 endX2 = x;
00713 }
00714 }
00715
else if (z == startcol)
00716 {
00717
00718
00719 endcol = z+1;
00720 endX2 = x;
00721 }
00722
00723
if (x >= maxwidth)
00724 {
00725 *needWrap =
true;
00726
break;
00727 }
00728 }
00729
00730
if (*needWrap)
00731 {
00732
if (endX)
00733 *endX = endX2;
00734
00735
return endcol;
00736 }
00737
else
00738 {
00739
if (endX)
00740 *endX = x;
00741
00742
return z+1;
00743 }
00744 }
00745
00746 uint KateRenderer::textWidth(
const KateTextCursor &cursor)
00747 {
00748
int line = QMIN(QMAX(0, cursor.
line()), (
int)m_doc->numLines() - 1);
00749
int col = QMAX(0, cursor.
col());
00750
00751
return textWidth(m_doc->kateTextLine(line), col);
00752 }
00753
00754 uint KateRenderer::textWidth(
KateTextCursor &cursor,
int xPos, uint startCol)
00755 {
00756
bool wrapCursor = m_doc->wrapCursor();
00757
int len;
00758
int x, oldX;
00759
00760 KateFontStruct *fs =
config()->fontStruct();
00761
00762
if (cursor.
line() < 0) cursor.
setLine(0);
00763
if (cursor.
line() > (
int)m_doc->lastLine()) cursor.
setLine(m_doc->lastLine());
00764
KateTextLine::Ptr textLine = m_doc->kateTextLine(cursor.
line());
00765
00766
if (!textLine)
return 0;
00767
00768 len = textLine->length();
00769
00770 x = oldX = 0;
00771
int z = startCol;
00772
while (x < xPos && (!wrapCursor || z < len)) {
00773 oldX = x;
00774
00775
KateAttribute* a =
attribute(textLine->attribute(z));
00776
00777
int width = 0;
00778
00779
if (z < len)
00780 width = a->
width(*fs, textLine->string(), z, m_tabWidth);
00781
else
00782 width = a->
width(*fs, spaceChar, m_tabWidth);
00783
00784 x += width;
00785
00786
if (textLine->getChar(z) == tabChar)
00787 x -= x % width;
00788
00789 z++;
00790 }
00791
if (xPos - oldX < x - xPos && z > 0) {
00792 z--;
00793 x = oldX;
00794 }
00795 cursor.
setCol(z);
00796
return x;
00797 }
00798
00799
const QFont *KateRenderer::currentFont()
00800 {
00801
return config()->font();
00802 }
00803
00804
const QFontMetrics* KateRenderer::currentFontMetrics()
00805 {
00806
return config()->fontMetrics();
00807 }
00808
00809 uint
KateRenderer::textPos(uint line,
int xPos, uint startCol,
bool nearest)
00810 {
00811
return textPos(m_doc->kateTextLine(line), xPos, startCol, nearest);
00812 }
00813
00814 uint
KateRenderer::textPos(
const KateTextLine::Ptr &textLine,
int xPos, uint startCol,
bool nearest)
00815 {
00816 Q_ASSERT(textLine);
00817
if (!textLine)
00818
return 0;
00819
00820 KateFontStruct *fs =
config()->fontStruct();
00821
00822
int x, oldX;
00823 x = oldX = 0;
00824
00825 uint z = startCol;
00826 uint len= textLine->length();
00827
while ( (x < xPos) && (z < len)) {
00828 oldX = x;
00829
00830
KateAttribute* a =
attribute(textLine->attribute(z));
00831 x += a->
width(*fs, textLine->string(), z, m_tabWidth);
00832
00833 z++;
00834 }
00835
if ( ( (! nearest) || xPos - oldX < x - xPos ) && z > 0 ) {
00836 z--;
00837
00838 }
00839
return z;
00840 }
00841
00842 uint KateRenderer::fontHeight()
00843 {
00844
return config()->fontStruct ()->fontHeight;
00845 }
00846
00847 uint KateRenderer::documentHeight()
00848 {
00849
return m_doc->numLines() * fontHeight();
00850 }
00851
00852
bool KateRenderer::getSelectionBounds(uint line, uint lineLength, uint &start, uint &end)
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