SynEdit: Change the order in which lines, frames and text is drawn. Fixes issue #13436

git-svn-id: trunk@19224 -
This commit is contained in:
martin 2009-04-04 23:51:31 +00:00
parent 186237311f
commit 7ee15b0d8e
2 changed files with 78 additions and 83 deletions

View File

@ -2932,19 +2932,19 @@ var
if bDoRightEdge and (not (eoHideRightMargin in Options))
and (nRightEdge<rcToken.Right) and (nRightEdge>=rcToken.Left)
then begin
// draw background
// draw background (use rcToken, so we do not delete the divider-draw-line)
InternalFillRect(dc,rcToken);
// draw edge
LCLIntf.MoveToEx(dc, nRightEdge, rcToken.Top, nil);
LCLIntf.LineTo(dc, nRightEdge, rcToken.Bottom + 1);
// draw edge (use rcLine / rcToken may be reduced)
LCLIntf.MoveToEx(dc, nRightEdge, rcLine.Top, nil);
LCLIntf.LineTo(dc, nRightEdge, rcLine.Bottom + 1);
// draw text
fTextDrawer.ExtTextOut(nX, rcToken.Top, ETOOptions-ETO_OPAQUE, rcToken,
Token, TokenLen);
Token, TokenLen, rcLine.Bottom);
end else begin
// draw text with background
//debugln('PaintToken nX=',dbgs(nX),' Token=',dbgstr(copy(Token,1, TokenLen)),' rcToken=',dbgs(rcToken));
fTextDrawer.ExtTextOut(nX, rcToken.Top, ETOOptions, rcToken,
Token, TokenLen);
Token, TokenLen, rcLine.Bottom);
end;
rcToken.Left := rcToken.Right;
end;
@ -3013,8 +3013,8 @@ var
// Draw the right edge if necessary.
if bDoRightEdge and (not (eoHideRightMargin in Options))
and (nRightEdge >= eolx) then begin // xx rc Token
LCLIntf.MoveToEx(dc, nRightEdge, rcToken.Top, nil);
LCLIntf.LineTo(dc, nRightEdge, rcToken.Bottom + 1);
LCLIntf.MoveToEx(dc, nRightEdge, rcLine.Top, nil);
LCLIntf.LineTo(dc, nRightEdge, rcLine.Bottom + 1);
end;
if FFoldedLinesView.FoldType[CurLine] = cfCollapsed then
@ -3051,7 +3051,7 @@ var
rcToken.Right := Min(rcToken.Right, rcLine.Right);
if rcToken.Right > rcToken.Left then
fTextDrawer.ExtTextOut(rcToken.Left, rcToken.Top, ETOOptions-ETO_OPAQUE,
rcToken, '...', 3);
rcToken, '...', 3, rcLine.Bottom);
end;
end;
@ -3333,7 +3333,17 @@ var
if not Assigned(fHighlighter) then begin
DrawHiLightMarkupToken(nil, PChar(Pointer(sLine)), Length(sLine));
end else begin
fHighlighter.CurrentLines := FTheLinesView;
// draw splitter line
DividerInfo := fHighlighter.DrawDivider[CurTextIndex];
if DividerInfo.Color <> clNone then
begin
ypos := rcToken.Bottom - 1;
cl := DividerInfo.Color;
if cl = clDefault then
cl := fRightEdgeColor;
fTextDrawer.DrawLine(nRightEdge, ypos, fGutterWidth - 1, ypos, cl);
dec(rcToken.Bottom);
end;
// 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.
@ -3359,19 +3369,6 @@ var
PaintHighlightToken(TRUE);
fMarkupManager.FinishMarkupForRow(FFoldedLinesView.TextIndex[CurLine]+1);
// draw splitter line
if Assigned(fHighlighter) then begin
DividerInfo := fHighlighter.DrawDivider[CurTextIndex];
if DividerInfo.Color <> clNone then
begin
ypos := rcToken.Bottom - 1;
cl := DividerInfo.Color;
if cl = clDefault then
cl := fRightEdgeColor;
fTextDrawer.DrawLine(nRightEdge, ypos, fGutterWidth - 1, ypos, cl);
end;
end;
end;
CurLine:=-1;
end;
@ -3410,11 +3407,14 @@ begin
FillChar(TokenAccu,SizeOf(TokenAccu),0);
//DebugLn('TCustomSynEdit.PaintTextLines ',DbgSName(Self),' TopLine=',dbgs(TopLine),' AClip=',dbgs(AClip));
colEditorBG := Color;
if Assigned(Highlighter) and Assigned(Highlighter.WhitespaceAttribute) then
begin
colBG := Highlighter.WhitespaceAttribute.Background;
if colBG <> clNone then
colEditorBG := colBG;
if Assigned(fHighlighter) then begin
fHighlighter.CurrentLines := FTheLinesView;
if Assigned(Highlighter.WhitespaceAttribute) then
begin
colBG := Highlighter.WhitespaceAttribute.Background;
if colBG <> clNone then
colEditorBG := colBG;
end;
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.
@ -3431,17 +3431,14 @@ begin
dc := Canvas.Handle;
SetBkMode(dc, TRANSPARENT);
// 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,colEditorBG);
InternalFillRect(dc, rcToken);
// Adjust the invalid area to not include this area.
AClip.Left := rcToken.Right;
end;
// Delete the whole area
SetBkColor(dc, ColorToRGB(colEditorBG));
InternalFillRect(dc, AClip);
// Adjust the invalid area to not include the gutter (nor the 2 ixel offset to the guttter).
if (AClip.Left < fGutterWidth + 2) then
AClip.Left := fGutterWidth + 2;
if (LastLine >= FirstLine) then begin
CalculateCtrlMouseLink;
// Paint the visible text lines. To make this easier, compute first the
@ -3457,17 +3454,12 @@ begin
end;
end;
// If there is anything visible below the last line, then fill this as well.
rcToken := AClip;
rcToken.Top := (LastLine+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
LCLIntf.MoveToEx(dc, nRightEdge, rcToken.Top, nil);
LCLIntf.LineTo(dc, nRightEdge, rcToken.Bottom + 1);
end;
// Draw the right edge if necessary.
AClip.Top := (LastLine+1) * fTextHeight;
if (AClip.Top < AClip.Bottom) and bDoRightEdge and
(not (eoHideRightMargin in Options)) then begin
LCLIntf.MoveToEx(dc, nRightEdge, AClip.Top, nil);
LCLIntf.LineTo(dc, nRightEdge, AClip.Bottom + 1);
end;
fMarkupManager.EndMarkup;

View File

@ -238,7 +238,7 @@ type
procedure EndDrawing; virtual;
procedure TextOut(X, Y: Integer; Text: PChar; Length: Integer); virtual;
procedure ExtTextOut(X, Y: Integer; fuOptions: UINT; const ARect: TRect;
Text: PChar; Length: Integer); virtual;
Text: PChar; Length: Integer; FrameBottom: Integer = -1); virtual;
procedure DrawLine(X, Y, X2, Y2: Integer; AColor: TColor);
procedure SetBaseFont(Value: TFont); virtual;
procedure SetBaseStyle(const Value: TFontStyles); virtual;
@ -290,7 +290,7 @@ type
const ARect: TRect; Text: PChar; Length: Integer); virtual;
public
procedure ExtTextOut(X, Y: Integer; fuOptions: UINT; const ARect: TRect;
Text: PChar; Length: Integer); override;
Text: PChar; Length: Integer; FrameBottom: Integer = -1); override;
end;
function GetFontsInfoManager: TheFontsInfoManager;
@ -1094,7 +1094,7 @@ begin
end;
procedure TheTextDrawer.ExtTextOut(X, Y: Integer; fuOptions: UINT;
const ARect: TRect; Text: PChar; Length: Integer);
const ARect: TRect; Text: PChar; Length: Integer; FrameBottom: Integer = -1);
procedure InitETODist(InitValue: Integer);
const
@ -1127,7 +1127,38 @@ var
Pen, OldPen: HPen;
old : TPoint;
begin
{$IFDEF SYN_LAZARUS}
if FFrameColor <> clNone then
begin
// draw background // TODO: only if not default bg color
InternalFillRect(FDC, ARect);
if FrameBottom < 0 then
FrameBottom := ARect.Bottom;
Pen := CreateColorPen(FFrameColor);
OldPen := SelectObject(FDC, Pen);
MoveToEx(FDC, ARect.Left, ARect.Top, @old);
if ARect.Right = FFrameEndX then begin
LineTo(FDC, ARect.Right-1, ARect.Top);
LineTo(FDC, ARect.Right-1, FrameBottom-1);
end else begin
// Last point of the line may not be drawn, so paint one more
LineTo(FDC, ARect.Right, ARect.Top);
MoveToEx(FDC, ARect.Right-1, FrameBottom-1, @old);
end;
if ARect.Left = FFrameStartX then begin
LineTo(FDC, ARect.Left, FrameBottom-1);
LineTo(FDC, ARect.Left, ARect.Top);
end else begin
MoveToEx(FDC, ARect.Left, FrameBottom-1, @old);
LineTo(FDC, ARect.Right, FrameBottom-1);
end;
DeleteObject(SelectObject(FDC, OldPen));
if (fuOptions and ETO_OPAQUE) > 0 then
fuOptions := fuOptions - ETO_OPAQUE;
fuOptions := 0;
end;
NeedDistArray:= (FCharExtra > 0) or (not MonoSpace)
or (not FFontStock.MonoSpace) or (FBaseCharWidth <> FFontStock.CharAdvance);
//DebugLn(['TheTextDrawer.ExtTextOut NeedDistArray=',NeedDistArray]);
@ -1142,34 +1173,6 @@ begin
LCLIntf.ExtUTF8Out(FDC, X, Y, fuOptions, @ARect, Text, Length, DistArray)
else
LCLIntf.ExtTextOut(FDC, X, Y, fuOptions, @ARect, Text, Length, DistArray);
{$ELSE}
if FETOSizeInChar < Length then
InitETODist(GetCharWidth);
Windows.ExtTextOut(FDC, X, Y, fuOptions, @ARect, Text,
Length, PInteger(FETODist));
{$ENDIF}
if FFrameColor <> clNone then
begin
Pen := CreateColorPen(FFrameColor);
OldPen := SelectObject(FDC, Pen);
MoveToEx(FDC, ARect.Left, ARect.Top, @old);
if ARect.Right = FFrameEndX then begin
LineTo(FDC, ARect.Right-1, ARect.Top);
LineTo(FDC, ARect.Right-1, ARect.Bottom-1);
end else begin
// Last point of the line may not be drawn, so paint one more
LineTo(FDC, ARect.Right, ARect.Top);
MoveToEx(FDC, ARect.Right-1, ARect.Bottom-1, @old);
end;
if ARect.Left = FFrameStartX then begin
LineTo(FDC, ARect.Left, ARect.Bottom-1);
LineTo(FDC, ARect.Left, ARect.Top);
end else begin
MoveToEx(FDC, ARect.Left, ARect.Bottom-1, @old);
LineTo(FDC, ARect.Right, ARect.Bottom-1);
end;
DeleteObject(SelectObject(FDC, OldPen));
end;
end;
procedure TheTextDrawer.DrawLine(X, Y, X2, Y2: Integer; AColor: TColor);
@ -1233,7 +1236,7 @@ end;
{$ENDIF}
procedure TheTextDrawerEx.ExtTextOut(X, Y: Integer; fuOptions: UINT;
const ARect: TRect; Text: PChar; Length: Integer);
const ARect: TRect; Text: PChar; Length: Integer; FrameBottom: Integer = -1);
begin
FExtTextOutProc(X, Y, fuOptions, ARect, Text, Length);
end;