Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CONTRIBUTORS.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ history and [GitHub's 'Contributors' feature](https://github.com/py-pdf/pypdf/gr

* [abyesilyurt](https://github.com/abyesilyurt)
* [ArkieCoder](https://github.com/ArkieCoder)
* [Beers, PJ](https://github.com/PJBrs)
* [Clauss, Christian](https://github.com/cclauss)
* [DL6ER](https://github.com/DL6ER)
* [Duy, Phan Thanh](https://github.com/zuypt)
Expand Down
7 changes: 7 additions & 0 deletions docs/user/forms.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,13 @@ parameter is `True` by default for legacy compatibility, but this flags the PDF
processor to recompute the field's rendering, and may trigger a "save changes"
dialog for users who open the generated PDF.

If you want to flatten your form, that is, keeping all form field contents while
removing the form fields themselves, you can set the `flatten` parameter in
{func}`~pypdf.PdfWriter.update_page_form_field_values` to `True`. This
will convert form field contents to regular PDF content. Afterwards, use
{func}`~pypdf.PdfWriter.remove_annotations` with `subtypes="/Widget"`
to remove all form fields to get an actual flattened PDF.

## Some notes about form fields and annotations

PDF forms have a dual-nature approach to the fields:
Expand Down
15 changes: 10 additions & 5 deletions pypdf/_font.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from dataclasses import dataclass, field
from typing import Optional

from pypdf.generic import DictionaryObject

Expand Down Expand Up @@ -29,10 +28,16 @@ class FontDescriptor:
character_widths: dict[str, int] = field(default_factory=dict)

@classmethod
def from_font_resource(cls, pdf_font_dict: DictionaryObject) -> "Optional[FontDescriptor]":
def from_font_resource(cls, pdf_font_dict: DictionaryObject) -> "FontDescriptor":
from pypdf._codecs.core_fontmetrics import CORE_FONT_METRICS # noqa: PLC0415
# Prioritize information from the PDF font dictionary
font_name = pdf_font_dict.get("/BaseFont", "Unknown")
if font_name[1:] in CORE_FONT_METRICS:
return CORE_FONT_METRICS.get(font_name[1:])
font_name = pdf_font_dict.get("/BaseFont", "Unknown").removeprefix("/")
if font_name in CORE_FONT_METRICS:
return CORE_FONT_METRICS[font_name]
return cls(name=font_name)

def text_width(self, text: str) -> float:
"""Sum of character widths specified in PDF font for the supplied text."""
return sum(
[self.character_widths.get(char, self.character_widths.get("default", 0)) for char in text], 0.0
)
Loading
Loading