技術記事

Delphi の PDFium VCL を利用した PDF フォント プロパティの分析

· PDFプログラミング

PDF ドキュメントで使用されているフォントを理解することは、品質管理、アクセシビリティ確認、ドキュメント解析にとって重要です。 フォントプロパティ このデモプログラムでは、PDFium VCL を使用して PDF 内の文字に関する詳細なフォント情報へアクセスする方法を示します。

概要

このデモでは、PDF 内の任意の文字をクリックして、フォント名、太さ、スタイル、サイズ、埋め込み状態などのフォントプロパティを表示できます。PDF の分析やトラブルシューティングに役立ちます。

主な機能

  • 交互式選択 - 任意の文字をクリックして分析できます。
  • フォント名 - フォントファミリー(例: “Arial”、“Times New Roman”)。
  • フォントのベース名 – PDF内部で利用されるフォント名
  • フォントの太さ – 数値による太さ (400 = 通常、700 = 太字)
  • フォントサイズ – ポイント単位のサイズ
  • イタリックの角度 – イタリックフォントの傾き
  • Ascent/Descent – 垂直方向のメトリクス
  • 埋め込み状態 – フォントがPDFに埋め込まれているかどうか
  • フォントデータ – 埋め込まれている場合は、生のフォントデータにアクセス

PDFium DLL の要件

PDFium VCL アプリケーションを実行する前に、PDFium DLL ファイルがインストールされていることを確認してください。

  • pdfium32.dll / pdfium64.dll – 標準バージョン(約 5-6 MB)
  • pdfium32v8.dll / pdfium64v8.dll – V8 JavaScript エンジン付き(約 23-27 MB)

インストール: 実行 PDFiumVCL\DLLs\CopyDlls.bat 管理者権限で、DLLファイルをWindowsシステムディレクトリに自動的にコピーします。

フォントプロパティへのアクセス

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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
procedure TfrmMain.UpdateFontInfo;
var
  FontInfo: TStringList;
begin
  FontInfo := TStringList.Create;
  try
    FontInfo.Add('=== Font Properties for Character Index: ' +
      IntToStr(PdfView.CurrentCharIndex) + ' ===');
    FontInfo.Add('');
    
    // Font family name
    try
      FontInfo.Add('Font Family Name: ' + PdfView.FontFamilyName);
    except
      FontInfo.Add('Font Family Name: \u003cError retrieving\u003e');
    end;
    
    // Font base name (internal PDF name)
    try
      FontInfo.Add('Font Base Name: ' + PdfView.FontBaseName);
    except
      FontInfo.Add('Font Base Name: \u003cError retrieving\u003e');
    end;
    
    // Font size for this character
    try
      FontInfo.Add('Font Size: ' +
        FloatToStr(PdfView.FontSize[PdfView.CurrentCharIndex]));
    except
      FontInfo.Add('Font Size: \u003cError retrieving\u003e');
    end;
    
    // Font weight (400=normal, 700=bold)
    try
      FontInfo.Add('Font Weight: ' + IntToStr(PdfView.FontWeight));
    except
      FontInfo.Add('Font Weight: \u003cError retrieving\u003e');
    end;
    
    // Italic angle (0 for upright, negative for italic)
    try
      FontInfo.Add('Font Italic Angle: ' + IntToStr(PdfView.FontItalicAngle));
    except
      FontInfo.Add('Font Italic Angle: \u003cError retrieving\u003e');
    end;
    
    // Vertical metrics
    try
      FontInfo.Add('Font Ascent: ' + FloatToStr(PdfView.FontAscent));
    except
      FontInfo.Add('Font Ascent: \u003cError retrieving\u003e');
    end;
    
    try
      FontInfo.Add('Font Descent: ' + FloatToStr(PdfView.FontDescent));
    except
      FontInfo.Add('Font Descent: \u003cError retrieving\u003e');
    end;
    
    // Embedded status
    try
      FontInfo.Add('Font Is Embedded: ' +
        BoolToStr(PdfView.FontIsEmbedded, True));
    except
      FontInfo.Add('Font Is Embedded: \u003cError retrieving\u003e');
    end;
    
    // Font data size (if embedded)
    try
      FontInfo.Add('Font Data Size: ' +
        IntToStr(Length(PdfView.FontData)) + ' bytes');
    except
      FontInfo.Add('Font Data Size: \u003cError retrieving\u003e');
    end;
    
    FontInfo.Add('');
    FontInfo.Add('Character: ' +
      PdfView.Character[PdfView.CurrentCharIndex]);
    
    memoFontInfo.Lines.Assign(FontInfo);
    
  finally
    FontInfo.Free;
  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
procedure TfrmMain.PdfViewMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  CharIndex: Integer;
begin
  if not PdfView.Active then
    Exit;
    
  try
    // Get character at click position
    CharIndex := PdfView.CharacterIndexAtPos(X, Y, 10.0, 10.0);
    
    if CharIndex >= 0 then
    begin
      edtCharIndex.Text := IntToStr(CharIndex);
      PdfView.CurrentCharIndex := CharIndex;
      UpdateFontInfo;
    end;
    
  except
    on E: Exception do
    begin
      memoFontInfo.Lines.Clear;
      memoFontInfo.Lines.Add('Error getting character: ' + E.Message);
    end;
  end;
