mirror of
https://github.com/doublecmd/doublecmd.git
synced 2026-06-21 09:58:13 +00:00
113 lines
2.9 KiB
ObjectPascal
113 lines
2.9 KiB
ObjectPascal
unit uBinaryDiffViewer;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, Graphics, ViewerControl;
|
|
|
|
type
|
|
|
|
{ TBinaryDiffViewer }
|
|
|
|
TBinaryDiffViewer = class(TViewerControl)
|
|
private
|
|
FSecondViewer: TBinaryDiffViewer;
|
|
protected
|
|
procedure WriteHex; override;
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
property SecondViewer: TBinaryDiffViewer read FSecondViewer write FSecondViewer;
|
|
end;
|
|
|
|
implementation
|
|
|
|
uses
|
|
Math;
|
|
|
|
const
|
|
cHexWidth = 16;
|
|
cHexOffsetWidth = 8;
|
|
cHexStartHex = cHexOffsetWidth + 2; // ': '
|
|
cHexStartAscii = cHexStartHex + (cHexWidth * 3) + 2; // ' '
|
|
|
|
{ TBinaryDiffViewer }
|
|
|
|
procedure TBinaryDiffViewer.WriteHex;
|
|
const
|
|
cWordSize = 3;
|
|
var
|
|
I: Integer;
|
|
X, Y: Integer;
|
|
yIndex: Integer;
|
|
P1, P2: PAnsiChar;
|
|
CurrentPos, LineStart: PtrInt;
|
|
Mine, Foreign, WordHex: String;
|
|
WordWidth, SymbolWidth: Integer;
|
|
MineLength, ForeignLength: Integer;
|
|
SymbolColor: array[0..15] of TColor;
|
|
begin
|
|
CurrentPos := Position;
|
|
SymbolWidth := Canvas.TextWidth('W');
|
|
WordWidth := SymbolWidth * cWordSize;
|
|
// Draw visible lines
|
|
for yIndex := 0 to GetClientHeightInLines - 1 do
|
|
begin
|
|
if CurrentPos >= FHighLimit then
|
|
Break;
|
|
// Draw if second viewer exists
|
|
if Assigned(SecondViewer) then
|
|
begin
|
|
X := 0;
|
|
Y := yIndex * FTextHeight;
|
|
LineStart := CurrentPos;
|
|
AddLineOffset(CurrentPos);
|
|
// Mine text
|
|
Mine := TransformHex(CurrentPos, FHighLimit);
|
|
MineLength:= Min(cHexWidth, (Length(Mine) - cHexStartHex) div cWordSize);
|
|
// Foreign text
|
|
Foreign := SecondViewer.TransformHex(LineStart, SecondViewer.FHighLimit);
|
|
ForeignLength:= (Length(Foreign) - cHexStartHex) div cWordSize;
|
|
// Pointers to text
|
|
P1 := PAnsiChar(Mine) + cHexStartHex;
|
|
P2 := PAnsiChar(Foreign) + cHexStartHex;
|
|
// Write line number
|
|
Canvas.TextOut(X, Y, Copy(Mine, 1, cHexStartHex));
|
|
X := X + SymbolWidth * cHexStartHex;
|
|
// Write hex part
|
|
for I := 0 to MineLength - 1 do
|
|
begin
|
|
if (I > ForeignLength) or (PWord(P1)^ <> PWord(P2)^) then
|
|
Canvas.Font.Color := clRed
|
|
else
|
|
Canvas.Font.Color := clBlack;
|
|
SymbolColor[I]:= Canvas.Font.Color;
|
|
WordHex:= Copy(P1, 1, cWordSize);
|
|
Canvas.TextOut(X, Y, WordHex);
|
|
Inc(X, WordWidth);
|
|
Inc(P1, cWordSize);
|
|
Inc(P2, cWordSize)
|
|
end;
|
|
Inc(X, SymbolWidth);
|
|
// Write ASCII part
|
|
WordHex:= Copy(Mine, cHexStartAscii + 1, cHexWidth);
|
|
for I:= 1 to Length(WordHex) do
|
|
begin
|
|
Canvas.Font.Color := SymbolColor[I - 1];
|
|
Canvas.TextOut(X, Y, WordHex[I]);
|
|
Inc(X, SymbolWidth);
|
|
end;
|
|
Canvas.Font.Color := clBlack
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
constructor TBinaryDiffViewer.Create(AOwner: TComponent);
|
|
begin
|
|
inherited Create(AOwner);
|
|
ViewerMode:= vmHex;
|
|
end;
|
|
|
|
end.
|
|
|