기술 문서

Delphi에서 연속 스크롤을 사용하여 다중 페이지 PDF 뷰어 만들기

· PDF 프로그래밍

이 튜토리얼에서는 Multi-Page Viewer 데모를 살펴봅니다. 이 데모는 기본 PDF 뷰어에 연속 스크롤 기능을 추가하여, Adobe Acrobat과 같은 최신 PDF 리더가 문서를 표시하는 방식과 유사하게 사용자가 모든 페이지를 끊김 없이 스크롤할 수 있도록 합니다.

개요

Multi-Page Viewer 데모는 PDFium VCL의 고급 보기 모드를 보여줍니다. 여기에는 단일 페이지 연속 스크롤 및 양면 연속 스크롤(책 모드)이 포함됩니다. 이러한 기능은 전문적인 PDF 읽기 환경을 만드는 데 필수적입니다.

표시 모드

PDFium VCL은 다음 속성을 통해 여러 표시 모드를 지원합니다. DisplayMode 속성:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
type
  TPdfDisplayMode = (
    dmSingleContinuous,  // Single page with continuous vertical scrolling
    dmDoubleContinuous   // Two pages side-by-side (book layout)
  );
 
// Switch between display modes
procedure TFormMain.ComboBoxDisplayModeChange(Sender: TObject);
begin
  case ComboBoxDisplayMode.ItemIndex of
    0: PdfView.DisplayMode := dmSingleContinuous;
    1: PdfView.DisplayMode := dmDoubleContinuous;
  end;
end;

주요 기능

  • 연속 스크롤 모든 페이지를 페이지 단위로 탐색하지 않고 스크롤하여 볼 수 있습니다.
  • 양면 모드 실제 책처럼 두 페이지를 나란히 볼 수 있습니다.
  • 페이지 간 텍스트 선택 여러 페이지에 걸쳐 텍스트를 선택하고 복사할 수 있습니다.
  • 북마크 탐색 북마크된 섹션으로 즉시 이동할 수 있습니다.
  • 하이라이트 검색 문서 전체에서 텍스트를 찾고 강조 표시합니다.
  • 키보드 탐색. 화살표 키, 페이지 위/아래, Home/End 지원
  • 최적화된 성능 화면에 보이는 페이지만 렌더링하여 부드러운 스크롤을 제공합니다.

PDFium DLL 요구 사항

PDFium VCL 애플리케이션을 실행하기 전에 PDFium DLL 파일을 설치해야 합니다. DLL 파일은 다음 폴더에 있습니다. DLLs 폴더:

  • pdfium32.dll / pdfium64.dll 대부분의 애플리케이션에 적합한 표준 버전입니다.
  • pdfium32v8.dll / pdfium64v8.dll – V8 JavaScript 엔진을 탑재한 확장 버전

설치: 실행 PDFiumVCL\DLLs\CopyDlls.bat 관리자 권한으로 DLL 파일을 Windows 시스템 디렉터리에 복사합니다. 64비트 Windows에서는 32비트 DLL 파일이 다음 디렉터리에 위치합니다. SysWOW64 그리고 64비트 DLL 파일은 다음 디렉터리에 위치합니다. System32.

구성 요소 설정

이 데모는 정교한 텍스트 선택 시스템을 구현합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
procedure TFormMain.PdfViewMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  CharIndex: Integer;
begin
  if Button = mbLeft then
  begin
    // Get character index at click position
    CharIndex := GetPreciseCharacterIndex(X, Y);
    
    if CharIndex >= 0 then
    begin
      SelectionMode := True;
      Selecting := True;
      SelectionStart := CharIndex;
      SelectionEnd := CharIndex;
    end;
  end;
end;
 
procedure TFormMain.PdfViewMouseMove(Sender: TObject; Shift: TShiftState;
  X, Y: Integer);
var
  CharIndex: Integer;
begin
  if Selecting then
  begin
    CharIndex := GetPreciseCharacterIndex(X, Y);
    if CharIndex >= 0 then
    begin
      SelectionEnd := CharIndex;
      PdfView.Invalidate; // Redraw to show selection
    end;
  end;
end;

문자 인덱스 감지

정확한 텍스트 선택을 위해, 이 데모는 문자 감지에 줌에 따른 허용 오차를 사용합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
function TFormMain.GetPreciseCharacterIndex(X, Y: Integer): Integer;
var
  BaseTolerance: Single;
  ZoomFactor: Single;
  AdjustedTolerance: Single;
  CharIndex: Integer;
begin
  Result := -1;
  
  if not PdfView.Active then
    Exit;
    
  // Calculate dynamic tolerance based on zoom level
  ZoomFactor := PdfView.Zoom;
  BaseTolerance := 5.0;
  
  // Adjust tolerance inversely to zoom
  AdjustedTolerance := BaseTolerance / ZoomFactor;
  
  // Get character at position with tolerance
  CharIndex := PdfView.CharacterIndexAtPos(X, Y,
    AdjustedTolerance, AdjustedTolerance);
    
  Result := CharIndex;
end;

선택한 텍스트 강조

데모에서는 선택 항목을 강조 표시합니다. OnPaint 이벤트:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
procedure TFormMain.PdfViewPaint(Sender: TObject);
var
  I, StartIdx, EndIdx: Integer;
  Rect: TPdfRectangle;
  R: TRect;
