doublecmd/src/ubinarydiffviewer.pas
2014-01-07 22:48:37 +00:00

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.