end;

手动文字索引输入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
procedure TfrmMain.btnGetFontInfoClick(Sender: TObject);
var
  CharIndex: Integer;
begin
  if not PdfView.Active then
  begin
    ShowMessage('Please open a PDF file first.');
    Exit;
  end;
  
  try
    CharIndex := StrToInt(edtCharIndex.Text);
    PdfView.CurrentCharIndex := CharIndex;
    UpdateFontInfo;
  except
    on E: Exception do
      ShowMessage('Invalid character index: ' + E.Message);
  end;
end;

利用可能なフォントプロパティ

PDFium VCL は、フォントに関連する次のプロパティを公開しています。

1
2
3
4
5
6
7
8
9
10
11
12
13
// Font properties accessible via TPdf and TPdfView
property FontFamilyName: WString;  // e.g., "Arial", "Times New Roman"
property FontBaseName: WString;    // Internal PDF font name
property FontWeight: Integer;      // 100-900, 400=normal, 700=bold
property FontItalicAngle: Integer; // Degrees, 0=upright, negative=italic
property FontAscent: Single;       // Height above baseline
property FontDescent: Single;      // Depth below baseline (negative)
property FontIsEmbedded: Boolean;  // True if font is embedded
property FontData: TBytes;         // Raw font data if embedded
property FontHandle: FPDF_FONT;    // PDFium font handle
 
// Per-character property
property FontSize[Index: Integer]: Double;  // Font size for character

フォントプロパティを使用した分析

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
procedure AnalyzeDocumentFonts(Pdf: TPdf);
var
  FontList: TStringList;
  I: Integer;
  FontName: string;
  LastFontName: string;
begin
  FontList := TStringList.Create;
  FontList.Sorted := True;
  FontList.Duplicates := dupIgnore;
  
  try
    Pdf.PageNumber := 1;
    LastFontName := '';
    
    for I := 0 to Pdf.CharacterCount - 1 do
    begin
      // Access font for each character
      // (In practice, use CurrentCharIndex pattern)
      
      // Check FontFamilyName changes
      // Add unique fonts to list
    end;
    
    ShowMessage('Document uses ' + IntToStr(FontList.Count) + ' fonts');
    
  finally
    FontList.Free;
  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
procedure CheckFontEmbedding(Pdf: TPdf);
var
  EmbeddedFonts, NonEmbeddedFonts: TStringList;
begin
  EmbeddedFonts := TStringList.Create;
  NonEmbeddedFonts := TStringList.Create;
  
  try
    EmbeddedFonts.Sorted := True;
    EmbeddedFonts.Duplicates := dupIgnore;
    NonEmbeddedFonts.Sorted := True;
    NonEmbeddedFonts.Duplicates := dupIgnore;
    
    // Analyze fonts...
    
    if NonEmbeddedFonts.Count > 0 then
    begin
      ShowMessage('Warning: ' + IntToStr(NonEmbeddedFonts.Count) +
        ' fonts are not embedded. Document may not display correctly ' +
        'on systems without these fonts installed.');
    end
    else
    begin
      ShowMessage('All fonts are embedded. Document will display ' +
        'consistently on all systems.');
    end;
    
  finally
    EmbeddedFonts.Free;
    NonEmbeddedFonts.Free;
  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
procedure ExtractEmbeddedFont(Pdf: TPdf; const OutputFile: string);
var
  FontData: TBytes;
  FileStream: TFileStream;
begin
  if Pdf.FontIsEmbedded then
  begin
    FontData := Pdf.FontData;
    
    if Length(FontData) > 0 then
    begin
      FileStream := TFileStream.Create(OutputFile, fmCreate);
      try
        FileStream.WriteBuffer(FontData[0], Length(FontData));
        ShowMessage('Font extracted: ' + IntToStr(Length(FontData)) + ' bytes');
      finally
        FileStream.Free;
      end;
    end;
  end
  else
    ShowMessage('Font is not embedded in the document.');
end;

フォントの太さの値を理解する

Weight Value Common Name
100 Thin
200 Extra Light
300 Light
400 Normal/Regular
500 Medium
600 Semi Bold
700 Bold
800 Extra Bold
900 Black

利用例

  • 品質管理 – ドキュメントで正しいフォントが使用されているかを確認します
  • アクセシビリティ – フォントがアクセシビリティ要件を満たしているか確認
  • 法医分析 – 文書の起源と変更を分析
  • 印刷プレフライト – 本番環境での印刷前にフォントの埋め込みを確認
  • フォントインベントリ – ドキュメント全体で利用されているフォントをカタログ化

結論

Font Properties デモは、PDFium VCL が PDF ドキュメント内のフォント情報へ深くアクセスできることを示します。印刷向けのフォント埋め込み確認にも、ドキュメントの組版分析にも、これらの API を活用できます。

任意の文字をクリックしてすぐにフォントプロパティを表示できるため、PDF 分析を直感的かつ効率的に行えます。

PDF フォントをさらに詳しく調べる。 利用 PDFium Delphi VCL コンポーネント。.