begin
  if (SelectionStart >= 0) and (SelectionEnd >= 0) then
  begin
    StartIdx := Min(SelectionStart, SelectionEnd);
    EndIdx := Max(SelectionStart, SelectionEnd);
    
    // Draw highlight for each character in selection
    for I := StartIdx to EndIdx do
    begin
      Rect := PdfView.CharacterRectangle[I];
      
      // Convert PDF coordinates to screen coordinates
      if PdfView.PageToDevice(
        Rect.Left, Rect.Top,
        PdfView.Left, PdfView.Top,
        PdfView.Width, PdfView.Height,
        PdfView.Rotation, R.Left, R.Top) then
      begin
        // Draw highlight rectangle
        PdfView.Canvas.Brush.Color := clHighlight;
        PdfView.Canvas.Brush.Style := bsSolid;
        PdfView.Canvas.FillRect(R);
      end;
    end;
  end;
end;

선택한 텍스트를 클립보드에 복사합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
procedure TFormMain.MenuItemCopyClick(Sender: TObject);
var
  StartIdx, EndIdx: Integer;
  SelectedText: string;
begin
  if (SelectionStart >= 0) and (SelectionEnd >= 0) then
  begin
    StartIdx := Min(SelectionStart, SelectionEnd);
    EndIdx := Max(SelectionStart, SelectionEnd);
    
    // Set page number for text extraction
    Pdf.PageNumber := PdfView.PageNumber;
    
    // Extract text from selection range
    SelectedText := Pdf.Text(StartIdx, EndIdx - StartIdx + 1);
    
    // Copy to clipboard
    Clipboard.AsText := SelectedText;
  end;
end;

검색 기능.

하이라이트를 사용하여 텍스트 검색을 구현합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
procedure TFormMain.SpeedButtonSearchClick(Sender: TObject);
var
  SearchText: string;
  FoundIndex: Integer;
begin
  SearchText := EditSearch.Text;
  
  if SearchText = '' then
    Exit;
    
  // Find first occurrence
  FoundIndex := Pdf.FindFirst(SearchText, [], 0, True);
  
  if FoundIndex >= 0 then
  begin
    SearchStart := FoundIndex;
    SearchEnd := FoundIndex + Length(SearchText) - 1;
    PdfView.Invalidate; // Redraw to show highlight
  end
  else
    ShowMessage('Text not found');
end;

페이지 변경 이벤트.

페이지 변경을 처리하여 UI 요소를 업데이트합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
procedure TFormMain.PdfViewPageChanged(Sender: TObject);
begin
  if PdfView.Active then
  begin
    // Update page indicator
    SpeedButtonPageNumber.Caption :=
      IntToStr(PdfView.PageNumber) + ' of ' + IntToStr(PdfView.PageCount);
    
    // Update navigation button states
    SpeedButtonFirstPage.Enabled := PdfView.PageNumber > 1;
    SpeedButtonPreviousPage.Enabled := PdfView.PageNumber > 1;
    SpeedButtonNextPage.Enabled := PdfView.PageNumber < PdfView.PageCount;
    SpeedButtonLastPage.Enabled := PdfView.PageNumber < PdfView.PageCount;
    
    // Update bookmark tree selection
    if not DisableBookmarks then
      UpdateBookmarkSelection(PdfView.PageNumber);
  end;
end;

키보드 탐색.

데모는 탐색을 위한 키보드 단축키를 지원합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
procedure TFormMain.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  case Key of
    VK_ESCAPE:
      begin
        // Exit selection mode on Escape
        if SelectionMode then
        begin
          SelectionMode := False;
          SelectionStart := -1;
          SelectionEnd := -1;
          PdfView.Invalidate;
        end;
        Key := 0;
      end;
      
    VK_PRIOR, VK_UP, VK_LEFT:
      begin
        if SpeedButtonPreviousPage.Enabled then
          SpeedButtonPreviousPage.Click;
        Key := 0;
      end;
      
    VK_NEXT, VK_DOWN, VK_RIGHT:
      begin
        if SpeedButtonNextPage.Enabled then
          SpeedButtonNextPage.Click;
        Key := 0;
      end;
      
    VK_HOME:
      begin
        if SpeedButtonFirstPage.Enabled then
          SpeedButtonFirstPage.Click;
        Key := 0;
      end;
      
    VK_END:
      begin
        if SpeedButtonLastPage.Enabled then
          SpeedButtonLastPage.Click;
        Key := 0;
      end;
  end;
end;

양면 탐색

양면 모드에서는 한 번에 두 페이지씩 탐색합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
procedure TFormMain.SpeedButtonNextPageClick(Sender: TObject);
begin
  if PdfView.DisplayMode = dmSingleContinuous then
    PdfView.PageNumber := PdfView.PageNumber + 1
  else
    PdfView.PageNumber := PdfView.PageNumber + 2;
end;
 
procedure TFormMain.SpeedButtonPreviousPageClick(Sender: TObject);
begin
  if PdfView.DisplayMode = dmSingleContinuous then
    PdfView.PageNumber := PdfView.PageNumber - 1
  else
    PdfView.PageNumber := PdfView.PageNumber - 2;
end;

결론

Multi-Page Viewer 데모는 연속 스크롤, 텍스트 선택 및 검색 기능을 갖춘 완벽한 PDF 리더를 만드는 방법을 보여줍니다. 이는 사용자가 최신 PDF 뷰어 애플리케이션에서 기대하는 기능입니다.

PDFium VCL은 복잡한 렌더링 및 텍스트 추출을 처리하고, 사용자는 사용자 인터페이스 및 애플리케이션별 기능에 집중할 수 있습니다. 그 결과는 상용 PDF 리더에 버금가는 부드럽고 반응성이 뛰어난 PDF 뷰어 경험을 제공합니다.

Get PDFium VCL 컴포넌트 at loslab.com 에서 오늘부터 Delphi로 전문적인 PDF 애플리케이션을 개발해 보세요.