mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-10-30 13:08:48 -06:00
M12: doc comments for the functions this change touches
This commit is contained in:
@@ -1464,6 +1464,9 @@ impl Layouter<'_> {
|
||||
if *n == 1 { base } else { format!("{base}_{n}") }
|
||||
}
|
||||
|
||||
/// Draw a field in `rect`: its border and caption, then its value as text (non-interactive
|
||||
/// fields, barcodes, text longer than a page) or as a widget. `radio` puts it in an
|
||||
/// exclusion group; `sib` is its index in its SOM path (`name[sib]`).
|
||||
fn draw_field(
|
||||
&mut self,
|
||||
f: &Field,
|
||||
|
||||
@@ -180,6 +180,8 @@ impl Default for Font {
|
||||
}
|
||||
|
||||
impl Font {
|
||||
/// This font with the properties `spec` sets in place of its own; those `spec` leaves
|
||||
/// `None` are inherited.
|
||||
pub fn apply(&self, spec: &FontSpec) -> Font {
|
||||
Font {
|
||||
typeface: spec.typeface.clone().unwrap_or_else(|| self.typeface.clone()),
|
||||
|
||||
@@ -146,6 +146,8 @@ fn parse_border(n: Option<XmlNode>) -> Option<Border> {
|
||||
Some(Border { presence: Presence::parse(n.attribute("presence")), edges: four, fill: parse_fill(child(n, "fill")) })
|
||||
}
|
||||
|
||||
/// `<font>`: typeface, size, weight, posture, underline, fill color and horizontal scale.
|
||||
/// What the element doesn't set, or a missing element, is left `None` to inherit.
|
||||
fn parse_font(n: Option<XmlNode>) -> FontSpec {
|
||||
let Some(n) = n else { return FontSpec::default() };
|
||||
FontSpec {
|
||||
@@ -206,6 +208,8 @@ fn parse_rich(body: XmlNode) -> RichText {
|
||||
size: Option<f64>,
|
||||
h_scale: Option<f64>,
|
||||
}
|
||||
/// `base` with the CSS declarations in `css` applied: weight, style, underline, size and
|
||||
/// `xfa-font-horizontal-scale`. Anything else is ignored.
|
||||
fn styled(base: &Style, css: Option<&str>) -> Style {
|
||||
let mut s = base.clone();
|
||||
for decl in css.unwrap_or("").split(';') {
|
||||
@@ -224,6 +228,9 @@ fn parse_rich(body: XmlNode) -> RichText {
|
||||
}
|
||||
// Paragraph boundaries from `p` are implicit (dropped when empty); `br` makes an explicit
|
||||
// line break that stays even when the line is blank.
|
||||
/// Add the text under `n` to `out` as runs in `style`, as the elements it meets restyle it;
|
||||
/// `p` and `br` start paragraphs (`explicit` marks the `br` ones) and `embed` spans add
|
||||
/// embedded fields. Nothing deeper than `MAX_DEPTH` is read.
|
||||
fn walk(n: XmlNode, style: &Style, out: &mut RichText, explicit: &mut Vec<bool>, depth: usize) {
|
||||
if depth > MAX_DEPTH {
|
||||
return;
|
||||
|
||||
@@ -570,6 +570,9 @@ impl Emitter<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Write one laid-out page under `pages_ref`: its fills, lines, text and pictures in a
|
||||
/// content stream, the fonts and images it uses as resources, and its widgets as
|
||||
/// annotations. Returns the page object.
|
||||
fn page(&mut self, page: &Page, pages_ref: ObjRef) -> Result<ObjRef, XfaError> {
|
||||
let page_ref = self.doc.add(Object::Dict(Dict::new()));
|
||||
let mut content: Vec<u8> = Vec::new();
|
||||
|
||||
@@ -51,6 +51,9 @@ fn scaled_text_template() -> (String, &'static str) {
|
||||
(xdp, TEXT)
|
||||
}
|
||||
|
||||
/// `fontHorizontalScale` is read as a percentage and text is measured at it: the 80% draw
|
||||
/// fits its box on one line where the full-width one takes two, and a span's own scale
|
||||
/// applies to that span alone.
|
||||
#[test]
|
||||
fn horizontally_scaled_text_is_measured_and_drawn_narrower() {
|
||||
let (xdp, text) = scaled_text_template();
|
||||
@@ -80,6 +83,8 @@ fn horizontally_scaled_text_is_measured_and_drawn_narrower() {
|
||||
assert!((half.face.width("half") - full.face.width("half") / 2.0).abs() < 1e-9);
|
||||
}
|
||||
|
||||
/// A growing non-interactive field is measured in the face its text is drawn in: condensed,
|
||||
/// its text takes fewer lines and the field grows only to hold them.
|
||||
#[test]
|
||||
fn a_non_interactive_field_is_measured_at_the_scale_its_text_is_drawn() {
|
||||
// A growing, non-interactive text field (drawn as text by the layout, not as a widget),
|
||||
@@ -111,6 +116,8 @@ fn a_non_interactive_field_is_measured_at_the_scale_its_text_is_drawn() {
|
||||
assert!((narrow_gap - full_gap).abs() < 0.01, "the field shrinks with its text: gap {narrow_gap} vs {full_gap}");
|
||||
}
|
||||
|
||||
/// Condensed text is written with `Tz` inside a `q`/`Q` pair of its own, and full-width text
|
||||
/// sets no scale, so none carries over from the text before it.
|
||||
#[test]
|
||||
fn horizontally_scaled_text_is_written_with_tz_inside_its_own_graphics_state() {
|
||||
let (xdp, _) = scaled_text_template();
|
||||
|
||||
@@ -81,6 +81,8 @@ pub struct Face {
|
||||
}
|
||||
|
||||
impl Face {
|
||||
/// The face a resolved font is drawn in: the standard-14 family its typeface maps to,
|
||||
/// with its size and horizontal scale clamped to a drawable range.
|
||||
pub fn of(font: &Font) -> Face {
|
||||
Face {
|
||||
family: Family::of(&font.typeface),
|
||||
@@ -93,6 +95,8 @@ impl Face {
|
||||
}
|
||||
}
|
||||
|
||||
/// This face with what a rich-text run sets in place of its own: weight, posture,
|
||||
/// underline, size and horizontal scale. The family and color stay.
|
||||
pub fn with_run(&self, run: &Run) -> Face {
|
||||
Face {
|
||||
family: self.family,
|
||||
@@ -111,6 +115,8 @@ impl Face {
|
||||
Face { h_scale: 1.0, ..self }
|
||||
}
|
||||
|
||||
/// The resource name of this face's standard font, as content streams and `/DA` strings
|
||||
/// refer to it.
|
||||
pub fn resource_name(&self) -> &'static str {
|
||||
self.family.resource_name(self.bold, self.italic)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user