///|
fn pdf_truetype_hmtx_widths(
  data : BytesView,
  hmtx : @truetype.PdfTrueTypeTableRecord,
  count : Int,
) -> Array[Int] raise @core.PdfError {
  let widths : Array[Int] = []
  for index in 0.. Int {
  let mut max_width = 0
  for width in widths {
    if width > max_width {
      max_width = width
    }
  }
  pdf_truetype_pdf_unit(units_per_em, max_width)
}

///|
fn pdf_truetype_flags(symbolic : Bool, italic_angle : Int) -> Int {
  let italic = if italic_angle != 0 { 1 } else { 0 }
  let symbolic_bit = if symbolic { 1 } else { 0 }
  let nonsymbolic_bit = if symbolic { 0 } else { 1 }
  (italic << 6) | (symbolic_bit << 2) | (nonsymbolic_bit << 5)
}

///|
/// Return the descriptor metrics read from the TrueType `OS/2` and `post`
/// tables by `Cpdftruetype.parse`.
///
/// The source parser requires `OS/2` for normal embedding, scales its signed
/// metrics to PDF units, reads the high word of the `post` italic-angle fixed
/// value when available, and derives both symbolic and non-symbolic font flags.
pub fn pdf_truetype_descriptor_metrics(
  data : BytesView,
) -> @truetype.PdfTrueTypeDescriptorMetrics raise @core.PdfError {
  let head = pdf_truetype_required_table(data, "head")
  let units_per_em = pdf_truetype_required_u16(
    data,
    head.offset + 18,
    "head table",
  )
  let os2 = match pdf_truetype_table(data, "OS/2") {
    Some(record) => record
    None => raise SoftError("No os/2 table found in truetype font")
  }
  let version = pdf_truetype_required_u16(data, os2.offset, "OS/2 table")
  let avgwidth = pdf_truetype_pdf_unit(
    units_per_em,
    pdf_truetype_required_i16(data, os2.offset + 2, "OS/2 table"),
  )
  let (ascent, descent) = if os2.length > 68 {
    (
      pdf_truetype_pdf_unit(
        units_per_em,
        pdf_truetype_required_i16(data, os2.offset + 68, "OS/2 table"),
      ),
      pdf_truetype_pdf_unit(
        units_per_em,
        pdf_truetype_required_i16(data, os2.offset + 70, "OS/2 table"),
      ),
    )
  } else {
    (0, 0)
  }
  let (xheight, capheight) = if version < 2 {
    (0, 0)
  } else {
    (
      pdf_truetype_pdf_unit(
        units_per_em,
        pdf_truetype_required_i16(data, os2.offset + 86, "OS/2 table"),
      ),
      pdf_truetype_pdf_unit(
        units_per_em,
        pdf_truetype_required_i16(data, os2.offset + 88, "OS/2 table"),
      ),
    )
  }
  let italicangle = match pdf_truetype_table(data, "post") {
    Some(post) => pdf_truetype_required_u16(data, post.offset + 4, "post table")
    None => 0
  }
  {
    ascent,
    descent,
    capheight,
    xheight,
    avgwidth,
    italicangle,
    nonsymbolic_flags: pdf_truetype_flags(false, italicangle),
    symbolic_flags: pdf_truetype_flags(true, italicangle),
  }
}

///|
/// Return the TrueType metrics needed by `Cpdftruetype.parse`.
///
/// This ports the table reads used before font subsetting proper: `/head`
/// provides units, PDF-unit bounding box, and `indexToLocFormat`; `/maxp`
/// provides `numGlyphs`; optional `/hhea` provides `numOfLongHorMetrics`; and
/// `/hmtx` provides the raw advance widths used for cpdf's width calculations.
pub fn pdf_truetype_metrics(
  data : BytesView,
) -> @truetype.PdfTrueTypeMetrics raise @core.PdfError {
  let head = pdf_truetype_required_table(data, "head")
  let maxp = pdf_truetype_required_table(data, "maxp")
  let hmtx = pdf_truetype_required_table(data, "hmtx")
  let units_per_em = pdf_truetype_required_u16(
    data,
    head.offset + 18,
    "head table",
  )
  let minx = pdf_truetype_pdf_unit(
    units_per_em,
    pdf_truetype_required_i16(data, head.offset + 36, "head table"),
  )
  let miny = pdf_truetype_pdf_unit(
    units_per_em,
    pdf_truetype_required_i16(data, head.offset + 38, "head table"),
  )
  let maxx = pdf_truetype_pdf_unit(
    units_per_em,
    pdf_truetype_required_i16(data, head.offset + 40, "head table"),
  )
  let maxy = pdf_truetype_pdf_unit(
    units_per_em,
    pdf_truetype_required_i16(data, head.offset + 42, "head table"),
  )
  let index_to_loc_format = pdf_truetype_required_i16(
    data,
    head.offset + 50,
    "head table",
  )
  let num_glyphs = pdf_truetype_required_u16(
    data,
    maxp.offset + 4,
    "maxp table",
  )
  let num_of_long_hor_metrics = match pdf_truetype_table(data, "hhea") {
    Some(hhea) =>
      pdf_truetype_required_u16(data, hhea.offset + 34, "hhea table")
    None => 0
  }
  let advance_widths = pdf_truetype_hmtx_widths(
    data, hmtx, num_of_long_hor_metrics,
  )
  {
    units_per_em,
    minx,
    miny,
    maxx,
    maxy,
    index_to_loc_format,
    num_glyphs,
    num_of_long_hor_metrics,
    advance_widths,
    max_width: pdf_truetype_max_pdf_width(units_per_em, advance_widths),
  }
}