ImageEn, unit iexUserInteractions |
|
TIEPdfViewerInteraction.GetTextRects
Declaration
function GetTextRects(CharIndex: Integer; Length: Integer; SelectionMerging: Integer = 3; ScreenValues: Boolean = True; SortRects: Boolean = False): array of TRect;
Description
Returns the rect(s) containing the text that starts at CharIndex of the specified length.
Parameter | Description |
CharIndex | The starting position of the text |
Count | The length of the text (or -1 to get all text) |
SelectionMerging | Merges closely aligned selections into single ones. Sometimes the words in PDF documents have widely spaced letters that show as multiple selections. If you specify a value > zero, then selections that are less than that number PDF points apart will be merged into one |
ScreenValues | True to return values in terms of the current display (considering scroll, zoom, etc). False to return PDF document valyes (in PDF points) |
SortRects | Set to True if you want the rects to be sorted from top-to-bottom, then left-to-right |
Multiple rects may be returned if the text is spaced or on multiple lines.
Result will be NIL if there are no rects found for the specified text range.
Notes:
- To convert a screen position to a CharIndex, use
ScrToCharIndex- To find text, use
FindExamples
// Get the location of the "Adobe" on the page
var
wordIdx, wordLen, i: Integer;
rects : TIERectArray;
begin
memo1.Lines.Clear();
// Get the location of the "Adobe" by index and count
ImageEnView1.PdfViewer.Find( 'Adobe', False, False, False, False );
ImageEnView1.PdfViewer.FindNext( wordIdx, wordLen, False, False );
// Convert index and count to rects
rects := ImageEnView1.PdfViewer.GetTextRects( wordIdx, wordLen );
if rects = nil then
memo1.Lines.Add( 'NOT FOUND!' )
else
for i := Low( rects ) to High( rects ) do
memo1.Lines.Add( format( '(%d, %d, %d, %d)', [ rects[i].Left, rects[i].Top, rects[i].Right, rects[i].Bottom ]));
end;
// Same as above, but finds *all* instances of "Adobe" on the page
ImageEnView1.PdfViewer.Find( 'Adobe', False, False, False, False );
While ImageEnView1.PdfViewer.FindNext( wordIdx, wordLen, False, False ) do
begin
// Convert index and count to rects
rects := ImageEnView1.PdfViewer.GetTextRects( wordIdx, wordLen );
if rects <> nil then
for i := Low( rects ) to High( rects ) do
memo1.Lines.Add( format( '(%d, %d, %d, %d)', [ rects[i].Left, rects[i].Top, rects[i].Right, rects[i].Bottom ]));
end;
// Output the locations of all text rects in current page to a memo (screen values)
var
rects: TIERectArray;
text: string;
begin
rects := ImageEnView1.PdfViewer.GetTextRects( 0, -1 );
for i := Low( rects ) to High( rects ) do
begin
text := ImageEnView1.PdfViewer.GetText( rects[i] );
memo1.Lines.Add( Format( '%d (%d, %d, %d, %d): %s', [ i + 1, rects[i].Left, rects[i].Top, rects[i].Right, rects[i].Bottom, text ]));
end;
end;
// Output the page text to a memo (attempting to format the layout with lines and spaces)
// Note: This is the same as calling Memo1.Text := GetText( true );
const
Lines_Per_Page = 80; // Typical number of lines on a PDF document
Chars_Per_Line = 120; // How many characters wide to make our text page
var
rects: TIERectArray;
text, currLine: string;
i, currY: Integer;
pageW, lineH, wantLeft: Integer;
newLine: Boolean;
begin
WindowState := wsMaximized;
Memo1.Font.Name := 'Courier New'; // Fixed width font
memo1.Clear;
pageW := ImageEnView1.PdfViewer.PageWidth;
lineH := ImageEnView1.PdfViewer.PageHeight div Lines_Per_Page;
currY := ImageEnView1.PdfViewer.PageHeight; // Note: PDF values are bottom up
rects := ImageEnView1.PdfViewer.GetTextRects( 0, -1, 3, False, True );
newLine := False;
currLine := '';
for i := Low( rects ) to High( rects ) do
begin
text := ImageEnView1.PdfViewer.GetText( rects[i], False );
// malformatted document?
if ( text = '' ) or ( rects[i].Right < 0 ) or ( rects[i].Left > pageW ) then
continue;
while currY > rects[i].Top do
begin
memo1.Lines.Add( currLine );
currLine := '';
dec( currY, lineH );
newLine := True;
end;
wantLeft := Round( Chars_Per_Line * rects[i].Left / pageW );
while Length( currLine ) < wantLeft do
currLine := currLine + ' ';
currLine := currLine + text;
if newLine then
currY := rects[i].Bottom;
newLine := False;
end;
if currLine <> '' then
memo1.Lines.Add( currLine );
end;
See Also
-
FindNext-
Find