prawn

    Prawn's layout behaviour for MoonBit on moonbitlang/pagelayout: the document cursor and bounds, formatted text, font metrics, prawn-svg and prawn-table sizing

    pdf
    prawn
    svg
    typesetting
    Download zip
    Author
    Version
    0.2.0
    License
    MIT
    Last updated
    7 hours ago
    Downloads
    26

    #bobzhang/prawn

    The layout of Prawn 2.4.0, the Ruby PDF library Asciidoctor PDF 2.3.27 lays documents out with, for MoonBit, drawing through moonbitlang/pagelayout. It reproduces Prawn's measurements and decisions closely enough that bobzhang/asciidoctor-pdf matches Ruby Asciidoctor PDF's output.

    packagewhat it is
    bobzhang/prawnthe document cursor, bounds, columns and pages (Flow), formatted text (Fragment, Style) and its line wrapping (typeset_lines, Flow::typeset, Flow::typeset_box), font metrics of TrueType and the standard AFM fonts (FontCatalog, Face) with fallback fonts and icon fonts; and Document, Prawn's own API as far as it is ported (pages, the cursor and bounding boxes, text and text boxes, fonts, images, graphics)
    bobzhang/prawn/svga port of prawn-svg 0.34.2: SVG documents rendered into pagelayout graphic operations
    bobzhang/prawn/tableprawn-table 0.2.2's sizing: column widths and row heights

    Where Prawn calls back into Asciidoctor PDF (its fragment callbacks for inline images and destinations, and its font policy), a Flow takes Hooks from the document:

    let catalog = FontCatalog::load(files)
    let flow = Flow::new(catalog, setup, hooks={ ..Hooks::new(), base_family: "Noto Serif" })
    flow.start_new_page()
    flow.typeset(fragments, line_metrics(1.15, flow.font(style), style.size), style)

    The module was factored out of the PDF backend in asciidoctor.mbt, whose comparison with Ruby Asciidoctor PDF (scripts/pdf_compare.mbtx) checks it end to end. Document is checked against Ruby Prawn itself: operation scripts run through both, their PDFs and answers compared (docs/op-scripts.md in the repository). The goal here is a MoonBit Prawn as good as the Ruby original; PLAN.md has the plan.

    #License

    MIT, except for the third-party material listed in NOTICE: the prawn-svg port (MIT, svg/LICENSE) and the parts adapted from Prawn and prawn-table (Matz's terms for Ruby, LICENSES/LICENSE-prawn).

    PrawnError

    pub(all) suberror PrawnError {
    CannotFit
    IncompatibleStringEncoding(String)
    ArgumentError(String)
    UnknownFont(String)
    BadFontFamily(String)
    EmptyGraphicStateStack
    UnsupportedImageType(String)
    Unsupported(String)
    }

    The errors Prawn raises (Prawn::Errors).

    PrawnError::ruby_class

    fn PrawnError::ruby_class(self : PrawnError) -> String

    The Ruby class of the error, as Prawn names it.

    Alignment

    pub(all) enum Alignment {
    Left
    Center
    Right
    Justify
    } derive(Eq)

    Alignment::equal

    fn Alignment::equal(Alignment, Alignment) -> Bool

    Alignment::not_equal

    fn Alignment::not_equal(x : Alignment, y : Alignment) -> Bool

    Bounds

    pub(all) struct Bounds {
    left : Double
    bottom : Double
    width : Double
    height : Double
    absolute_left : Double
    absolute_top : Double
    }

    The bounds content is set in, as Prawn's bounds reports them.

    CodeBackground

    pub(all) enum CodeBackground {
    Gap(Double, Bool)
    FullLine
    } derive(Eq)

    How far the background of a fragment of a highlighted source block reaches, when not just its glyph box.

    CodeBackground::equal

    CodeBackground::not_equal

    fn CodeBackground::not_equal(x : CodeBackground, y : CodeBackground) -> Bool

    Columns

    pub(all) struct Columns {
    count : Int
    stride : Double
    current : Int
    }

    A column box (Prawn's ColumnBox with reflow_margins): the bounds are split into count columns gap apart; running out of room moves to the next column at the box's top, and past the last one to a new page, where the box starts at the page's top.

    Document

    pub struct Document {
    family : String
    size : Double
    // private fields
    }

    A Prawn document.

    Document::bounding_box

    fn Document::bounding_box(self : Document, at : (Double, Double), width : Double, height? : Double, body : () -> Unit raise) -> Unit raise

    Prawn's bounding_box: body set in a box whose top left corner is at (relative to the bottom left of the current bounds), width wide and height tall, or stretchy. Afterwards the position is below the current box (when it has a height), or where it was when nothing was set.

    Document::bounds

    fn Document::bounds(self : Document) -> Bounds

    Prawn's bounds.

    Document::canvas

    fn Document::canvas(self : Document, body : () -> Unit raise) -> Unit raise

    Prawn's canvas: body in a box the size of the page, with no parent (a new page makes the margin box current again), and the position left where body leaves it.

    Document::circle

    fn Document::circle(self : Document, center : (Double, Double), radius : Double) -> Unit

    Prawn's circle.

    Document::close_and_stroke

    fn Document::close_and_stroke(self : Document) -> Unit

    Prawn's close_and_stroke.

    Document::close_path

    fn Document::close_path(self : Document) -> Unit

    Prawn's close_path.

    Document::column_box

    fn Document::column_box(self : Document, at : (Double, Double), width : Double, height? : Double, columns? : Int, spacer? : Double, reflow_margins? : Bool, body : () -> Unit raise) -> Unit raise

    Prawn's column_box: body set in columns columns spacer apart (by default the font size) in a box at at, width wide and height tall or stretchy; content runs down a column, then to the next, then to a new page. Afterwards the position is at the current box's bottom.

    Document::cursor

    fn Document::cursor(self : Document) -> Double

    Prawn's cursor: how far the current position is above the bottom of the bounds (always 0 in a stretchy box, whose bottom is the position).

    Document::curve

    fn Document::curve(self : Document, origin : (Double, Double), dest : (Double, Double), bounds : ((Double, Double), (Double, Double))) -> Unit

    Prawn's curve.

    Document::curve_to

    fn Document::curve_to(self : Document, dest : (Double, Double), bounds : ((Double, Double), (Double, Double))) -> Unit

    Prawn's curve_to: a Bézier curve to dest with control points bounds.

    Document::dash

    fn Document::dash(self : Document, lengths : Array[Double], space? : Double, phase? : Double) -> Unit raise PrawnError

    Prawn's dash: dashes lengths long (one length: dashes that long with gaps space, by default as long), starting phase into the pattern.

    Document::default_leading

    fn Document::default_leading(self : Document) -> Double

    Prawn's default_leading (without a value).

    Document::draw_text

    fn Document::draw_text(self : Document, text : String, at~ : (Double, Double), size? : Double, style? : FontStyle, rotate? : Double, kerning? : Bool) -> Unit raise

    Prawn's draw_text: text on one line, its baseline starting at at (a point of the bounds), in the current font at size (the current size), in style (by default the current one), kerned unless kerning is false, turned rotate degrees about at. No wrapping, no page break; the cursor does not move.

    Document::ellipse

    fn Document::ellipse(self : Document, center : (Double, Double), r1 : Double, r2? : Double) -> Unit

    Prawn's ellipse: four Bézier curves around center, then a move to the center.

    Document::fallback_fonts

    fn Document::fallback_fonts(self : Document, fonts : Array[String]) -> Unit

    Prawn's fallback_fonts: the fonts (families, standard fonts, files) a character text's font lacks is looked for in, in order.

    Document::fill

    fn Document::fill(self : Document, even_odd? : Bool) -> Unit

    Prawn's fill.

    Document::fill_and_stroke

    fn Document::fill_and_stroke(self : Document, even_odd? : Bool) -> Unit

    Prawn's fill_and_stroke: PDF's b, which closes the current subpath before it fills and strokes.

    Document::float

    fn Document::float(self : Document, body : () -> Unit raise) -> Unit raise

    Prawn's float: body, then back to the page and position it started at.

    Document::font

    fn Document::font(self : Document, name : String, style? : FontStyle, size? : Double, body? : () -> Unit raise) -> Unit raise

    Prawn's font(name, style:, size:): the font text is set in from now on (within body only, when given), name being a family (in style, by default its normal one) or a font of its own (a standard font's name, such as Times-Bold). Raises UnknownFont for a name Prawn does not know.

    Document::font_class

    fn Document::font_class(self : Document) -> String

    The Ruby class of the current font (Prawn's font.class): AFM for a standard font, TTF for one read from a file.

    Document::font_families_update

    fn Document::font_families_update(self : Document, family : String, files : Array[(FontStyle, String)]) -> Unit

    Prawn's font_families.update(family => { style => file }): family is set in files from now on, each the path of a TrueType font (read through the document's assets when used).

    Document::font_name

    fn Document::font_name(self : Document) -> String

    The current font's name (Prawn's font.name): a standard font's own name (Times-Bold).

    Document::font_size

    fn Document::font_size(self : Document) -> Double

    Prawn's font_size (without a size): the size text is set at.

    Document::formatted_text

    fn Document::formatted_text(self : Document, fragments : Array[TextFragment], size? : Double, style? : FontStyle, align? : Alignment, leading? : Double, draw_text_callback? : (String, (Double, Double), Bool) -> Unit raise PrawnError) -> Unit raise PrawnError

    Prawn's formatted_text: fragments flowed from the cursor as text flows a string.

    Document::go_to_page

    fn Document::go_to_page(self : Document, number : Int) -> Unit

    Prawn's go_to_page (from 1): back to an existing page, at the top of its margin box.

    Document::height_of

    fn Document::height_of(self : Document, string : String, size? : Double, style? : FontStyle, width? : Double, leading? : Double) -> Double raise PrawnError

    Prawn's height_of: how tall string would be set by text in boxes width wide (the bounds' width), with the line gap and leading after it (Prawn's final gap).

    Document::horizontal_line

    fn Document::horizontal_line(self : Document, x1 : Double, x2 : Double, at? : Double) -> Unit

    Prawn's horizontal_line: from x1 to x2 at at (by default the cursor).

    Document::horizontal_rule

    fn Document::horizontal_rule(self : Document) -> Unit

    Prawn's horizontal_rule: across the bounds at the cursor.

    Document::image

    fn Document::image(self : Document, file : String, at? : (Double, Double), width? : Double, height? : Double, scale? : Double, fit? : (Double, Double), position? : ImagePosition, vposition? : ImageVPosition) -> ImageInfo raise PrawnError

    Prawn's image: the image in file (read through the document's assets) drawn with its top left at at (a point of the bounds), or, without at, in the flow of the page at position across the bounds and vposition down them (by default at the position, which moves down past it, to the next page when it does not fit); width and height (either keeps the proportions), scale or fit size it, else its pixels are points. What Prawn knows of it is returned.

    Document::indent

    fn Document::indent(self : Document, left : Double, right? : Double, body : () -> Unit raise) -> Unit raise

    Prawn's indent: body set with the current bounds narrowed by left and right; afterwards the padding comes off the bounds current then.

    Document::line

    fn Document::line(self : Document, from : (Double, Double), to : (Double, Double)) -> Unit

    Prawn's line.

    Document::line_to

    fn Document::line_to(self : Document, x : Double, y : Double) -> Unit

    Prawn's line_to.

    Document::move_cursor_to

    fn Document::move_cursor_to(self : Document, cursor : Double) -> Unit

    Prawn's move_cursor_to: the cursor at cursor points above the bottom of the bounds (as they are before the move).

    Document::move_down

    fn Document::move_down(self : Document, amount : Double) -> Unit

    Prawn's move_down.

    Document::move_to

    fn Document::move_to(self : Document, x : Double, y : Double) -> Unit

    Prawn's move_to.

    Document::move_up

    fn Document::move_up(self : Document, amount : Double) -> Unit

    Prawn's move_up.

    Document::new

    fn Document::new(size? : (Double, Double), layout? : String, margin? : Array[Double], assets? : (String) -> Bytes?) -> Document raise

    A document with pages size (points; Prawn's default is LETTER) in layout ("portrait" or "landscape") with margin (Prawn's default 36 all round). Font files are read through assets, given a path as it was named (none by default). Like Prawn, it starts with a page.

    Document::on_warning

    fn Document::on_warning(self : Document, handler : (String) -> Unit) -> Unit

    Where Prawn's warnings go (Ruby's Kernel#warn): handler gets each message. By default they go nowhere.

    Document::pad

    fn Document::pad(self : Document, amount : Double, body : () -> Unit raise) -> Unit raise

    Prawn's pad: down by amount before and after body.

    Document::pad_bottom

    fn Document::pad_bottom(self : Document, amount : Double, body : () -> Unit raise) -> Unit raise

    Prawn's pad_bottom: body, then down by amount.

    Document::pad_top

    fn Document::pad_top(self : Document, amount : Double, body : () -> Unit raise) -> Unit raise

    Prawn's pad_top: down by amount, then body.

    Document::page_count

    fn Document::page_count(self : Document) -> Int

    Prawn's page_count.

    Document::page_number

    fn Document::page_number(self : Document) -> Int

    Prawn's page_number (from 1).

    Document::polygon

    fn Document::polygon(self : Document, points : Array[(Double, Double)]) -> Unit

    Prawn's polygon: closed.

    Document::rectangle

    fn Document::rectangle(self : Document, point : (Double, Double), width : Double, height : Double) -> Unit

    Prawn's rectangle: point is the top left corner.

    Document::render

    fn Document::render(self : Document) -> Bytes raise

    The PDF.

    Document::rotate

    fn Document::rotate(self : Document, angle : Double, origin? : (Double, Double), body : () -> Unit raise) -> Unit raise

    Prawn's rotate with a block: angle degrees counterclockwise, about the page's origin or origin (a point of the bounds).

    Document::rounded_polygon

    fn Document::rounded_polygon(self : Document, radius : Double, points : Array[(Double, Double)]) -> Unit

    Prawn's rounded_polygon: corners rounded with radius, closed.

    Document::rounded_rectangle

    fn Document::rounded_rectangle(self : Document, point : (Double, Double), width : Double, height : Double, radius : Double) -> Unit

    Prawn's rounded_rectangle.

    Document::save_graphics_state

    fn Document::save_graphics_state(self : Document, body : () -> Unit raise) -> Unit raise

    Prawn's save_graphics_state with a block: what the block changes in the graphics state is undone after it.

    Document::scale

    fn Document::scale(self : Document, factor : Double, origin? : (Double, Double), body : () -> Unit raise) -> Unit raise

    Prawn's scale with a block, about the page's origin or origin.

    Document::set_cap_style

    fn Document::set_cap_style(self : Document, cap :
    LineCap
    ) -> Unit

    Prawn's cap_style=.

    Document::set_default_leading

    fn Document::set_default_leading(self : Document, leading : Double) -> Unit

    Prawn's default_leading=: the leading text is set with when none is given.

    Document::set_fill_color

    fn Document::set_fill_color(self : Document, color :
    Color
    ) -> Unit

    Prawn's fill_color=: what fills and text are painted with.

    Document::set_font_size

    fn Document::set_font_size(self : Document, size : Double) -> Unit

    Prawn's font_size=.

    Document::set_join_style

    fn Document::set_join_style(self : Document, join :
    LineJoin
    ) -> Unit

    Prawn's join_style=.

    Document::set_line_width

    fn Document::set_line_width(self : Document, width : Double) -> Unit

    Prawn's line_width=.

    Document::set_stroke_color

    fn Document::set_stroke_color(self : Document, color :
    Color
    ) -> Unit

    Prawn's stroke_color=.

    Document::span

    fn Document::span(self : Document, width : Double, position? : SpanPosition, body : () -> Unit raise) -> Unit raise

    Prawn's span: body in a column width wide across the margin box (whatever box is current), at position, from the current position; a stretchy box, so the position ends below what body set.

    Document::start_new_page

    fn Document::start_new_page(self : Document, layout? : String, size? : (Double, Double)) -> Unit

    Prawn's start_new_page.

    Document::stroke

    fn Document::stroke(self : Document) -> Unit

    Prawn's stroke.

    Document::stroke_axis

    fn Document::stroke_axis(self : Document, at? : (Double, Double), width? : Double, height? : Double, step_length? : Double, negative_axes_length? : Double, color? :
    Color
    ) -> Unit raise

    Prawn's stroke_axis: dashed axes from at (a point of the bounds, by default their origin), width and height long (to the bounds' edge by default) and negative_axes_length back, in color, with a dot and a label every step_length points.

    Document::stroke_bounds

    fn Document::stroke_bounds(self : Document) -> Unit

    Prawn's stroke_bounds.

    Document::text

    fn Document::text(self : Document, string : String, size? : Double, style? : FontStyle, align? : Alignment, leading? : Double, inline_format? : Bool, draw_text_callback? : (String, (Double, Double), Bool) -> Unit raise PrawnError) -> Unit raise PrawnError

    Prawn's text: string flowed from the cursor within the bounds, across pages as needed; the cursor ends below it.

    Document::text_box

    fn Document::text_box(self : Document, string : String, at? : (Double, Double), width? : Double, height? : Double, size? : Double, style? : FontStyle, align? : Alignment, valign? : VerticalAlignment, overflow? : Overflow, min_font_size? : Double, leading? : Double, rotate? : Double, rotate_around? : String, draw_text_callback? : (String, (Double, Double), Bool) -> Unit raise PrawnError) -> String raise

    Prawn's text_box: string set in a box at at (a point of the bounds, by default their top left), width wide (by default to the bounds' right) and height tall (by default to the bottom of the bounds, or of the box a stretchy box is in), as overflow says; the text that did not fit is returned. The cursor does not move.

    Document::transformation_matrix

    fn Document::transformation_matrix(self : Document, matrix : (Double, Double, Double, Double, Double, Double), body : () -> Unit raise) -> Unit raise

    Prawn's transformation_matrix with a block: body drawn under the matrix [a, b, c, d, e, f] in Prawn's page space (y up).

    Document::translate

    fn Document::translate(self : Document, x : Double, y : Double, body : () -> Unit raise) -> Unit raise

    Prawn's translate with a block.

    Document::transparent

    fn Document::transparent(self : Document, opacity : Double, stroke_opacity? : Double, body : () -> Unit raise) -> Unit raise

    Prawn's transparent: body drawn with fill opacity opacity and stroke opacity stroke_opacity (by default the same), each clamped to 0 to 1.

    Document::undash

    fn Document::undash(self : Document) -> Unit

    Prawn's undash.

    Document::vertical_line

    fn Document::vertical_line(self : Document, y1 : Double, y2 : Double, at~ : Double) -> Unit

    Prawn's vertical_line.

    Document::width_of

    fn Document::width_of(self : Document, string : String, size? : Double, style? : FontStyle, kerning? : Bool) -> Double raise PrawnError

    Prawn's width_of: how wide string is set in the current font at size (the current font size), with the font's kerning only when kerning asks for it (Prawn does not apply the document's default here).

    Document::with_font_size

    fn Document::with_font_size(self : Document, points : Double, body : () -> Unit raise) -> Unit raise

    Prawn's font_size(points) { … }: body with text set at points, then back to the size before (only when body returns: Prawn has no ensure here).

    Face

    pub(all) struct Face {
    metrics :
    FaceMetrics

    ascender : Int
    descender : Int
    line_gap : Int
    kern : Map[Int, Double]
    standard : Bool
    }

    One face of the font catalog, with the metrics Prawn (the layout engine behind Ruby asciidoctor-pdf) derives from it. Prawn works in 1/1000 em and truncates every metric to an integer there; so does this.

    Face::ascender_pt

    fn Face::ascender_pt(self : Face, size : Double) -> Double

    Face::descender_pt

    fn Face::descender_pt(self : Face, size : Double) -> Double

    Positive depth below the baseline.

    Face::height_pt

    fn Face::height_pt(self : Face, size : Double) -> Double

    Prawn's font.height: ascender − descender + line gap.

    Face::kerning

    fn Face::kerning(self : Face, left : Int, right : Int) -> Double

    Kerning between two codepoints, 1/1000 em (negative tightens).

    Face::line_gap_pt

    fn Face::line_gap_pt(self : Face, size : Double) -> Double

    Face::prawn_width

    fn Face::prawn_width(self : Face, codepoint : Int) -> Double

    Prawn's glyph width in 1/1000 em (truncated), used to break lines as Prawn does.

    Flow

    pub(all) struct Flow {
    catalog : FontCatalog
    setup : PageSetup
    hooks : Hooks
    model :
    PageModel

    scratch : Bool
    page_top : Double
    top : Double
    bottom : Double
    page : Int
    y : Double
    left : Double
    right : Double
    columns : Columns?
    last_line : (Line, Int, Double)?
    last_line_first : Bool
    taring : Int
    inked : Bool
    first_break_empty : Bool?
    page_margins : (Int) -> (Double, Double)?
    margin_left : Double
    margin_right : Double
    page_width_now : Double
    page_height_now : Double
    }

    Flow::add_anchor

    fn Flow::add_anchor(self : Flow, name : String, x : Double, y : Double) -> Unit

    Flow::advance_page

    fn Flow::advance_page(self : Flow) -> Unit

    Move to the next page, creating it unless an earlier pass already did (a block's background revisits pages its content spilled onto); in a column box, to the next column first (Prawn's move_past_bottom).

    Flow::at_page_top

    fn Flow::at_page_top(self : Flow) -> Bool

    Flow::column_box

    fn Flow::column_box(self : Flow, count : Int, gap : Double, body : () -> Unit) -> Unit

    Lay out body in count columns gap apart, starting at the cursor (Prawn's column_box with reflow_margins: true); the cursor ends where the first column did, or, when the box went on past it, at the bottom of the last one.

    Flow::cursor

    fn Flow::cursor(self : Flow) -> Double

    Space left above the bottom margin (Prawn's cursor).

    Flow::dest_x

    fn Flow::dest_x(self : Flow) -> Double

    A named destination for the block at the cursor (asciidoctor-pdf's add_dest_for_block).

    Flow::fits

    fn Flow::fits(self : Flow, height : Double, y? : Double) -> Bool

    Whether height fits below the cursor (prawn-table's fits_on_page?).

    Flow::font

    fn Flow::font(self : Flow, style : Style) -> Face

    Flow::go_to_page

    fn Flow::go_to_page(self : Flow, index : Int) -> Unit

    Make page index the current page (Prawn's go_to_page), in its margins; the cursor is left where it is.

    Flow::height_of

    fn Flow::height_of(self : Flow, fragments : Array[Fragment], metrics : LineMetrics, base : Style, normalize_line_height? : Bool, width? : Double) -> Double

    The height typeset would take for fragments in the current bounds (asciidoctor-pdf's height_of_typeset_text), ignoring page breaks.

    Flow::indent

    fn[T] Flow::indent(self : Flow, left : Double, right : Double, body : () -> T) -> T

    Flow::ink_line

    fn Flow::ink_line(self : Flow, line : Line, x0 : Double, baseline : Double) -> Unit

    Draw one placed line on the current page.

    Flow::line_items

    fn Flow::line_items(self : Flow, line : Line, x0 : Double, baseline : Double) -> Array[
    PageItem
    ]

    The items that draw one placed line with its left edge at x0 and its baseline at baseline: backgrounds, glyph runs, decorations, link regions and anchors.

    Flow::margin

    fn Flow::margin(self : Flow, amount : Double) -> Unit

    asciidoctor-pdf's margin: nothing at the top of a page, a move down when it fits, else a new page.

    Flow::mark

    fn Flow::mark(self : Flow) -> Mark

    Flow::move_down

    fn Flow::move_down(self : Flow, amount : Double) -> Unit

    Flow::new

    fn Flow::new(catalog : FontCatalog, setup : PageSetup, hooks? : Hooks, scratch? : Bool) -> Flow

    A flow over pages set up as setup, its text set from catalog, the document answering hooks; scratch for a dry run.

    Flow::on_verso

    fn Flow::on_verso(self : Flow) -> Bool

    Whether the current page is a verso page (an even page number).

    Flow::pad_bottom

    fn Flow::pad_bottom(self : Flow, amount : Double) -> Unit

    The bottom padding of a padded box: a move down when it fits, else the next page (Prawn's move_past_bottom).

    Flow::page_h

    fn Flow::page_h(self : Flow) -> Double

    The current page's height (the PDF's y axis is measured up from its bottom).

    Flow::push

    fn Flow::push(self : Flow, item :
    PageItem
    ) -> Unit

    Flow::start_new_page

    fn Flow::start_new_page(self : Flow, layout? : String, size? : (Double, Double)) -> Unit

    Flow::tared

    fn Flow::tared(self : Flow, body : () -> Unit) -> Unit

    Ink body as tared content: captions and backgrounds, which do not keep a block on a page by themselves.

    Flow::text

    fn Flow::text(self : Flow) -> TextContext

    What the flow sets text with.

    Flow::to_last_column

    fn Flow::to_last_column(self : Flow) -> Unit

    In a column box, move to its last column (Prawn's bounds.current_column = bounds.last_column), so the next page break starts a new page.

    Flow::typeset

    fn Flow::typeset(self : Flow, fragments : Array[Fragment], metrics : LineMetrics, base : Style, align? : Alignment, bottom_gutter? : Double, hanging_indent? : Double, normalize_line_height? : Bool, first_line_style? : Style, text_indent? : Double) -> Unit

    Ink formatted text at the cursor, flowing onto new pages as needed — asciidoctor-pdf's typeset_text over Prawn's text.

    Flow::typeset_box

    fn Flow::typeset_box(self : Flow, fragments : Array[Fragment], metrics : LineMetrics, base : Style, align~ : Alignment, x~ : Double, width~ : Double, height~ : Double, text_indent~ : Double) -> (Array[Fragment], Double?)

    Prawn's formatted text box with a height (text_box): the lines of fragments set width wide from x (the first one text_indent further in, Prawn's indent_paragraphs), the first hanging from the cursor plus the line padding, as many as fit in height. Returns the fragments that did not fit and the baseline of the last line inked (None when none was); the cursor does not move.

    Flow::underlay

    fn Flow::underlay(self : Flow, start : Mark, make : (Double, Double, Bool, Bool) -> Array[
    PageItem
    ]) -> Unit

    Slide make(page, top, bottom, first, last) underneath everything inked since start, on every page from start to the cursor: the painter's order of a background drawn before its content, without a dry run.

    Flow::width

    fn Flow::width(self : Flow) -> Double

    Flow::width_of

    fn Flow::width_of(self : Flow, text : String, style : Style) -> Double

    Prawn's width_of a plain string in style's font, trailing spaces included (asciidoctor-pdf's rendered_width_of_string): the truncated glyph widths, kerned.

    FontCatalog

    pub struct FontCatalog {
    faces : Map[String, Face]
    registry :
    FontRegistry

    legacy_icons : Map[String, String]
    // private fields
    }

    The font catalog of the theme: family → the four styles, and the pagelayout registry holding them, which the renderer draws with; and the icon sets (icons=font), each a font family of its own.

    FontCatalog::has_icons

    fn FontCatalog::has_icons(self : FontCatalog) -> Bool

    Whether the catalog can draw font icons (it has icon sets).

    FontCatalog::icon_glyph

    fn FontCatalog::icon_glyph(self : FontCatalog, set : String, name : String) -> String?

    The glyph of icon name in icon set set, when the catalog has both.

    FontCatalog::load

    fn FontCatalog::load(files : Array[(String, Bool, Bool, Bytes)], icon_sets? : Array[IconSet], legacy_icon_mapping? : String, fallbacks? : Array[String]) -> FontCatalog raise

    Load a catalog from font files: (family, bold, italic, TrueType bytes), with the icon sets icons=font draws from, asciidoctor-pdf's mapping of Font Awesome 4 icon names (fa-legacy-mapping.yml), and the families a character the text's font lacks is looked for in (fallbacks).

    FontCatalog::svg_families

    fn FontCatalog::svg_families(self : FontCatalog) -> Array[(String, Array[String])]

    The families Prawn knows (font_families), with their styles: the catalog's (not the icon sets'), and Prawn's built-in AFM families.

    FontStyle

    pub(all) enum FontStyle {
    Normal
    Bold
    Italic
    BoldItalic
    }

    A style of a font family (Prawn's :normal, :bold, :italic, :bold_italic).

    Fragment

    pub(all) struct Fragment {
    text : String
    style : Style
    anchor : String?
    }

    A run of text in one style. An anchor fragment has no text and marks a named destination at its position.

    FragmentCallback

    pub(all) struct FragmentCallback {
    render_behind : (PlacedFragment) -> Unit raise PrawnError?
    render_in_front : (PlacedFragment) -> Unit raise PrawnError?
    }

    A fragment callback (Prawn's callback object): render_behind before the text is drawn, render_in_front after it and its decorations and links. Not called in dry runs (measuring, shrinking, aligning).

    Hooks

    pub(all) struct Hooks {
    base_family : String
    unknown_font : (String) -> Unit
    image_size : (Int, Double, Double) -> (Double, Double, Bool)
    image_items : (Flow, Int, Double, Double, Double, Double) -> Array[
    PageItem
    ]
    anchor_inked : (String, Int) -> Unit
    fragment_inked : (Int) -> Unit
    }

    What the document does where Prawn calls back into asciidoctor-pdf: the fragment callbacks it registers (InlineImageArranger and InlineImageRenderer for inline images, InlineDestinationMarker for anchors), and its font policy. One per document: a font catalog may be shared between documents, these may not.

    Hooks::new

    fn Hooks::new(base_family? : String) -> Hooks

    Hooks for a document without inline images, whose unknown fonts go unreported.

    IconSet

    pub(all) struct IconSet {
    name : String
    font : Bytes
    legend : String
    }

    An icon font of prawn-icon (data/fonts/<set>/): the set's name (fas, far, fab, fi, pf), its TrueType font and its legend, which names each glyph: name: glyph lines (fire: "…", under the set's key in prawn-icon's <set>.yml; the bundled @icons.fonts() have their own tables, <set>/glyphs.txt, made from the fonts' projects).

    ImageInfo

    pub(all) struct ImageInfo {
    kind : String
    width : Int
    height : Int
    }

    What Prawn knows of an image: its type and its size in pixels (Prawn's Prawn::Images::PNG / JPG).

    ImagePosition

    pub(all) enum ImagePosition {
    ImageLeft
    ImageCenter
    ImageRight
    ImageAt(Double)
    }

    Where an image goes across the bounds, in the flow (Prawn's :position).

    ImageVPosition

    pub(all) enum ImageVPosition {
    ImageTop
    ImageMiddle
    ImageBottom
    ImageDown(Double)
    }

    Where an image goes down the bounds (Prawn's :vposition): by default at the position, in the flow of the page.

    Item

    pub(all) struct Item {
    unit : Int
    fragment : Int
    fit : Double
    draw : Double
    kern : Double
    hard_break : Bool
    anchor : String?
    offset : Int
    }

    Line

    pub(all) struct Line {
    runs : Array[LineRun]
    anchors : Array[(String, Double)]
    fit_width : Double
    ascender : Double
    descender : Double
    height : Double
    empty_links : Array[(Double, Style, Face)]
    images : Array[(Double, Int, Double, Double, Bool, Style, Face)]
    marks : Array[(Double, Style, Face)]
    held : Array[(Int, Double, Style, Face)]
    }

    LineMetrics

    pub(all) struct LineMetrics {
    leading : Double
    padding_top : Double
    padding_bottom : Double
    }

    Prawn's line metrics for a line height factor (asciidoctor-pdf's calc_line_metrics).

    LineRun

    pub(all) struct LineRun {
    fragment : Int
    text : String
    style : Style
    face : Face
    x : Double
    advances : Array[Double]
    width : Double
    }

    One placed run of a line; x is relative to the line's left edge.

    Mark

    pub(all) struct Mark {
    page : Int
    y : Double
    item : Int
    }

    A point in the flow: page, cursor, and how many items the page held, so backgrounds can be slid underneath content inked after it.

    Overflow

    pub(all) enum Overflow {
    Truncate
    ShrinkToFit
    Expand
    }

    What a text box does with text that does not fit (overflow).

    PageSetup

    pub(all) struct PageSetup {
    width : Double
    height : Double
    margin_top : Double
    margin_right : Double
    margin_bottom : Double
    margin_left : Double
    }

    The page size and margins a document starts with (asciidoctor-pdf's build_pdf_options: page_size, page_layout, page_margin), in points.

    PlacedFragment

    pub(all) struct PlacedFragment {
    text : String
    left : Double
    baseline : Double
    width : Double
    height : Double
    top : Double
    bottom : Double
    }

    A piece of a fragment as it is drawn (Prawn's fragment, as callbacks see it), in the coordinates of the bounds: its left side, baseline, width, and its font's top (baseline plus ascender) and bottom (baseline less descender).

    SpanPosition

    pub(all) enum SpanPosition {
    SpanLeft
    SpanCenter
    SpanRight
    SpanAt(Double)
    }

    Where span puts its column across the margin box.

    Style

    pub(all) struct Style {
    family : String
    size : Double
    bold : Bool
    italic : Bool
    color :
    Color

    link :
    LinkTarget
    ?
    background :
    Color
    ?
    script : Int
    border_offset : Double
    underline : Bool
    strike : Bool
    wj : Bool
    image : Int
    callback : Int
    doc_bold : Bool
    doc_italic : Bool
    font_set : Bool
    text_transform : String?
    code_background : CodeBackground?
    linenum : Bool
    line_mark : Bool
    wrap_break : Bool
    } derive(Eq)

    Character formatting of a fragment.

    Style::equal

    fn Style::equal(Style, Style) -> Bool

    Style::face_style

    fn Style::face_style(self : Style) -> (Bool, Bool)

    The (bold, italic) face a fragment is set in, as Prawn's arranger picks it (apply_font_settings): a fragment whose markup names a font or a bold or italic style takes exactly those styles; any other fragment is set in the document font, whatever its style.

    Style::not_equal

    fn Style::not_equal(x : Style, y : Style) -> Bool

    TextContext

    pub(all) struct TextContext {
    catalog : FontCatalog
    hooks : Hooks
    }

    What text is set with: the font catalog and the document's hooks.

    TextContext::face

    fn TextContext::face(self : TextContext, family : String, bold : Bool, italic : Bool) -> Face

    TextFragment

    pub(all) struct TextFragment {
    text : String
    bold : Bool
    italic : Bool
    underline : Bool
    strikethrough : Bool
    subscript : Bool
    superscript : Bool
    font : String?
    size : Double?
    color : String?
    cmyk : Array[Double]?
    character_spacing : Double?
    link : String?
    anchor : String?
    callbacks : Array[FragmentCallback]
    }

    A fragment of formatted text (Prawn's fragment hash). Unset fields take the document's (font, size, fill colour).

    TextFragment::new

    fn TextFragment::new(text : String) -> TextFragment

    A plain fragment.

    VerticalAlignment

    pub(all) enum VerticalAlignment {
    Top
    Center
    Bottom
    }

    Where a text box puts its lines vertically (valign).

    build_items

    fn build_items(fragments : Array[Fragment], ctx : TextContext, available? : Double) -> (Array[Item], Array[Face])

    color_of_hex

    fn color_of_hex(hex : String) ->
    Color
    raise PrawnError

    A colour Prawn names in hex ("FFCC00": six digits, no #).

    dashed_hrule

    fn dashed_hrule(x1 : Double, x2 : Double, y : Double, width : Double, color :
    Color
    ) -> Array[
    PageItem
    ]

    A dashed horizontal rule (dashes and gaps four times its width, as Prawn's dash in asciidoctor-pdf's dashed style), as filled segments.

    default_font_files

    fn default_font_files() -> Array[(String, Bool, Bool, String)]

    The file names of the default theme's catalog (asciidoctor-pdf's data/fonts): (family, bold, italic, file).

    default_icon_font_files

    fn default_icon_font_files() -> Array[(String, String, String)]

    The icon sets of prawn-icon 3.0.0 (its data/fonts): (set, font file, legend file), relative to that directory.

    face_key

    fn face_key(family : String, bold : Bool, italic : Bool) -> String

    hrule

    fn hrule(x1 : Double, x2 : Double, y : Double, width : Double, color :
    Color
    ) ->
    PageItem

    A horizontal rule width thick centred on y.

    line_extent

    fn line_extent(line : Line, base_face : Face, size : Double, normalize_line_height : Bool) -> (Double, Double, Double)

    The ascender, descender and height a placed line takes: its fragments' largest, or the document font's for an empty line. With normalize_line_height, the document font's count on every line, as asciidoctor-pdf's arranger puts a zero-width space in that font at the start of each line (so a line of code in a list takes the prose line's height, not the smaller one of the monospace font).

    line_metrics

    fn line_metrics(factor : Double, face : Face, size : Double) -> LineMetrics

    margins_of

    fn margins_of(values : Array[Double]) -> (Double, Double, Double, Double)

    Margins as Prawn takes them (margin: 36, [v, h], [t, h, b], [t, r, b, l], CSS order): top, right, bottom, left.

    page_size_named

    fn page_size_named(name : String) -> (Double, Double)?

    The size of a page Prawn names ("A4"), in points.

    parse_inline_format

    fn parse_inline_format(string : String) -> Array[TextFragment] raise PrawnError

    Prawn's inline format (Text::Formatted::Parser.format): <b>/ <strong>, <i>/<em>, <u>, <strikethrough>, <sub>, <sup>, <font name size>, <color rgb>, <link href anchor>/<a>, <br>, and &lt;, &gt;, &amp;. A < that starts no tag is dropped, as Prawn's scan skips it.

    pdf_anchor_name

    fn pdf_anchor_name(id : String) -> String

    The PDF destination name for an id (asciidoctor-pdf's derive_anchor_from_id): the id itself when it is ASCII, else 0x and the hex of its UTF-8 bytes.

    rect_item

    fn rect_item(x : Double, y : Double, w : Double, h : Double, fill? :
    Color
    , stroke? :
    Color
    , stroke_width? : Double) ->
    PageItem

    rgb_hex

    fn rgb_hex(value : Int) ->
    Color

    ruby_number

    fn ruby_number(x : Double) -> String

    A number as Ruby prints a whole one: without a fraction.

    source_wrap

    fn source_wrap(fragments : Array[Fragment], ctx : TextContext, width : Double) -> Array[Fragment]?

    asciidoctor-pdf's SourceWrap: fragments (a numbered source block, each line starting with its line number, Style::linenum) with every line that wraps in width broken where it wraps: a line break, then the number's blank (a no-break space and spaces as wide as the number, in no style of its own), the line's highlight mark if it has one (Style::line_mark), and the rest of the line without the blanks it starts with. A number (or blank) wider than the line breaks before its trailing blanks, the line's text going on a line of its own, as Prawn breaks it. Each pass breaks the first line that wraps, consuming some of the source's text or of a number's blanks, so the passes end.

    None when a line cannot fit, as Prawn raises Prawn::Errors::CannotFit: its number (or blank) without its blanks is wider than the line, or it would hold nothing else.

    typeset_lines

    fn typeset_lines(fragments : Array[Fragment], ctx : TextContext, width : Double, align : Alignment, first_width? : Double, indent_paragraphs? : Bool, paragraphs? : Bool) -> Array[Line]

    Break fragments into lines of at most width (the first line first_width, and with indent_paragraphs also each line after a hard break: Prawn's indent_paragraphs starts a paragraph there) and place them.

    vrule

    fn vrule(x : Double, y1 : Double, y2 : Double, width : Double, color :
    Color
    ) ->
    PageItem

    A vertical rule width thick centred on x.