summaryrefslogtreecommitdiff
path: root/docview/components/richtext
diff options
context:
space:
mode:
authorGraeme Geldenhuys <graeme@mastermaths.co.za>2011-07-23 22:40:34 +0200
committerGraeme Geldenhuys <graeme@mastermaths.co.za>2011-07-23 22:40:34 +0200
commitd2d9660e01e653f62f15d73e52f5b92470863acd (patch)
tree9afbe5710021192a42081f195a0c9da2286f6656 /docview/components/richtext
parent26b9f1e9a89abbf0678812b4c421ee8e5399b6b8 (diff)
downloadfpGUI-d2d9660e01e653f62f15d73e52f5b92470863acd.tar.xz
TRichTextLayout & TLayoutLine code reworked to classes instead of arrays
- TLayoutLine changed from a record type to a data class - Implemented TLayoutLineList class instead of using a dynamic array for TLayoutLine storage. - Changed all related code to reference the object list correctly.
Diffstat (limited to 'docview/components/richtext')
-rw-r--r--docview/components/richtext/RichTextDisplayUnit.pas2
-rw-r--r--docview/components/richtext/RichTextLayoutUnit.pas135
-rw-r--r--docview/components/richtext/RichTextView.pas53
3 files changed, 115 insertions, 75 deletions
diff --git a/docview/components/richtext/RichTextDisplayUnit.pas b/docview/components/richtext/RichTextDisplayUnit.pas
index 5f5f8ac1..67914de8 100644
--- a/docview/components/richtext/RichTextDisplayUnit.pas
+++ b/docview/components/richtext/RichTextDisplayUnit.pas
@@ -306,7 +306,7 @@ ProfileEvent('DEBUG: DrawRichTextLayout >>>');
//FontManager.Canvas.DrawLine(0, y, 300, y);
repeat
- Line := Layout.FLines^[ LineIndex ];
+ Line := Layout.FLines[LineIndex];
BottomOfLine := Y;
if // the line is in the range to be drawn
diff --git a/docview/components/richtext/RichTextLayoutUnit.pas b/docview/components/richtext/RichTextLayoutUnit.pas
index b5a324b5..004c2ef1 100644
--- a/docview/components/richtext/RichTextLayoutUnit.pas
+++ b/docview/components/richtext/RichTextLayoutUnit.pas
@@ -12,10 +12,13 @@ Uses
CanvasFontManager,
RichTextDocumentUnit,
RichTextStyleUnit,
- fpg_imagelist;
+ fpg_imagelist,
+ contnrs;
Type
- TLayoutLine = record
+
+ TLayoutLine = class(TObject)
+ public
Text: PChar;
Length: longint;
Height: longint;
@@ -28,7 +31,18 @@ Type
end;
- TLinesArray = array[ 0..0 ] of TLayoutLine;
+ TLayoutLineList = class(TObjectList)
+ protected
+ function GetItem(Index: Integer): TLayoutLine; reintroduce;
+ procedure SetItem(Index: Integer; const AValue: TLayoutLine); reintroduce;
+ public
+ function Add(AObject: TLayoutLine): Integer; reintroduce;
+ function Remove(AObject: TLayoutLine): Integer; reintroduce;
+ function IndexOf(AObject: TLayoutLine): Integer; reintroduce;
+ function First: TLayoutLine; reintroduce;
+ Function Last: TLayoutLine; reintroduce;
+ property Items[Index: Integer]: TLayoutLine read GetItem write SetItem; default;
+ end;
TTextPosition =
@@ -53,7 +67,6 @@ Type
FFontManager: TCanvasFontManager;
FText: PChar;
FImages: TfpgImageList;
- FAllocatedNumLines: Longint;
FLayoutWidth: longint; // The target width for the layout. Used for centreing/right align
FWidth: longint; // The actual width of the text. May be wider due to unaligned
// parts or bitmaps or width so small individual characters don't fit.
@@ -62,8 +75,7 @@ Type
FHorizontalImageScale: double;
FVerticalImageScale: double;
public
- // Internal layout data
- FLines: ^TLinesArray;
+ FLines: TLayoutLineList;
FNumLines: longint;
FRichTextSettings: TRichTextSettings;
// Drawing functions
@@ -116,6 +128,46 @@ Type
Implementation
+
+{ TLayoutLineList }
+
+function TLayoutLineList.GetItem(Index: Integer): TLayoutLine;
+begin
+ inherited GetItem(Index);
+end;
+
+procedure TLayoutLineList.SetItem(Index: Integer; const AValue: TLayoutLine);
+begin
+ inherited SetItem(Index, AValue);
+end;
+
+function TLayoutLineList.Add(AObject: TLayoutLine): Integer;
+begin
+ Result := inherited Add(AObject);
+end;
+
+function TLayoutLineList.Remove(AObject: TLayoutLine): Integer;
+begin
+ Result := inherited Remove(AObject);
+end;
+
+function TLayoutLineList.IndexOf(AObject: TLayoutLine): Integer;
+begin
+ Result := inherited IndexOf(AObject);
+end;
+
+function TLayoutLineList.First: TLayoutLine;
+begin
+ Result := TLayoutLine(inherited First);
+end;
+
+function TLayoutLineList.Last: TLayoutLine;
+begin
+ Result := TLayoutLine(inherited Last);
+end;
+
+
+{ TRichTextLayout }
Uses
SysUtils
,ACLStringUtility
@@ -138,9 +190,8 @@ ProfileEvent('DEBUG: TRichTextLayout.Create >>>>');
FRichTextSettings := RichTextSettings;
FImages := Images;
FText := Text;
- FAllocatedNumLines := 10;
ProfileEvent('DEBUG: TRichTextLayout.Create 1 of 4');
- GetMem( FLines, FAllocatedNumLines * sizeof( TLayoutLine ) );
+ FLines := TLayoutLineList.Create;
FNumLines := 0;
FLinks := TStringList.Create;
FLinks.Duplicates := dupIgnore;
@@ -161,41 +212,30 @@ end;
Destructor TRichTextLayout.Destroy;
Begin
- FreeMem( Flines, FAllocatedNumLines * sizeof( TLayoutLine ) );
- FLines := nil;
+ ProfileEvent('TRichTextLayout.Destroy ******* ');
+ FreeAndNil(FLines);
FLinks.Free;
- Inherited Destroy;
+ inherited Destroy;
End;
Procedure TRichTextLayout.AddLineStart(var Line: TLayoutLine);
-var
- NewAllocation: longint;
begin
- if FNumLines >= FAllocatedNumLines then
- begin
- // reallocate the array twice the size
- NewAllocation := FAllocatedNumLines * 2;
- FLines := ReAllocMem( FLines,
-// FAllocatedNumLines * sizeof( TLayoutLine ),
- NewAllocation * sizeof( TLayoutLine ) );
- FAllocatedNumLines := NewAllocation;
- end;
- FLines^[ FNumLines ] := Line;
+ FLines.Add(Line);
inc( FNumLines );
- ProfileEvent(' DEBUG: TRichTextLayout.AddLineStart: FNumLines =' + intToStr(FNumLines));
+ ProfileEvent('TRichTextLayout.AddLineStart: FNumLines =' + intToStr(FNumLines));
end;
Procedure TRichTextLayout.PerformStyleTag( Const Tag: TTag;
Var Style: TTextDrawStyle;
const X: longint );
begin
-ProfileEvent('DEBUG: TRichTextLayout.PerformStyleTag >>>');
+ProfileEvent('TRichTextLayout.PerformStyleTag >>>');
ApplyStyleTag( Tag,
Style,
FFontManager,
FRichTextSettings,
X );
-ProfileEvent('DEBUG: TRichTextLayout.PerformStyleTag <<<');
+ProfileEvent('TRichTextLayout.PerformStyleTag <<<');
end;
// Check the current font specifications and see if the
@@ -230,7 +270,7 @@ end;
// Main procedure: reads through the whole text currently stored
// and breaks up into lines - each represented as a TLayoutLine in
-// the array FLines[ 0.. FNumLines ]
+// the LayoutLineList class
Procedure TRichTextLayout.Layout;
Var
CurrentLine: TLayoutLine;
@@ -266,8 +306,10 @@ Var
CurrentLine.Width := EndX;
if CurrentLine.Width > FWidth then
FWidth := CurrentLine.Width;
- assert( CurrentLine.Height > 0 ); // we must have set the line height!
+ Assert( CurrentLine.Height > 0 ); // we must have set the line height!
AddLineStart( CurrentLine );
+
+ CurrentLine := TLayoutLine.Create;
CurrentLine.Text := NextLine;
CurrentLine.Style := Style;
CurrentLine.Height := 0;
@@ -276,6 +318,7 @@ Var
CurrentLine.Width := 0;
CurrentLine.LinkIndex := CurrentLinkIndex;
CurrentLine.Wrapped := false;
+
assert( CurrentLinkIndex >= -1 );
assert( CurrentLinkIndex < FLinks.Count );
WordStartX := Style.LeftMargin;
@@ -294,6 +337,8 @@ ProfileEvent('DEBUG: TRichTextLayout.Layout >>>>');
ApplyStyle( Style, FFontManager );
CurrentLinkIndex := -1;
P := FText; // P is the current search position
+
+ CurrentLine := TLayoutLine.Create;
CurrentLine.Text := P;
CurrentLine.Style := Style;
CurrentLine.Height := 0;
@@ -302,6 +347,7 @@ ProfileEvent('DEBUG: TRichTextLayout.Layout >>>>');
CurrentLine.Width := 0;
CurrentLine.LinkIndex := -1;
CurrentLine.Wrapped := false;
+
WordStartX := Style.LeftMargin;
WordX := 0;
WrapX := FLayoutWidth - FRichTextSettings.Margins.Right;
@@ -631,7 +677,7 @@ Var
StartedDrawing: boolean;
fstyle: string;
begin
- Line := TLayoutLine(FLines[ LineIndex ]);
+ Line := FLines[LineIndex];
P := Line.Text;
EndP := Line.Text + Line.Length;
Style := Line.Style;
@@ -731,7 +777,7 @@ Var
NewMarginX: longint;
fStyle: string;
begin
- Line := TLayoutLine(FLines[ LineIndex ]);
+ Line := FLines[LineIndex];
P := Line.Text;
EndP := Line.Text + Line.Length;
@@ -811,12 +857,13 @@ begin
if YToFind < Y then
begin
Result := tpAboveText;
- exit;
+ Exit; //==>
end;
+ // TODO: Replace FNumLines with FLines.Count-1
while LineIndex < FNumLines do
begin
- LineHeight := TLayoutLine(FLines[ LineIndex ]).Height;
+ LineHeight := FLines[LineIndex].Height;
if ( YToFind >= Y )
and ( YToFind < (Y + LineHeight)) then
begin
@@ -831,7 +878,7 @@ begin
end;
LineIndex := FNumLines - 1;
- Remainder := TLayoutLine(FLines[ LineIndex ]).Height;
+ Remainder := FLines[LineIndex].Height;
Result := tpBelowText;
end;
@@ -856,7 +903,7 @@ begin
tpBelowText:
begin
- Offset := TLayoutLine(FLines[ LineIndex ]).Length;
+ Offset := FLines[LineIndex].Length;
exit;
end;
end;
@@ -875,17 +922,16 @@ var
begin
Result := 0;
if Index <= 0 then
- exit;
+ Exit; //==>
while Result < FNumLines do
begin
- LineCharIndex := GetCharIndex( TLayoutLine(FLines[ Result ]).Text );
- LineLength := TLayoutLine(FLines[ Result ]).Length;
- if LineCharIndex + LineLength
- > Index then
+ LineCharIndex := GetCharIndex(FLines[Result].Text );
+ LineLength := FLines[Result].Length;
+ if (LineCharIndex + LineLength) > Index then
begin
// found
- exit;
+ Exit; //==>
end;
inc( Result );
end;
@@ -895,7 +941,7 @@ end;
function TRichTextLayout.GetOffsetFromCharIndex( Index: longint;
Line: longint ): longint;
begin
- Result := Index - GetCharIndex( TLayoutLine( FLines[ Line ] ).Text );
+ Result := Index - GetCharIndex(FLines[Line].Text);
end;
function TRichTextLayout.GetElementWidth( Element: TTextElement ): longint;
@@ -939,8 +985,7 @@ begin
dec( line );
while line >= 0 do
begin
- inc( Result,
- TLayoutLine(Flines[ Line ]).Height );
+ inc( Result, Flines[Line].Height );
dec( line );
end;
end;
@@ -957,12 +1002,12 @@ begin
if FNumLines = 0 then
begin
Result := '';
- exit;
+ Exit; //==>
end;
LineIndex := GetLineFromCharIndex( CharIndexToFind );
- Line := TLayoutLine(FLines[ LineIndex ]);
+ Line := FLines[LineIndex];
P := Line.Text;
EndP := Line.Text + Line.Length;
diff --git a/docview/components/richtext/RichTextView.pas b/docview/components/richtext/RichTextView.pas
index a0234468..0b183ff8 100644
--- a/docview/components/richtext/RichTextView.pas
+++ b/docview/components/richtext/RichTextView.pas
@@ -1121,7 +1121,7 @@ begin
// below the bottom
Result := tpBelowTextArea;
LineIndex := FLayout.FNumLines;
- Offset := FLayout.FLines^[ FLayout.FNumLines - 1 ].Length - 1;
+ Offset := FLayout.FLines[FLayout.FNumLines-1].Length - 1;
exit;
end;
@@ -1319,7 +1319,7 @@ begin
DrawHeight := TextRect.Top - TextRect.Bottom;
DrawWidth := TextRect.Right - TextRect.Left;
- Line := FLayout.FLines^[ CursorRow ];
+ Line := FLayout.FLines[CursorRow];
LineHeight := Line.Height;
Y := DrawHeight
@@ -1347,7 +1347,7 @@ begin
TextHeight := FFontManager.CharHeight;
Descender := FFontManager.CharDescender;
- MaxDescender := FLayout.FLines^[ CursorRow ].MaxDescender;
+ MaxDescender := FLayout.FLines[CursorRow].MaxDescender;
CursorHeight := TextHeight;
dec( Y, LineHeight - 1 );
@@ -1397,7 +1397,7 @@ begin
if LastLine = -1 then
exit;
- LineHeight := FLayout.FLines^[ LastLine ].Height;
+ LineHeight := FLayout.FLines[LastLine].Height;
if LastLine = FLayout.FNumLines - 1 then
begin
@@ -1418,7 +1418,7 @@ begin
// more than half line already displayed so
if LastLine < FLayout.FNumLines - 1 then
// AND to make next line fully visible
- inc( Result, FLayout.FLines^[ LastLine + 1 ].Height );
+ inc( Result, FLayout.FLines[LastLine+1].Height );
end;
Function TRichTextView.GetSmallDownScrollPosition: longint;
@@ -1436,7 +1436,7 @@ begin
// Now limit the scrolling to max text height for the bottom line
Diff := Result - FVScrollBar.Position;
- LineTextHeight := FLayout.FLines^[ LastLine ].MaxTextHeight;
+ LineTextHeight := FLayout.FLines[LastLine].MaxTextHeight;
if Diff > LineTextHeight then
Diff := LineTextHeight;
Result := FVScrollBar.Position + Diff;
@@ -1456,7 +1456,7 @@ begin
// Now limit the scrolling to max text height for the bottom line
Diff := FVScrollBar.Position - Result;
- LineTextHeight := FLayout.FLines^[ FirstVisibleLine ].MaxTextHeight;
+ LineTextHeight := FLayout.FLines[FirstVisibleLine].MaxTextHeight;
if Diff > LineTextHeight then
Diff := LineTextHeight;
Result := FVScrollBar.Position - Diff;
@@ -1504,11 +1504,11 @@ begin
// scroll so that top line is fully visible...
Result := FVScrollBar.Position - Offset;
- if Offset < (FLayout.FLines^[ FirstVisibleLine ].Height div 2) then
+ if Offset < (FLayout.FLines[FirstVisibleLine].Height div 2) then
// more than half the line was already displayed so
if FirstVisibleLine > 0 then
// AND to make next line up visible
- dec( Result, FLayout.FLines^[ FirstVisibleLine - 1 ].Height );
+ dec( Result, FLayout.FLines[FirstVisibleLine-1].Height );
end;
Function Sign( arg: longint ): longint;
@@ -2033,7 +2033,7 @@ begin
Result := -1;
exit;
end;
- Result := FLayout.GetCharIndex( FLayout.FLines^[ FCursorRow ].Text ) + FCursorOffset;
+ Result := FLayout.GetCharIndex( FLayout.FLines[FCursorRow].Text ) + FCursorOffset;
end;
procedure TRichTextView.RefreshCursorPosition;
@@ -2059,20 +2059,15 @@ begin
end;
Row := FLayout.GetLineFromCharIndex( Index );
- SetCursorPosition( Index - FLayout.GetCharIndex( FLayout.FLines^[ Row ].Text ),
- Row,
- true );
+ SetCursorPosition( Index - FLayout.GetCharIndex( FLayout.FLines[Row].Text ), Row, true );
end;
-procedure TRichTextView.SetCursorIndex( Index: longint;
- PreserveSelection: boolean );
+procedure TRichTextView.SetCursorIndex( Index: longint; PreserveSelection: boolean );
var
Row: longint;
begin
Row := FLayout.GetLineFromCharIndex( Index );
- SetCursorPosition( Index - FLayout.GetCharIndex( FLayout.FLines^[ Row ].Text ),
- Row,
- PreserveSelection );
+ SetCursorPosition( Index - FLayout.GetCharIndex( FLayout.FLines[Row].Text ), Row, PreserveSelection );
SetupCursor;
end;
@@ -2085,7 +2080,7 @@ begin
RemoveCursor;
FCursorOffset := Offset;
FCursorRow := Row;
- Index := FLayout.GetCharIndex( FLayout.FLines^[ Row ].Text ) + Offset;
+ Index := FLayout.GetCharIndex( FLayout.FLines[Row].Text ) + Offset;
//writeln(' SetCursorPosition: offset=', FCursorOffset, ' row=', FCursorRow, ' index=', Index);
exit; { TODO: Complete this selection of text code - currently gives AV's }
@@ -2123,7 +2118,7 @@ begin
// exit;
// SetCursorIndex( GetCharIndex( P ), PreserveSelection );
- Line := FLayout.FLines^[ CursorRow ];
+ Line := FLayout.FLines[CursorRow];
NewOffset := PCharDiff( P, Line.Text );
if NewOffset < Line.Length then
begin
@@ -2163,7 +2158,7 @@ begin
// if Element.ElementType = teTextEnd then
// exit;
- Line := FLayout.FLines^[ CursorRow ];
+ Line := FLayout.FLines[CursorRow];
NewOffset := PCharDiff( P, Line.Text );
if NewOffset >= 0 then
begin
@@ -2173,7 +2168,7 @@ begin
begin
if FCursorRow <= 0 then
exit;
- Line := FLayout.FLines^[ CursorRow - 1 ];
+ Line := FLayout.FLines[CursorRow-1];
if Line.Wrapped then
SetCursorPosition( Line.Length - 1, FCursorRow - 1, PreserveSelection )
else
@@ -2211,7 +2206,7 @@ Procedure TRichTextView.CursorToLineStart( PreserveSelection: boolean );
Var
Line: TLayoutLine;
begin
- Line := FLayout.FLines^[ FCursorRow ];
+ Line := FLayout.FLines[FCursorRow];
SetCursorPosition( 0, FCursorRow, PreserveSelection );
SetupCursor;
end;
@@ -2220,7 +2215,7 @@ Procedure TRichTextView.CursorToLineEnd( PreserveSelection: boolean );
Var
Line: TLayoutLine;
begin
- Line := FLayout.FLines^[ FCursorRow ];
+ Line := FLayout.FLines[FCursorRow];
SetCursorPosition( Line.Length, FCursorRow, PreserveSelection );
SetupCursor;
end;
@@ -2281,7 +2276,7 @@ begin
if NewRow >= FLayout.FNumLines - 1 then
break;
- Distance := Distance + FLayout.FLines^[ NewRow ].Height;
+ Distance := Distance + FLayout.FLines[NewRow].Height;
inc( NewRow );
end;
@@ -2306,7 +2301,7 @@ begin
if NewRow <= 0 then
break;
dec( NewRow );
- Distance := Distance + FLayout.FLines^[ NewRow ].Height;
+ Distance := Distance + FLayout.FLines[NewRow].Height;
end;
FLayout.GetXFromOffset( FCursorOffset, FCursorRow, X );
@@ -2676,7 +2671,7 @@ begin
GetFirstVisibleLine( LineIndex,
Y );
if LineIndex >= 0 then
- Result := FLayout.GetCharIndex( FLayout.FLines^[ LineIndex ].Text )
+ Result := FLayout.GetCharIndex( FLayout.FLines[LineIndex].Text )
else
Result := 0;
end;
@@ -2750,7 +2745,7 @@ begin
exit;
if ( Row = BottomLine )
- and ( Offset >= FLayout.FLines^[ BottomLine ].Height - 1 ) then
+ and ( Offset >= FLayout.FLines[BottomLine].Height - 1 ) then
// bottom row already entirely visible
exit;
@@ -2778,7 +2773,7 @@ begin
if ( BottomLine <> -1 )
and ( Row >= BottomLine ) then
SetVerticalPosition( FLayout.GetLinePosition( Row )
- + FLayout.FLines^[ Row ].Height
+ + FLayout.FLines[Row].Height
- GetTextAreaHeight );
end;
end;