mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-11-23 02:29:41 +01:00
SynEdit: Clean up, dead code and duplicates
git-svn-id: trunk@18597 -
This commit is contained in:
parent
f50efde17e
commit
6a87b62df4
@ -2667,7 +2667,6 @@ end;
|
|||||||
|
|
||||||
procedure TCustomSynEdit.PaintTextLines(AClip: TRect; FirstLine, LastLine,
|
procedure TCustomSynEdit.PaintTextLines(AClip: TRect; FirstLine, LastLine,
|
||||||
FirstCol, LastCol: integer);
|
FirstCol, LastCol: integer);
|
||||||
{$IFDEF SYN_LAZARUS}
|
|
||||||
// FirstLine, LastLine are based 1
|
// FirstLine, LastLine are based 1
|
||||||
// FirstCol, LastCol are screen based 1 without scrolling (physical position).
|
// FirstCol, LastCol are screen based 1 without scrolling (physical position).
|
||||||
// i.e. the real screen position is fTextOffset+Pred(FirstCol)*CharWidth
|
// i.e. the real screen position is fTextOffset+Pred(FirstCol)*CharWidth
|
||||||
@ -3432,538 +3431,6 @@ begin
|
|||||||
fMarkupManager.EndMarkup;
|
fMarkupManager.EndMarkup;
|
||||||
ReAllocMem(TokenAccu.p,0);
|
ReAllocMem(TokenAccu.p,0);
|
||||||
end;
|
end;
|
||||||
{$ELSE below for NOT SYN_LAZARUS ----------------------------------------------}
|
|
||||||
var
|
|
||||||
bDoRightEdge: boolean; // right edge
|
|
||||||
nRightEdge: integer;
|
|
||||||
// selection info
|
|
||||||
bAnySelection: boolean; // any selection visible?
|
|
||||||
nSelL1, nSelCol1: integer; // start of selected area
|
|
||||||
nSelL2, nSelCol2: integer; // end of selected area
|
|
||||||
// info about normal and selected text and background colors
|
|
||||||
bSpecialLine, bLineSelected: boolean;
|
|
||||||
colFG, colBG: TColor;
|
|
||||||
colSelFG, colSelBG: TColor;
|
|
||||||
colEditorBG: TColor;
|
|
||||||
// info about selection of the current line
|
|
||||||
nSelStart, nSelEnd: integer;
|
|
||||||
bComplexLine: boolean;
|
|
||||||
// painting the background and the text
|
|
||||||
rcLine, rcToken: TRect;
|
|
||||||
TokenAccu: record
|
|
||||||
// Note: s is not managed as a string, it will only grow!!!
|
|
||||||
// Never use AppendStr or "+", use Len and MaxLen instead and
|
|
||||||
// copy the string chars directly. This is for efficiency.
|
|
||||||
Len, MaxLen, CharsBefore: integer;
|
|
||||||
s: string;
|
|
||||||
FG, BG: TColor;
|
|
||||||
Style: TFontStyles;
|
|
||||||
end;
|
|
||||||
dc: HDC;
|
|
||||||
|
|
||||||
{ local procedures }
|
|
||||||
|
|
||||||
procedure ComputeSelectionInfo;
|
|
||||||
var
|
|
||||||
p: TPoint;
|
|
||||||
begin
|
|
||||||
bAnySelection := FALSE;
|
|
||||||
// Only if selection is visible anyway.
|
|
||||||
if (not HideSelection or Self.Focused) then begin
|
|
||||||
bAnySelection := TRUE;
|
|
||||||
// Get the *real* start of the selected area.
|
|
||||||
if (fBlockBegin.Y < fBlockEnd.Y) then begin
|
|
||||||
nSelL1 := fBlockBegin.Y;
|
|
||||||
nSelCol1 := fBlockBegin.X;
|
|
||||||
nSelL2 := fBlockEnd.Y;
|
|
||||||
nSelCol2 := fBlockEnd.X;
|
|
||||||
end else if (fBlockBegin.Y > fBlockEnd.Y) then begin
|
|
||||||
nSelL2 := fBlockBegin.Y;
|
|
||||||
nSelCol2 := fBlockBegin.X;
|
|
||||||
nSelL1 := fBlockEnd.Y;
|
|
||||||
nSelCol1 := fBlockEnd.X;
|
|
||||||
end else if (fBlockBegin.X <> fBlockEnd.X) then begin
|
|
||||||
// No selection at all, or it is only on this line.
|
|
||||||
nSelL1 := fBlockBegin.Y;
|
|
||||||
nSelL2 := nSelL1;
|
|
||||||
if (fBlockBegin.X < fBlockEnd.X) then begin
|
|
||||||
nSelCol1 := fBlockBegin.X;
|
|
||||||
nSelCol2 := fBlockEnd.X;
|
|
||||||
end else begin
|
|
||||||
nSelCol2 := fBlockBegin.X;
|
|
||||||
nSelCol1 := fBlockEnd.X;
|
|
||||||
end;
|
|
||||||
end else
|
|
||||||
bAnySelection := FALSE;
|
|
||||||
// If there is any visible selection so far, then test if there is an
|
|
||||||
// intersection with the area to be painted.
|
|
||||||
if bAnySelection then begin
|
|
||||||
// Don't care if the selection is not visible.
|
|
||||||
bAnySelection := (nSelL2 >= FirstLine) and (nSelL1 <= LastLine);
|
|
||||||
// In the column selection mode sort the begin and end of the selection,
|
|
||||||
// this makes the painting code simpler.
|
|
||||||
if (SelectionMode = smColumn) and (nSelCol1 > nSelCol2) then
|
|
||||||
SwapInt(nSelCol1, nSelCol2);
|
|
||||||
if bAnySelection then begin
|
|
||||||
// Transform the selection from text space into screen space
|
|
||||||
p := LogicalToPhysicalPos(Point(nSelCol1, nSelL1));
|
|
||||||
nSelCol1 := p.x;
|
|
||||||
nSelL1 := p.y;
|
|
||||||
p := LogicalToPhysicalPos(point(nSelCol2, nSelL2));
|
|
||||||
nSelCol2 := p.x;
|
|
||||||
nSelL2 := p.y;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure SetDrawingColors(Selected: boolean);
|
|
||||||
begin
|
|
||||||
with fTextDrawer do
|
|
||||||
if Selected then begin
|
|
||||||
SetBackColor(colSelBG);
|
|
||||||
SetForeColor(colSelFG);
|
|
||||||
end else begin
|
|
||||||
SetBackColor(colBG);
|
|
||||||
SetForeColor(colFG);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function ColumnToXValue(Col: integer): integer;
|
|
||||||
// map screen column to screen pixel
|
|
||||||
begin
|
|
||||||
Result := fTextOffset + Pred(Col) * fCharWidth;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure PaintToken(const Token: string;
|
|
||||||
TokenLen, CharsBefore, First, Last: integer);
|
|
||||||
// CharsBefore tells if Token starts at column one or not
|
|
||||||
var
|
|
||||||
pszText: PChar;
|
|
||||||
nCharsToPaint: integer;
|
|
||||||
nX: integer;
|
|
||||||
const
|
|
||||||
ETOOptions = ETO_CLIPPED or ETO_OPAQUE;
|
|
||||||
begin
|
|
||||||
if (Last >= First) and (rcToken.Right > rcToken.Left) then begin
|
|
||||||
nX := ColumnToXValue(First);
|
|
||||||
Dec(First, CharsBefore);
|
|
||||||
Dec(Last, CharsBefore);
|
|
||||||
if (First > TokenLen) then begin
|
|
||||||
pszText := nil;
|
|
||||||
nCharsToPaint := 0;
|
|
||||||
end else begin
|
|
||||||
{$IFDEF SYN_MBCSSUPPORT}
|
|
||||||
if (First > 1) and (ByteType(Token, First) = mbTrailByte) then begin
|
|
||||||
Dec(First);
|
|
||||||
Dec(nX, fCharWidth);
|
|
||||||
end;
|
|
||||||
{$ENDIF}
|
|
||||||
pszText := PChar(@Token[First]);
|
|
||||||
nCharsToPaint := Min(Last - First + 1, TokenLen - First + 1);
|
|
||||||
end;
|
|
||||||
fTextDrawer.ExtTextOut(nX, rcToken.Top, ETOOptions, rcToken,
|
|
||||||
pszText, nCharsToPaint);
|
|
||||||
rcToken.Left := rcToken.Right;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure PaintHighlightToken(bFillToEOL: boolean);
|
|
||||||
var
|
|
||||||
bComplexToken: boolean;
|
|
||||||
nC1, nC2, nC1Sel, nC2Sel: integer;
|
|
||||||
bU1, bSel, bU2: boolean;
|
|
||||||
nX1, nX2: integer;
|
|
||||||
begin
|
|
||||||
// Compute some helper variables.
|
|
||||||
nC1 := Max(FirstCol, TokenAccu.CharsBefore + 1);
|
|
||||||
nC2 := Min(LastCol, TokenAccu.CharsBefore + TokenAccu.Len + 1);
|
|
||||||
if bComplexLine then begin
|
|
||||||
bU1 := (nC1 < nSelStart);
|
|
||||||
bSel := (nC1 < nSelEnd) and (nC2 >= nSelStart);
|
|
||||||
bU2 := (nC2 >= nSelEnd);
|
|
||||||
bComplexToken := bSel and (bU1 or bU2);
|
|
||||||
end else begin
|
|
||||||
bU1 := FALSE; // to shut up Compiler warning Delphi 2
|
|
||||||
bSel := bLineSelected;
|
|
||||||
bU2 := FALSE; // to shut up Compiler warning Delphi 2
|
|
||||||
bComplexToken := FALSE;
|
|
||||||
end;
|
|
||||||
// Any token chars accumulated?
|
|
||||||
if (TokenAccu.Len > 0) then begin
|
|
||||||
// Initialize the colors and the font style.
|
|
||||||
if not bSpecialLine then begin
|
|
||||||
colBG := TokenAccu.BG;
|
|
||||||
colFG := TokenAccu.FG;
|
|
||||||
end;
|
|
||||||
fTextDrawer.SetStyle(TokenAccu.Style);
|
|
||||||
// Paint the chars
|
|
||||||
if bComplexToken then begin
|
|
||||||
// first unselected part of the token
|
|
||||||
if bU1 then begin
|
|
||||||
SetDrawingColors(FALSE);
|
|
||||||
rcToken.Right := ColumnToXValue(nSelStart);
|
|
||||||
with TokenAccu do PaintToken(s, Len, CharsBefore, nC1, nSelStart);
|
|
||||||
end;
|
|
||||||
// selected part of the token
|
|
||||||
SetDrawingColors(TRUE);
|
|
||||||
nC1Sel := Max(nSelStart, nC1);
|
|
||||||
nC2Sel := Min(nSelEnd, nC2);
|
|
||||||
rcToken.Right := ColumnToXValue(nC2Sel);
|
|
||||||
with TokenAccu do PaintToken(s, Len, CharsBefore, nC1Sel, nC2Sel);
|
|
||||||
// second unselected part of the token
|
|
||||||
if bU2 then begin
|
|
||||||
SetDrawingColors(FALSE);
|
|
||||||
rcToken.Right := ColumnToXValue(nC2);
|
|
||||||
with TokenAccu do PaintToken(s, Len, CharsBefore, nSelEnd, nC2);
|
|
||||||
end;
|
|
||||||
end else begin
|
|
||||||
SetDrawingColors(bSel);
|
|
||||||
rcToken.Right := ColumnToXValue(nC2);
|
|
||||||
with TokenAccu do PaintToken(s, Len, CharsBefore, nC1, nC2);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
// Fill the background to the end of this line if necessary.
|
|
||||||
if bFillToEOL and (rcToken.Left < rcLine.Right) then begin
|
|
||||||
if not bSpecialLine then colBG := colEditorBG;
|
|
||||||
if bComplexLine then begin
|
|
||||||
nX1 := ColumnToXValue(nSelStart);
|
|
||||||
nX2 := ColumnToXValue(nSelEnd);
|
|
||||||
if (rcToken.Left < nX1) then begin
|
|
||||||
SetDrawingColors(FALSE);
|
|
||||||
rcToken.Right := nX1;
|
|
||||||
InternalFillRect(dc, rcToken);
|
|
||||||
rcToken.Left := nX1;
|
|
||||||
end;
|
|
||||||
if (rcToken.Left < nX2) then begin
|
|
||||||
SetDrawingColors(TRUE);
|
|
||||||
rcToken.Right := nX2;
|
|
||||||
InternalFillRect(dc, rcToken);
|
|
||||||
rcToken.Left := nX2;
|
|
||||||
end;
|
|
||||||
if (rcToken.Left < rcLine.Right) then begin
|
|
||||||
SetDrawingColors(FALSE);
|
|
||||||
rcToken.Right := rcLine.Right;
|
|
||||||
InternalFillRect(dc, rcToken);
|
|
||||||
end;
|
|
||||||
end else begin
|
|
||||||
SetDrawingColors(bLineSelected);
|
|
||||||
rcToken.Right := rcLine.Right;
|
|
||||||
InternalFillRect(dc, rcToken);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure AddHighlightToken(
|
|
||||||
const Token: AnsiString;
|
|
||||||
CharsBefore, TokenLen: integer;
|
|
||||||
Foreground, Background: TColor;
|
|
||||||
Style: TFontStyles);
|
|
||||||
var
|
|
||||||
bCanAppend: boolean;
|
|
||||||
bSpacesTest, bIsSpaces: boolean;
|
|
||||||
i: integer;
|
|
||||||
|
|
||||||
function TokenIsSpaces: boolean;
|
|
||||||
var
|
|
||||||
pTok: PChar;
|
|
||||||
begin
|
|
||||||
if not bSpacesTest then begin
|
|
||||||
bSpacesTest := TRUE;
|
|
||||||
pTok := PChar(Token);
|
|
||||||
while (pTok^ <> #0) do begin
|
|
||||||
if (pTok^ <> ' ') then break;
|
|
||||||
Inc(pTok);
|
|
||||||
end;
|
|
||||||
bIsSpaces := (pTok^ = #0);
|
|
||||||
end;
|
|
||||||
Result := bIsSpaces;
|
|
||||||
end;
|
|
||||||
|
|
||||||
begin
|
|
||||||
if Background = clNone then Background := colEditorBG;
|
|
||||||
if Foreground = clNone then Foreground := Font.Color;
|
|
||||||
// Do we have to paint the old chars first, or can we just append?
|
|
||||||
bCanAppend := FALSE;
|
|
||||||
bSpacesTest := FALSE;
|
|
||||||
if (TokenAccu.Len > 0) then begin
|
|
||||||
// font style must be the same or token is only spaces
|
|
||||||
if (TokenAccu.Style = Style)
|
|
||||||
or (not (fsUnderline in Style) and not (fsUnderline in TokenAccu.Style)
|
|
||||||
and TokenIsSpaces)
|
|
||||||
then
|
|
||||||
// either special colors or same colors
|
|
||||||
if bSpecialLine or bLineSelected or
|
|
||||||
// background color must be the same and
|
|
||||||
((TokenAccu.BG = Background) and
|
|
||||||
// foreground color must be the same or token is only spaces
|
|
||||||
((TokenAccu.FG = Foreground) or TokenIsSpaces))
|
|
||||||
then
|
|
||||||
bCanAppend := TRUE;
|
|
||||||
// If we can't append it, then we have to paint the old token chars first.
|
|
||||||
if not bCanAppend then
|
|
||||||
PaintHighlightToken(FALSE);
|
|
||||||
end;
|
|
||||||
// Don't use AppendStr because it's more expensive.
|
|
||||||
if bCanAppend then begin
|
|
||||||
if (TokenAccu.Len + TokenLen > TokenAccu.MaxLen) then begin
|
|
||||||
TokenAccu.MaxLen := TokenAccu.Len + TokenLen + 32;
|
|
||||||
SetLength(TokenAccu.s, TokenAccu.MaxLen);
|
|
||||||
end;
|
|
||||||
for i := 1 to TokenLen do begin
|
|
||||||
TokenAccu.s[TokenAccu.Len + i] := Token[i];
|
|
||||||
end;
|
|
||||||
Inc(TokenAccu.Len, TokenLen);
|
|
||||||
end else begin
|
|
||||||
TokenAccu.Len := TokenLen;
|
|
||||||
if (TokenAccu.Len > TokenAccu.MaxLen) then begin
|
|
||||||
TokenAccu.MaxLen := TokenAccu.Len + 32;
|
|
||||||
SetLength(TokenAccu.s, TokenAccu.MaxLen);
|
|
||||||
end;
|
|
||||||
for i := 1 to TokenLen do begin
|
|
||||||
TokenAccu.s[i] := Token[i];
|
|
||||||
end;
|
|
||||||
TokenAccu.CharsBefore := CharsBefore;
|
|
||||||
TokenAccu.FG := Foreground;
|
|
||||||
TokenAccu.BG := Background;
|
|
||||||
TokenAccu.Style := Style;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure PaintLines;
|
|
||||||
var
|
|
||||||
nLine: integer; // line index for the loop
|
|
||||||
sLine: string; // the current line (expanded)
|
|
||||||
// pConvert: TConvertTabsProc; //mh 2000-10-19
|
|
||||||
sToken: string; // highlighter token info
|
|
||||||
nTokenPos, nTokenLen: integer;
|
|
||||||
attr: TSynHighlighterAttributes;
|
|
||||||
begin
|
|
||||||
// Initialize rcLine for drawing. Note that Top and Bottom are updated
|
|
||||||
// inside the loop. Get only the starting point for this.
|
|
||||||
rcLine := AClip;
|
|
||||||
rcLine.Bottom := (FirstLine - TopLine) * fTextHeight;
|
|
||||||
// Make sure the token accumulator string doesn't get reassigned to often.
|
|
||||||
if Assigned(fHighlighter) then begin
|
|
||||||
TokenAccu.MaxLen := Max(128, fCharsInWindow);
|
|
||||||
SetLength(TokenAccu.s, TokenAccu.MaxLen);
|
|
||||||
end;
|
|
||||||
{begin} //mh 2000-10-19
|
|
||||||
// Find the fastest function for the tab expansion.
|
|
||||||
// pConvert := GetBestConvertTabsProc(fTabWidth);
|
|
||||||
// Now loop through all the lines. The indices are valid for Lines.
|
|
||||||
for nLine := FirstLine to LastLine do begin
|
|
||||||
// Get the expanded line.
|
|
||||||
// sLine := pConvert(Lines[nLine - 1], fTabWidth);
|
|
||||||
sLine := TSynEditStringList(Lines).ExpandedStrings[nLine - 1];
|
|
||||||
{end} //mh 2000-10-19
|
|
||||||
// Get the information about the line selection. Three different parts
|
|
||||||
// are possible (unselected before, selected, unselected after), only
|
|
||||||
// unselected or only selected means bComplexLine will be FALSE. Start
|
|
||||||
// with no selection, compute based on the visible columns.
|
|
||||||
bComplexLine := FALSE;
|
|
||||||
nSelStart := 0;
|
|
||||||
nSelEnd := 0;
|
|
||||||
// Does the selection intersect the visible area?
|
|
||||||
if bAnySelection and (nLine >= nSelL1) and (nLine <= nSelL2) then begin
|
|
||||||
// Default to a fully selected line. This is correct for the smLine
|
|
||||||
// selection mode and a good start for the smNormal mode.
|
|
||||||
nSelStart := FirstCol;
|
|
||||||
nSelEnd := LastCol + 1;
|
|
||||||
if (SelectionMode = smColumn) or
|
|
||||||
((SelectionMode = smNormal) and (nLine = nSelL1))
|
|
||||||
then
|
|
||||||
if (nSelCol1 > LastCol) then begin
|
|
||||||
nSelStart := 0;
|
|
||||||
nSelEnd := 0;
|
|
||||||
end else if (nSelCol1 > FirstCol) then begin
|
|
||||||
nSelStart := nSelCol1;
|
|
||||||
bComplexLine := TRUE;
|
|
||||||
end;
|
|
||||||
if (SelectionMode = smColumn) or
|
|
||||||
((SelectionMode = smNormal) and (nLine = nSelL2))
|
|
||||||
then
|
|
||||||
if (nSelCol2 < FirstCol) then begin
|
|
||||||
nSelStart := 0;
|
|
||||||
nSelEnd := 0;
|
|
||||||
end else if (nSelCol2 < LastCol) then begin
|
|
||||||
nSelEnd := nSelCol2;
|
|
||||||
bComplexLine := TRUE;
|
|
||||||
end;
|
|
||||||
{$IFDEF SYN_MBCSSUPPORT}
|
|
||||||
if (SelectionMode = smColumn) then
|
|
||||||
MBCSGetSelRangeInLineWhenColumnSelectionMode(sLine, nSelStart,
|
|
||||||
nSelEnd);
|
|
||||||
{$ENDIF}
|
|
||||||
end;
|
|
||||||
// Update the rcLine rect to this line.
|
|
||||||
rcLine.Top := rcLine.Bottom;
|
|
||||||
Inc(rcLine.Bottom, fTextHeight);
|
|
||||||
// Initialize the text and background colors, maybe the line should
|
|
||||||
// use special values for them.
|
|
||||||
colFG := Font.Color;
|
|
||||||
colBG := colEditorBG;
|
|
||||||
bSpecialLine := DoOnSpecialLineColors(nLine, colFG, colBG);
|
|
||||||
if bSpecialLine then begin
|
|
||||||
// The selection colors are just swapped, like seen in Delphi.
|
|
||||||
colSelFG := colBG;
|
|
||||||
colSelBG := colFG;
|
|
||||||
end else begin
|
|
||||||
colSelFG := fSelectedColor.Foreground;
|
|
||||||
colSelBG := fSelectedColor.Background;
|
|
||||||
end;
|
|
||||||
// Paint the lines depending on the assigned highlighter.
|
|
||||||
bLineSelected := not bComplexLine and (nSelStart > 0);
|
|
||||||
rcToken := rcLine;
|
|
||||||
if not Assigned(fHighlighter) then begin
|
|
||||||
// Note: The PaintToken procedure will take care of invalid parameters
|
|
||||||
// like empty token rect or invalid indices into sLine.
|
|
||||||
nTokenLen := Length(sLine);
|
|
||||||
if bComplexLine then begin
|
|
||||||
SetDrawingColors(FALSE);
|
|
||||||
rcToken.Left := Max(rcLine.Left, ColumnToXValue(FirstCol));
|
|
||||||
rcToken.Right := Min(rcLine.Right, ColumnToXValue(nSelStart));
|
|
||||||
PaintToken(sLine, nTokenLen, 0, FirstCol, nSelStart);
|
|
||||||
rcToken.Left := Max(rcLine.Left, ColumnToXValue(nSelEnd));
|
|
||||||
rcToken.Right := Min(rcLine.Right, ColumnToXValue(LastCol));
|
|
||||||
PaintToken(sLine, nTokenLen, 0, nSelEnd, LastCol);
|
|
||||||
SetDrawingColors(TRUE);
|
|
||||||
rcToken.Left := Max(rcLine.Left, ColumnToXValue(nSelStart));
|
|
||||||
rcToken.Right := Min(rcLine.Right, ColumnToXValue(nSelEnd));
|
|
||||||
PaintToken(sLine, nTokenLen, 0, nSelStart, nSelEnd);
|
|
||||||
end else begin
|
|
||||||
SetDrawingColors(bLineSelected);
|
|
||||||
PaintToken(sLine, nTokenLen, 0, FirstCol, LastCol);
|
|
||||||
end;
|
|
||||||
end else begin
|
|
||||||
// Initialize highlighter with line text and range info. It is
|
|
||||||
// necessary because we probably did not scan to the end of the last
|
|
||||||
// line - the internal highlighter range might be wrong.
|
|
||||||
// fHighlighter.SetRange(Lines.Objects[nLine - 1]);
|
|
||||||
fHighlighter.SetRange(TSynEditStringList(Lines).Ranges[nLine - 1]); //mh 2000-10-10
|
|
||||||
fHighlighter.SetLine(sLine, nLine - 1);
|
|
||||||
// Try to concatenate as many tokens as possible to minimize the count
|
|
||||||
// of ExtTextOut calls necessary. This depends on the selection state
|
|
||||||
// or the line having special colors. For spaces the foreground color
|
|
||||||
// is ignored as well.
|
|
||||||
TokenAccu.Len := 0;
|
|
||||||
while not fHighlighter.GetEol do begin
|
|
||||||
// Test first whether anything of this token is visible.
|
|
||||||
nTokenPos := fHighlighter.GetTokenPos; // zero-based
|
|
||||||
sToken := fHighlighter.GetToken;
|
|
||||||
nTokenLen := Length(sToken);
|
|
||||||
if (nTokenPos + nTokenLen >= FirstCol) then begin
|
|
||||||
// It's at least partially visible. Get the token attributes now.
|
|
||||||
attr := fHighlighter.GetTokenAttribute;
|
|
||||||
// Store the token chars with the attributes in the TokenAccu
|
|
||||||
// record. This will paint any chars already stored if there is
|
|
||||||
// a (visible) change in the attributes.
|
|
||||||
if Assigned(attr) then
|
|
||||||
AddHighlightToken(sToken, nTokenPos, nTokenLen, attr.Foreground,
|
|
||||||
attr.Background, attr.Style)
|
|
||||||
else
|
|
||||||
AddHighlightToken(sToken, nTokenPos, nTokenLen, colFG, colBG,
|
|
||||||
Font.Style);
|
|
||||||
end;
|
|
||||||
// Let the highlighter scan the next token.
|
|
||||||
fHighlighter.Next;
|
|
||||||
end;
|
|
||||||
// Draw anything that's left in the TokenAccu record. Fill to the end
|
|
||||||
// of the invalid area with the correct colors.
|
|
||||||
PaintHighlightToken(TRUE);
|
|
||||||
end;
|
|
||||||
// Now paint the right edge if necessary. We do it line by line to reduce
|
|
||||||
// the flicker. Should not cost very much anyway, compared to the many
|
|
||||||
// calls to ExtTextOut.
|
|
||||||
if bDoRightEdge then begin
|
|
||||||
Windows.MoveToEx(dc, nRightEdge, rcLine.Top, nil);
|
|
||||||
Windows.LineTo(dc, nRightEdge, rcLine.Bottom + 1);
|
|
||||||
//codefold draw splitter line
|
|
||||||
ypos := rcToken.Bottom - 1;
|
|
||||||
nLine := PixelsToRowColumn(Point(0, ypos)).Y;
|
|
||||||
if TSynEditStringList(Lines).FoldType[nLine] in [cfEnd] then
|
|
||||||
begin
|
|
||||||
Windows.MoveToEx(dc, nRightEdge, ypos, nil);
|
|
||||||
Windows.LineTo(dc, fGutterWidth, ypos);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
{ end local procedures }
|
|
||||||
|
|
||||||
begin
|
|
||||||
colEditorBG := Color;
|
|
||||||
if Assigned(Highlighter) and Assigned(Highlighter.WhitespaceAttribute) then
|
|
||||||
begin
|
|
||||||
colBG := Highlighter.WhitespaceAttribute.Background;
|
|
||||||
if colBG <> clNone then
|
|
||||||
colEditorBG := colBG;
|
|
||||||
end;
|
|
||||||
// If the right edge is visible and in the invalid area, prepare to paint it.
|
|
||||||
// Do this first to realize the pen when getting the dc variable.
|
|
||||||
bDoRightEdge := FALSE;
|
|
||||||
if (fRightEdge > 0) then begin // column value
|
|
||||||
nRightEdge := fTextOffset + fRightEdge * fCharWidth; // pixel value
|
|
||||||
if (nRightEdge >= AClip.Left) and (nRightEdge <= AClip.Right) then begin
|
|
||||||
bDoRightEdge := TRUE;
|
|
||||||
Canvas.Pen.Color := fRightEdgeColor;
|
|
||||||
Canvas.Pen.Width := 1;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
// Do everything else with API calls. This (maybe) realizes the new pen color.
|
|
||||||
dc := Canvas.Handle;
|
|
||||||
|
|
||||||
// If anything of the two pixel space before the text area is visible, then
|
|
||||||
// fill it with the component background color.
|
|
||||||
if (AClip.Left < fGutterWidth + 2) then begin
|
|
||||||
rcToken := AClip;
|
|
||||||
rcToken.Left := Max(AClip.Left, fGutterWidth);
|
|
||||||
rcToken.Right := fGutterWidth + 2;
|
|
||||||
SetBkColor(dc,ColorToRGB(colEditorBG));
|
|
||||||
InternalFillRect(dc, rcToken);
|
|
||||||
// Adjust the invalid area to not include this area.
|
|
||||||
AClip.Left := rcToken.Right;
|
|
||||||
end;
|
|
||||||
if (LastLine >= FirstLine) then begin
|
|
||||||
// Paint the visible text lines. To make this easier, compute first the
|
|
||||||
// necessary information about the selected area: is there any visible
|
|
||||||
// selected area, and what are its lines / columns?
|
|
||||||
// Moved to two local procedures to make it easier to read.
|
|
||||||
ComputeSelectionInfo;
|
|
||||||
fTextDrawer.Style := Font.Style;
|
|
||||||
fTextDrawer.BeginDrawing(dc);
|
|
||||||
try
|
|
||||||
PaintLines;
|
|
||||||
finally
|
|
||||||
fTextDrawer.EndDrawing;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
// If there is anything visible below the last line, then fill this as well.
|
|
||||||
rcToken := AClip;
|
|
||||||
rcToken.Top := (LastLine - TopLine + 1) * fTextHeight;
|
|
||||||
if (rcToken.Top < rcToken.Bottom) then begin
|
|
||||||
SetBkColor(dc, ColorToRGB(colEditorBG));
|
|
||||||
InternalFillRect(dc, rcToken);
|
|
||||||
// Draw the right edge if necessary.
|
|
||||||
if bDoRightEdge and (not (eoHideRightMargin in Options)) then begin
|
|
||||||
Windows.MoveToEx(dc, nRightEdge, rcToken.Top, nil);
|
|
||||||
Windows.LineTo(dc, nRightEdge, rcToken.Bottom + 1);
|
|
||||||
|
|
||||||
//codefold draw splitter line
|
|
||||||
ypos := rcToken.Bottom - 1;
|
|
||||||
nLine := PixelsToRowColumn(Point(0, ypos)).Y;
|
|
||||||
if TSynEditStringList(Lines).FoldType[nLine] in [cfEnd] then
|
|
||||||
begin
|
|
||||||
Windows.MoveToEx(dc, nRightEdge, ypos, nil);
|
|
||||||
Windows.LineTo(dc, fGutterWidth, ypos);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
{$ENDIF not SYN_LAZARUS}
|
|
||||||
|
|
||||||
{$IFDEF SYN_LAZARUS}
|
{$IFDEF SYN_LAZARUS}
|
||||||
procedure TCustomSynEdit.StartPaintBuffer(const ClipRect: TRect);
|
procedure TCustomSynEdit.StartPaintBuffer(const ClipRect: TRect);
|
||||||
|
|||||||
@ -202,10 +202,7 @@ type
|
|||||||
AHandler: TStringListLineCountEvent); override;
|
AHandler: TStringListLineCountEvent); override;
|
||||||
public
|
public
|
||||||
property DosFileFormat: boolean read fDosFileFormat write fDosFileFormat;
|
property DosFileFormat: boolean read fDosFileFormat write fDosFileFormat;
|
||||||
{begin} //mh 2000-10-19
|
|
||||||
property ExpandedStrings[Index: integer]: string read GetExpandedString;
|
|
||||||
property LengthOfLongestLine: integer read GetLengthOfLongestLine;
|
property LengthOfLongestLine: integer read GetLengthOfLongestLine;
|
||||||
{end} //mh 2000-10-19
|
|
||||||
property Ranges[Index: integer]: TSynEditRange read GetRange write PutRange;
|
property Ranges[Index: integer]: TSynEditRange read GetRange write PutRange;
|
||||||
property OnChange: TNotifyEvent read fOnChange write fOnChange;
|
property OnChange: TNotifyEvent read fOnChange write fOnChange;
|
||||||
property OnChanging: TNotifyEvent read fOnChanging write fOnChanging;
|
property OnChanging: TNotifyEvent read fOnChanging write fOnChanging;
|
||||||
|
|||||||
@ -60,7 +60,6 @@ TSynEditStringTabExpander = class(TSynEditStringsLinked)
|
|||||||
constructor Create(ASynStringSource: TSynEditStrings);
|
constructor Create(ASynStringSource: TSynEditStrings);
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
|
|
||||||
property ExpandedStrings[Index: integer]: string read GetExpandedString;
|
|
||||||
property LengthOfLongestLine: integer read GetLengthOfLongestLine;
|
property LengthOfLongestLine: integer read GetLengthOfLongestLine;
|
||||||
|
|
||||||
// TODO: maybe use inherited for utf8?
|
// TODO: maybe use inherited for utf8?
|
||||||
|
|||||||
@ -78,7 +78,6 @@ type
|
|||||||
procedure InsertLines(Index, NumLines: integer); override;
|
procedure InsertLines(Index, NumLines: integer); override;
|
||||||
procedure InsertStrings(Index: integer; NewStrings: TStrings); override;
|
procedure InsertStrings(Index: integer; NewStrings: TStrings); override;
|
||||||
procedure Exchange(Index1, Index2: integer); override;
|
procedure Exchange(Index1, Index2: integer); override;
|
||||||
property ExpandedStrings[Index: integer]: string read GetExpandedString;
|
|
||||||
property LengthOfLongestLine: integer read GetLengthOfLongestLine;
|
property LengthOfLongestLine: integer read GetLengthOfLongestLine;
|
||||||
public
|
public
|
||||||
procedure Lock;
|
procedure Lock;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user