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
00361 xPosAfter += curAt->
width(*fs, curChar, m_tabWidth);
00362
00363
00364
if (isTab)
00365 xPosAfter -= (xPosAfter % curAt->
width(*fs, curChar, m_tabWidth));
00366
00367
00368
00369
if ((
int)xPosAfter >= xStart)
00370 {
00371
00372 isSel = (
showSelections() && hasSel && (curCol >= startSel) && (curCol < endSel));
00373
00374
00375 isIMEdit = ( ( int( imStartLine ) == line ) & ( imStart < imEnd ) & ( curCol >= imStart ) & ( curCol < imEnd ) );
00376
00377
00378 isIMSel = ( ( int( imStartLine ) == line ) & ( imSelStart < imSelEnd ) & ( curCol >= imSelStart ) & ( curCol < imSelEnd ) );
00379
00380
00381 curColor = isSel ? &(curAt->
selectedTextColor()) : &(curAt->
textColor());
00382
00383
00384
if (curAt != oldAt || curColor != oldColor || (superRanges.count() && superRanges.currentBoundary() && *(superRanges.currentBoundary()) == currentPos)) {
00385
if (superRanges.count() && superRanges.currentBoundary() && *(superRanges.currentBoundary()) == currentPos)
00386 customHL = KateArbitraryHighlightRange::merge(superRanges.rangesIncluding(currentPos));
00387
00388
KateAttribute hl = customHL;
00389
00390 hl += *curAt;
00391
00392
00393
if (!hl.
itemSet(KateAttribute::TextColor))
00394 hl.
setTextColor(*curColor);
00395
00396
if (!isSel)
00397 paint.setPen(hl.
textColor());
00398
else
00399 paint.setPen(hl.
selectedTextColor());
00400
00401 paint.setFont(hl.
font(*currentFont()));
00402
00403
if (superRanges.currentBoundary() && *(superRanges.currentBoundary()) == currentPos)
00404 superRanges.nextBoundary();
00405
00406 currentHL = hl;
00407 }
00408
00409
00410
00411
if (isTab)
00412 {
00413
if (!
isPrinterFriendly() && !selectionPainted) {
00414
if (isSel)
00415 paint.fillRect(oldXPos - xStart, 0, xPosAfter - oldXPos, fs->fontHeight,
config()->selectionColor());
00416
else if (currentHL.
itemSet(KateAttribute::BGColor))
00417 paint.fillRect(oldXPos - xStart, 0, xPosAfter - oldXPos, fs->fontHeight, currentHL.
bgColor());
00418 }
00419
00420
00421
static QString spaces;
00422
if (int(spaces.length()) != m_tabWidth)
00423 spaces.fill(
' ', m_tabWidth);
00424
00425 paint.drawText(oldXPos-xStart, y, spaces);
00426
00427
if (
showTabs())
00428 {
00429
QPen penBackup( paint.pen() );
00430 paint.setPen(
config()->tabMarkerColor() );
00431 paint.drawPoint(xPos - xStart, y);
00432 paint.drawPoint(xPos - xStart + 1, y);
00433 paint.drawPoint(xPos - xStart, y - 1);
00434 paint.setPen( penBackup );
00435 }
00436
00437
00438 oldCol = curCol+1;
00439 oldXPos = xPosAfter;
00440 }
00441
00442
00443
00444
else if (
00445
00446 (superRanges.count() && superRanges.currentBoundary() && *(superRanges.currentBoundary()) ==
KateTextCursor(line, curCol+1)) ||
00447
00448
00449 (tmp < 2) ||
00450
00451
00452 ((
int)xPos > xEnd) ||
00453
00454
00455 (!noAttribs && curAt != &at[*(a+1)]) ||
00456
00457
00458 (isSel != (hasSel && ((curCol+1) >= startSel) && ((curCol+1) < endSel))) ||
00459
00460
00461
00462 (textLine->string()[curCol+1] == tabChar) ||
00463
00464
00465 ( isIMEdit != ( imStart < imEnd && ( (curCol+1) >= imStart && (curCol+1) < imEnd ) ) ) ||
00466
00467
00468 ( isIMSel != ( imSelStart < imSelEnd && ( (curCol+1) >= imSelStart && (curCol+1) < imSelEnd ) ) )
00469 )
00470 {
00471
00472
if (!
isPrinterFriendly() && !selectionPainted) {
00473
if (isSel)
00474 paint.fillRect(oldXPos - xStart, 0, xPosAfter - oldXPos, fs->fontHeight,
config()->selectionColor());
00475
else if (currentHL.
itemSet(KateAttribute::BGColor))
00476 paint.fillRect(oldXPos - xStart, 0, xPosAfter - oldXPos, fs->fontHeight, currentHL.
bgColor());
00477 }
00478
00479
00480
if (!
isPrinterFriendly()) {
00481
00482
if ( isIMEdit ) {
00483
const QColorGroup& cg = m_view->colorGroup();
00484
int h1, s1, v1, h2, s2, v2;
00485 cg.color( QColorGroup::Base ).hsv( &h1, &s1, &v1 );
00486 cg.color( QColorGroup::Background ).hsv( &h2, &s2, &v2 );
00487
QColor imCol;
00488 imCol.setHsv( h1, s1, ( v1 + v2 ) / 2 );
00489 paint.fillRect( oldXPos - xStart, 0, xPosAfter - oldXPos, fs->fontHeight, imCol );
00490 }
00491
00492
00493
if ( isIMSel ) {
00494
const QColorGroup& cg = m_view->colorGroup();
00495 paint.fillRect( oldXPos - xStart, 0, xPosAfter - oldXPos, fs->fontHeight, cg.color( QColorGroup::Foreground ) );
00496 paint.save();
00497 paint.setPen( cg.color( QColorGroup::BrightText ) );
00498 }
00499 }
00500
00501
00502 paint.drawText(oldXPos-xStart, y, textLine->string(), oldCol, curCol+1-oldCol);
00503
00504
00505
if (isIMSel) paint.restore();
00506
00507
00508
if ((
int)xPos > xEnd)
00509
break;
00510
00511
00512 oldCol = curCol+1;
00513 oldXPos = xPosAfter;
00514
00515 }
00516
00517
00518
if ((showCursor > -1) && (showCursor == (
int)curCol))
00519 {
00520 cursorVisible =
true;
00521 cursorXPos = xPos;
00522 cursorMaxWidth = xPosAfter - xPos;
00523 cursorColor = &curAt->
textColor();
00524 }
00525 }
00526
else
00527 {
00528
00529 oldCol = curCol+1;
00530 oldXPos = xPosAfter;
00531 }
00532
00533
00534 xPos = xPosAfter;
00535
00536
00537 a++;
00538
00539
00540 oldAt = curAt;
00541 oldColor = curColor;
00542
00543
00544 curCol++;
00545 currentPos.
setCol(currentPos.
col() + 1);
00546 }
00547
00548
00549
if ((showCursor > -1) && (showCursor >= (
int)curCol))
00550 {
00551 cursorVisible =
true;
00552 cursorXPos = xPos + (showCursor - (
int) curCol) * fs->myFontMetrics.width(spaceChar);
00553 cursorMaxWidth = xPosAfter - xPos;
00554 cursorColor = &oldAt->
textColor();
00555 }
00556 }
00557
00558
00559
00560
if (!
isPrinterFriendly() &&
showSelections() && !selectionPainted && m_doc->lineEndSelected (line, endcol))
00561 {
00562 paint.fillRect(xPos-xStart, 0, xEnd - xStart, fs->fontHeight,
config()->selectionColor());
00563 selectionPainted =
true;
00564 }
00565
00566
00567
if (cursorVisible)
00568 {
00569
if (
caretStyle() == Replace && (cursorMaxWidth > 2))
00570 paint.fillRect(cursorXPos-xStart, 0, cursorMaxWidth, fs->fontHeight, *cursorColor);
00571
else
00572 paint.fillRect(cursorXPos-xStart, 0, 2, fs->fontHeight, *cursorColor);
00573 }
00574
00575
00576
else if (showCursor > -1)
00577 {
00578
if ((cursorXPos2>=xStart) && (cursorXPos2<=xEnd))
00579 {
00580 cursorMaxWidth = fs->myFontMetrics.width(spaceChar);
00581
00582
if (
caretStyle() == Replace && (cursorMaxWidth > 2))
00583 paint.fillRect(cursorXPos2-xStart, 0, cursorMaxWidth, fs->fontHeight, attribute(0)->textColor());
00584
else
00585 paint.fillRect(cursorXPos2-xStart, 0, 2, fs->fontHeight, attribute(0)->textColor());
00586 }
00587 }
00588
00589
00590
if ( paintWWMarker ) {
00591 paint.setPen(
config()->wordWrapMarkerColor() );
00592
int _x = m_doc->config()->wordWrapAt() * fs->myFontMetrics.width(
'x') - xStart;
00593 paint.drawLine( _x,0,_x,fs->fontHeight );
00594 }
00595
00596
00597
delete bracketStartRange;
00598
delete bracketEndRange;
00599 }
00600
00601 uint KateRenderer::textWidth(
const KateTextLine::Ptr &textLine,
int cursorCol)
00602 {
00603
if (!textLine)
00604
return 0;
00605
00606
int len = textLine->length();
00607
00608
if (cursorCol < 0)
00609 cursorCol = len;
00610
00611 KateFontStruct *fs =
config()->fontStruct();
00612
00613
int x = 0;
00614
int width;
00615
for (
int z = 0; z < cursorCol; z++) {
00616
KateAttribute* a = attribute(textLine->attribute(z));
00617
00618
if (z < len) {
00619 width = a->
width(*fs, textLine->string(), z, m_tabWidth);
00620 }
else {
00621 Q_ASSERT(!m_doc->wrapCursor());
00622 width = a->
width(*fs, spaceChar, m_tabWidth);
00623 }
00624
00625 x += width;
00626
00627
if (textLine->getChar(z) == tabChar)
00628 x -= x % width;
00629 }
00630
00631
return x;
00632 }
00633
00634 uint KateRenderer::textWidth(
const KateTextLine::Ptr &textLine, uint startcol, uint maxwidth,
bool *needWrap,
int *endX)
00635 {
00636 KateFontStruct *fs =
config()->fontStruct();
00637 uint x = 0;
00638 uint endcol = startcol;
00639
int endX2 = 0;
00640
int lastWhiteSpace = -1;
00641
int lastWhiteSpaceX = -1;
00642
00643
00644
00645
bool foundNonWhitespace = startcol != 0;
00646
bool foundWhitespaceAfterNonWhitespace = startcol != 0;
00647
00648 *needWrap =
false;
00649
00650 uint z = startcol;
00651
for (; z < textLine->length(); z++)
00652 {
00653
KateAttribute* a = attribute(textLine->attribute(z));
00654
int width = a->
width(*fs, textLine->string(), z, m_tabWidth);
00655 Q_ASSERT(width);
00656 x += width;
00657
00658
if (textLine->getChar(z).isSpace())
00659 {
00660 lastWhiteSpace = z+1;
00661 lastWhiteSpaceX = x;
00662
00663
if (foundNonWhitespace)
00664 foundWhitespaceAfterNonWhitespace =
true;
00665 }
00666
else
00667 {
00668
if (!foundWhitespaceAfterNonWhitespace) {
00669 foundNonWhitespace =
true;
00670
00671 lastWhiteSpace = z+1;
00672 lastWhiteSpaceX = x;
00673 }
00674 }
00675
00676
00677
00678
if (textLine->getChar(z) == tabChar)
00679 x -= x % width;
00680
00681
if (x <= maxwidth)
00682 {
00683
if (lastWhiteSpace > -1)
00684 {
00685 endcol = lastWhiteSpace;
00686 endX2 = lastWhiteSpaceX;
00687 }
00688
else
00689 {
00690 endcol = z+1;
00691 endX2 = x;
00692 }
00693 }
00694
else if (z == startcol)
00695 {
00696
00697
00698 endcol = z+1;
00699 endX2 = x;
00700 }
00701
00702
if (x >= maxwidth)
00703 {
00704 *needWrap =
true;
00705
break;
00706 }
00707 }
00708
00709
if (*needWrap)
00710 {
00711
if (endX)
00712 *endX = endX2;
00713
00714
return endcol;
00715 }
00716
else
00717 {
00718
if (endX)
00719 *endX = x;
00720
00721
return z+1;
00722 }
00723 }
00724
00725 uint KateRenderer::textWidth(
const KateTextCursor &cursor)
00726 {
00727
int line = QMIN(QMAX(0, cursor.
line()), (
int)m_doc->numLines() - 1);
00728
int col = QMAX(0, cursor.
col());
00729
00730
return textWidth(m_doc->kateTextLine(line), col);
00731 }
00732
00733 uint KateRenderer::textWidth(
KateTextCursor &cursor,
int xPos, uint startCol)
00734 {
00735
bool wrapCursor = m_doc->wrapCursor();
00736
int len;
00737
int x, oldX;
00738
00739 KateFontStruct *fs =
config()->fontStruct();
00740
00741
if (cursor.
line() < 0) cursor.
setLine(0);
00742
if (cursor.
line() > (
int)m_doc->lastLine()) cursor.
setLine(m_doc->lastLine());
00743
KateTextLine::Ptr textLine = m_doc->kateTextLine(cursor.
line());
00744
00745
if (!textLine)
return 0;
00746
00747 len = textLine->length();
00748
00749 x = oldX = 0;
00750
int z = startCol;
00751
while (x < xPos && (!wrapCursor || z < len)) {
00752 oldX = x;
00753
00754
KateAttribute* a = attribute(textLine->attribute(z));
00755
00756
int width = 0;
00757
00758
if (z < len)
00759 width = a->
width(*fs, textLine->string(), z, m_tabWidth);
00760
else
00761 width = a->
width(*fs, spaceChar, m_tabWidth);
00762
00763 x += width;
00764
00765
if (textLine->getChar(z) == tabChar)
00766 x -= x % width;
00767
00768 z++;
00769 }
00770
if (xPos - oldX < x - xPos && z > 0) {
00771 z--;
00772 x = oldX;
00773 }
00774 cursor.
setCol(z);
00775
return x;
00776 }
00777
00778
const QFont *KateRenderer::currentFont()
00779 {
00780
return config()->font();
00781 }
00782
00783
const QFontMetrics* KateRenderer::currentFontMetrics()
00784 {
00785
return config()->fontMetrics();
00786 }
00787
00788 uint
KateRenderer::textPos(uint line,
int xPos, uint startCol,
bool nearest)
00789 {
00790
return textPos(m_doc->kateTextLine(line), xPos, startCol, nearest);
00791 }
00792
00793 uint
KateRenderer::textPos(
const KateTextLine::Ptr &textLine,
int xPos, uint startCol,
bool nearest)
00794 {
00795 Q_ASSERT(textLine);
00796
if (!textLine)
00797
return 0;
00798
00799 KateFontStruct *fs =
config()->fontStruct();
00800
00801
int x, oldX;
00802 x = oldX = 0;
00803
00804 uint z = startCol;
00805 uint len= textLine->length();
00806
while ( (x < xPos) && (z < len)) {
00807 oldX = x;
00808
00809
KateAttribute* a = attribute(textLine->attribute(z));
00810 x += a->
width(*fs, textLine->string(), z, m_tabWidth);
00811
00812 z++;
00813 }
00814
if ( ( (! nearest) || xPos - oldX < x - xPos ) && z > 0 ) {
00815 z--;
00816
00817 }
00818
return z;
00819 }
00820
00821 uint KateRenderer::fontHeight()
00822 {
00823
return config()->fontStruct ()->fontHeight;
00824 }
00825
00826 uint KateRenderer::documentHeight()
00827 {
00828
return m_doc->numLines() * fontHeight();
00829 }
00830
00831
00832
bool KateRenderer::selectBounds(uint line, uint &start, uint &end, uint lineLength)
00833 {
00834
bool hasSel =
false;
00835
00836
if (m_doc->hasSelection() && !m_doc->blockSelect)
00837 {
00838
if (m_doc->lineIsSelection(line))
00839 {
00840 start = m_doc->selectStart.col();
00841
end = m_doc->selectEnd.col();
00842 hasSel =
true;
00843 }
00844
else if ((
int)line == m_doc->selectStart.line())
00845 {
00846 start = m_doc->selectStart.col();
00847
end = lineLength;
00848 hasSel =
true;
00849 }
00850
else if ((
int)line == m_doc->selectEnd.line())
00851 {
00852 start = 0;
00853
end = m_doc->selectEnd.col();
00854 hasSel =
true;
00855 }
00856 }
00857
else if (m_doc->lineHasSelected(line))
00858 {
00859 start = m_doc->selectStart.col();
00860
end = m_doc->selectEnd.col();
00861 hasSel =
true;
00862 }
00863
00864
if (start >
end) {
00865
int temp =
end;
00866
end = start;
00867 start = temp;
00868 }
00869
00870
return hasSel;
00871 }
00872
00873
void KateRenderer::updateConfig ()
00874 {
00875
00876
updateAttributes ();
00877
00878
if (m_view)
00879 m_view->updateRendererConfig();
00880 }
00881
00882 uint
KateRenderer::spaceWidth()
00883 {
00884
return attribute(0)->
width(*
config()->fontStruct(), spaceChar, m_tabWidth);
00885 }
00886
00887