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