///|
/// Return the byte string cpdf add-text uses for measuring a visible line.
///
/// Raw mode and font-pack mode keep UTF-8 bytes. Selected simple-font mode
/// converts Unicode text to PDF character codes first, matching cpdf's
/// non-raw line measurement path.
pub fn pdf_addtext_measurement_bytes(
font : PdfFont?,
fontpack : PdfFontPack?,
raw : Bool,
text : String,
) -> @core.PdfBytes raise @core.PdfError {
if raw || fontpack is Some(_) {
@utf8.encode(text)
} else {
match font {
Some(font) => pdf_addtext_charcodes_of_utf8(font, text)
None => @utf8.encode(text)
}
}
}
///|
fn PdfDocument::pdf_addtext_measurement_bytes_for_page(
self : PdfDocument,
page : @page.PdfPage,
font : PdfFont?,
fontpack : PdfFontPack?,
fontname : @core.PdfName,
raw : Bool,
text : String,
) -> @core.PdfBytes raise @core.PdfError {
if raw || fontpack is Some(_) {
@utf8.encode(text)
} else {
match font {
Some(font) => pdf_addtext_charcodes_of_utf8(font, text)
None => {
let (_, font_object) = self.addtext_existing_font_resource(
page, fontname,
)
pdf_addtext_charcodes_of_utf8(self.read_font(font_object), text)
}
}
}
}
///|
/// Prepare one cpdf add-text line for later content and annotation emission.
///
/// This ports the source-level block which expands page-local replacement
/// fields, strips `%URL[text|url]` markup, measures the current and paragraph
/// line widths, and resolves the final cpdf placement offsets.
pub fn PdfDocument::addtext_prepare_line(
self : PdfDocument,
page : @page.PdfPage,
time : @date.PdfStrftimeTime,
lines : ArrayView[String],
replacements : ArrayView[(String, () -> String)],
font : PdfFont?,
fontpack : PdfFontPack?,
fontname : @core.PdfName,
font_size : Double,
text : String,
position : @geometry.PdfPosition,
relative_to_box? : @core.PdfName = pdf_page_mediabox_key(),
horizontal_offset? : Double = 0.0,
vertical_offset? : Double = 0.0,
justification? : @addtext.PdfAddTextJustification = PdfAddTextLeftJustify,
rotation? : @addtext.PdfAddTextRotation = PdfAddTextRot0,
raw? : Bool = false,
) -> @addtext.PdfAddTextPreparedLine raise @core.PdfError {
let processed = pdf_addtext_process_text_with_time(time, text, replacements)
let parsed = @addtext.pdf_addtext_get_urls_line(processed)
let expanded_lines = pdf_addtext_expand_lines_with_time(
time, lines, replacements,
)
let text_bytes = self.pdf_addtext_measurement_bytes_for_page(
page,
font,
fontpack,
fontname,
raw,
parsed.text,
)
let expanded_line_bytes : Array[@core.PdfBytes] = Array(
capacity=expanded_lines.length(),
)
for line in expanded_lines {
expanded_line_bytes.push(
self.pdf_addtext_measurement_bytes_for_page(
page, font, fontpack, fontname, raw, line,
),
)
}
let widths = self.addtext_line_widths(
page, font, fontpack, fontname, font_size, text_bytes, expanded_line_bytes,
)
let bounds = self.pdf_addtext_rectangle_bounds(page, relative_to_box)
let placement = @addtext.pdf_addtext_line_placement(
bounds,
position,
rotation,
widths.text_width,
widths.longest_width,
horizontal_offset,
vertical_offset,
justification,
)
{
text: parsed.text,
text_bytes,
urls: parsed.urls,
expanded_lines,
expanded_line_bytes,
widths,
placement,
}
}
///|
/// Compatibility wrapper for `PdfDocument::addtext_prepare_line`.
pub fn pdf_addtext_prepare_line(
document : PdfDocument,
page : @page.PdfPage,
time : @date.PdfStrftimeTime,
lines : ArrayView[String],
replacements : ArrayView[(String, () -> String)],
font : PdfFont?,
fontpack : PdfFontPack?,
fontname : @core.PdfName,
font_size : Double,
text : String,
position : @geometry.PdfPosition,
relative_to_box? : @core.PdfName = pdf_page_mediabox_key(),
horizontal_offset? : Double = 0.0,
vertical_offset? : Double = 0.0,
justification? : @addtext.PdfAddTextJustification = PdfAddTextLeftJustify,
rotation? : @addtext.PdfAddTextRotation = PdfAddTextRot0,
raw? : Bool = false,
) -> @addtext.PdfAddTextPreparedLine raise @core.PdfError {
document.addtext_prepare_line(
page,
time,
lines,
replacements,
font,
fontpack,
fontname,
font_size,
text,
position,
relative_to_box~,
horizontal_offset~,
vertical_offset~,
justification~,
rotation~,
raw~,
)
}