docling-pdf 0.56.0

PDF/image backend for docling.rs: pdfium text extraction + ONNX layout/table/OCR pipeline.
Documentation
//! Built-in glyph advance widths for the PDF standard-14 (base-14) Type1
//! fonts, which a producer may reference without embedding a font program or
//! a `/Widths` array (ReportLab's default, plus many report generators and
//! office exporters — issue #187). Without these metrics every glyph advance
//! resolved to 0, the cells collapsed to zero width, and the whole text layer
//! was silently dropped; pdfium ships the same built-in metrics and reads such
//! files fine.
//!
//! Data: the Adobe Core 14 AFM metrics (redistributable per Adobe's AFM
//! license), as tabulated by pdfminer.six's `fontmetrics.py`, re-keyed by the
//! Unicode character each glyph decodes to. Oblique/Italic Helvetica share the
//! upright widths and the Courier family is fixed-pitch 600, so six tables
//! cover the twelve text faces; Symbol and ZapfDingbats are excluded (they
//! need their own built-in *encodings*, not just widths, and are practically
//! always embedded).

/// The width every glyph of the fixed-pitch Courier family advances.
const COURIER_WIDTH: f64 = 600.0;

#[rustfmt::skip]
static HELVETICA: &[(u32, u16)] = &[
    (32,278),(33,278),(34,355),(35,556),(36,556),(37,889),(38,667),(39,191),(40,333),(41,333),
    (42,389),(43,584),(44,278),(45,333),(46,278),(47,278),(48,556),(49,556),(50,556),(51,556),
    (52,556),(53,556),(54,556),(55,556),(56,556),(57,556),(58,278),(59,278),(60,584),(61,584),
    (62,584),(63,556),(64,1015),(65,667),(66,667),(67,722),(68,722),(69,667),(70,611),(71,778),
    (72,722),(73,278),(74,500),(75,667),(76,556),(77,833),(78,722),(79,778),(80,667),(81,778),
    (82,722),(83,667),(84,611),(85,722),(86,667),(87,944),(88,667),(89,667),(90,611),(91,278),
    (92,278),(93,278),(94,469),(95,556),(96,333),(97,556),(98,556),(99,500),(100,556),(101,556),
    (102,278),(103,556),(104,556),(105,222),(106,222),(107,500),(108,222),(109,833),(110,556),
    (111,556),(112,556),(113,556),(114,333),(115,500),(116,278),(117,556),(118,500),(119,722),
    (120,500),(121,500),(122,500),(123,334),(124,260),(125,334),(126,584),(161,333),(162,556),
    (163,556),(164,556),(165,556),(166,260),(167,556),(168,333),(169,737),(170,370),(171,556),
    (172,584),(174,737),(175,333),(176,400),(177,584),(178,333),(179,333),(180,333),(181,556),
    (182,537),(183,278),(184,333),(185,333),(186,365),(187,556),(188,834),(189,834),(190,834),
    (191,611),(192,667),(193,667),(194,667),(195,667),(196,667),(197,667),(198,1000),(199,722),
    (200,667),(201,667),(202,667),(203,667),(204,278),(205,278),(206,278),(207,278),(208,722),
    (209,722),(210,778),(211,778),(212,778),(213,778),(214,778),(215,584),(216,778),(217,722),
    (218,722),(219,722),(220,722),(221,667),(222,667),(223,611),(224,556),(225,556),(226,556),
    (227,556),(228,556),(229,556),(230,889),(231,500),(232,556),(233,556),(234,556),(235,556),
    (236,278),(237,278),(238,278),(239,278),(240,556),(241,556),(242,556),(243,556),(244,556),
    (245,556),(246,556),(247,584),(248,611),(249,556),(250,556),(251,556),(252,556),(253,500),
    (254,556),(255,500),(256,667),(257,556),(258,667),(259,556),(260,667),(261,556),(262,722),
    (263,500),(268,722),(269,500),(270,722),(271,643),(272,722),(273,556),(274,667),(275,556),
    (278,667),(279,556),(280,667),(281,556),(282,667),(283,556),(286,778),(287,556),(290,778),
    (291,556),(298,278),(299,278),(302,278),(303,222),(304,278),(305,278),(310,667),(311,500),
    (313,556),(314,222),(315,556),(316,222),(317,556),(318,299),(321,556),(322,222),(323,722),
    (324,556),(325,722),(326,556),(327,722),(328,556),(332,778),(333,556),(336,778),(337,556),
    (338,1000),(339,944),(340,722),(341,333),(342,722),(343,333),(344,722),(345,333),(346,667),
    (347,500),(350,667),(351,500),(352,667),(353,500),(354,611),(355,278),(356,611),(357,317),
    (362,722),(363,556),(366,722),(367,556),(368,722),(369,556),(370,722),(371,556),(376,667),
    (377,611),(378,500),(379,611),(380,500),(381,611),(382,500),(402,556),(536,667),(537,500),
    (710,333),(711,333),(728,333),(729,333),(730,333),(731,333),(732,333),(733,333),(8211,556),
    (8212,1000),(8216,222),(8217,222),(8218,222),(8220,333),(8221,333),(8222,333),(8224,556),
    (8225,556),(8226,350),(8230,1000),(8240,1000),(8249,333),(8250,333),(8260,167),(8482,1000),
    (8706,476),(8710,612),(8721,600),(8722,584),(8730,453),(8800,549),(8804,549),(8805,549),
    (9674,471),(63171,250),(64257,500),(64258,500),
];

#[rustfmt::skip]
static HELVETICA_BOLD: &[(u32, u16)] = &[
    (32,278),(33,333),(34,474),(35,556),(36,556),(37,889),(38,722),(39,238),(40,333),(41,333),
    (42,389),(43,584),(44,278),(45,333),(46,278),(47,278),(48,556),(49,556),(50,556),(51,556),
    (52,556),(53,556),(54,556),(55,556),(56,556),(57,556),(58,333),(59,333),(60,584),(61,584),
    (62,584),(63,611),(64,975),(65,722),(66,722),(67,722),(68,722),(69,667),(70,611),(71,778),
    (72,722),(73,278),(74,556),(75,722),(76,611),(77,833),(78,722),(79,778),(80,667),(81,778),
    (82,722),(83,667),(84,611),(85,722),(86,667),(87,944),(88,667),(89,667),(90,611),(91,333),
    (92,278),(93,333),(94,584),(95,556),(96,333),(97,556),(98,611),(99,556),(100,611),(101,556),
    (102,333),(103,611),(104,611),(105,278),(106,278),(107,556),(108,278),(109,889),(110,611),
    (111,611),(112,611),(113,611),(114,389),(115,556),(116,333),(117,611),(118,556),(119,778),
    (120,556),(121,556),(122,500),(123,389),(124,280),(125,389),(126,584),(161,333),(162,556),
    (163,556),(164,556),(165,556),(166,280),(167,556),(168,333),(169,737),(170,370),(171,556),
    (172,584),(174,737),(175,333),(176,400),(177,584),(178,333),(179,333),(180,333),(181,611),
    (182,556),(183,278),(184,333),(185,333),(186,365),(187,556),(188,834),(189,834),(190,834),
    (191,611),(192,722),(193,722),(194,722),(195,722),(196,722),(197,722),(198,1000),(199,722),
    (200,667),(201,667),(202,667),(203,667),(204,278),(205,278),(206,278),(207,278),(208,722),
    (209,722),(210,778),(211,778),(212,778),(213,778),(214,778),(215,584),(216,778),(217,722),
    (218,722),(219,722),(220,722),(221,667),(222,667),(223,611),(224,556),(225,556),(226,556),
    (227,556),(228,556),(229,556),(230,889),(231,556),(232,556),(233,556),(234,556),(235,556),
    (236,278),(237,278),(238,278),(239,278),(240,611),(241,611),(242,611),(243,611),(244,611),
    (245,611),(246,611),(247,584),(248,611),(249,611),(250,611),(251,611),(252,611),(253,556),
    (254,611),(255,556),(256,722),(257,556),(258,722),(259,556),(260,722),(261,556),(262,722),
    (263,556),(268,722),(269,556),(270,722),(271,743),(272,722),(273,611),(274,667),(275,556),
    (278,667),(279,556),(280,667),(281,556),(282,667),(283,556),(286,778),(287,611),(290,778),
    (291,611),(298,278),(299,278),(302,278),(303,278),(304,278),(305,278),(310,722),(311,556),
    (313,611),(314,278),(315,611),(316,278),(317,611),(318,400),(321,611),(322,278),(323,722),
    (324,611),(325,722),(326,611),(327,722),(328,611),(332,778),(333,611),(336,778),(337,611),
    (338,1000),(339,944),(340,722),(341,389),(342,722),(343,389),(344,722),(345,389),(346,667),
    (347,556),(350,667),(351,556),(352,667),(353,556),(354,611),(355,333),(356,611),(357,389),
    (362,722),(363,611),(366,722),(367,611),(368,722),(369,611),(370,722),(371,611),(376,667),
    (377,611),(378,500),(379,611),(380,500),(381,611),(382,500),(402,556),(536,667),(537,556),
    (710,333),(711,333),(728,333),(729,333),(730,333),(731,333),(732,333),(733,333),(8211,556),
    (8212,1000),(8216,278),(8217,278),(8218,278),(8220,500),(8221,500),(8222,500),(8224,556),
    (8225,556),(8226,350),(8230,1000),(8240,1000),(8249,333),(8250,333),(8260,167),(8482,1000),
    (8706,494),(8710,612),(8721,600),(8722,584),(8730,549),(8800,549),(8804,549),(8805,549),
    (9674,494),(63171,250),(64257,611),(64258,611),
];

#[rustfmt::skip]
static TIMES_ROMAN: &[(u32, u16)] = &[
    (32,250),(33,333),(34,408),(35,500),(36,500),(37,833),(38,778),(39,180),(40,333),(41,333),
    (42,500),(43,564),(44,250),(45,333),(46,250),(47,278),(48,500),(49,500),(50,500),(51,500),
    (52,500),(53,500),(54,500),(55,500),(56,500),(57,500),(58,278),(59,278),(60,564),(61,564),
    (62,564),(63,444),(64,921),(65,722),(66,667),(67,667),(68,722),(69,611),(70,556),(71,722),
    (72,722),(73,333),(74,389),(75,722),(76,611),(77,889),(78,722),(79,722),(80,556),(81,722),
    (82,667),(83,556),(84,611),(85,722),(86,722),(87,944),(88,722),(89,722),(90,611),(91,333),
    (92,278),(93,333),(94,469),(95,500),(96,333),(97,444),(98,500),(99,444),(100,500),(101,444),
    (102,333),(103,500),(104,500),(105,278),(106,278),(107,500),(108,278),(109,778),(110,500),
    (111,500),(112,500),(113,500),(114,333),(115,389),(116,278),(117,500),(118,500),(119,722),
    (120,500),(121,500),(122,444),(123,480),(124,200),(125,480),(126,541),(161,333),(162,500),
    (163,500),(164,500),(165,500),(166,200),(167,500),(168,333),(169,760),(170,276),(171,500),
    (172,564),(174,760),(175,333),(176,400),(177,564),(178,300),(179,300),(180,333),(181,500),
    (182,453),(183,250),(184,333),(185,300),(186,310),(187,500),(188,750),(189,750),(190,750),
    (191,444),(192,722),(193,722),(194,722),(195,722),(196,722),(197,722),(198,889),(199,667),
    (200,611),(201,611),(202,611),(203,611),(204,333),(205,333),(206,333),(207,333),(208,722),
    (209,722),(210,722),(211,722),(212,722),(213,722),(214,722),(215,564),(216,722),(217,722),
    (218,722),(219,722),(220,722),(221,722),(222,556),(223,500),(224,444),(225,444),(226,444),
    (227,444),(228,444),(229,444),(230,667),(231,444),(232,444),(233,444),(234,444),(235,444),
    (236,278),(237,278),(238,278),(239,278),(240,500),(241,500),(242,500),(243,500),(244,500),
    (245,500),(246,500),(247,564),(248,500),(249,500),(250,500),(251,500),(252,500),(253,500),
    (254,500),(255,500),(256,722),(257,444),(258,722),(259,444),(260,722),(261,444),(262,667),
    (263,444),(268,667),(269,444),(270,722),(271,588),(272,722),(273,500),(274,611),(275,444),
    (278,611),(279,444),(280,611),(281,444),(282,611),(283,444),(286,722),(287,500),(290,722),
    (291,500),(298,333),(299,278),(302,333),(303,278),(304,333),(305,278),(310,722),(311,500),
    (313,611),(314,278),(315,611),(316,278),(317,611),(318,344),(321,611),(322,278),(323,722),
    (324,500),(325,722),(326,500),(327,722),(328,500),(332,722),(333,500),(336,722),(337,500),
    (338,889),(339,722),(340,667),(341,333),(342,667),(343,333),(344,667),(345,333),(346,556),
    (347,389),(350,556),(351,389),(352,556),(353,389),(354,611),(355,278),(356,611),(357,326),
    (362,722),(363,500),(366,722),(367,500),(368,722),(369,500),(370,722),(371,500),(376,722),
    (377,611),(378,444),(379,611),(380,444),(381,611),(382,444),(402,500),(536,556),(537,389),
    (710,333),(711,333),(728,333),(729,333),(730,333),(731,333),(732,333),(733,333),(8211,500),
    (8212,1000),(8216,333),(8217,333),(8218,333),(8220,444),(8221,444),(8222,444),(8224,500),
    (8225,500),(8226,350),(8230,1000),(8240,1000),(8249,333),(8250,333),(8260,167),(8482,980),
    (8706,476),(8710,612),(8721,600),(8722,564),(8730,453),(8800,549),(8804,549),(8805,549),
    (9674,471),(63171,250),(64257,556),(64258,556),
];

#[rustfmt::skip]
static TIMES_BOLD: &[(u32, u16)] = &[
    (32,250),(33,333),(34,555),(35,500),(36,500),(37,1000),(38,833),(39,278),(40,333),(41,333),
    (42,500),(43,570),(44,250),(45,333),(46,250),(47,278),(48,500),(49,500),(50,500),(51,500),
    (52,500),(53,500),(54,500),(55,500),(56,500),(57,500),(58,333),(59,333),(60,570),(61,570),
    (62,570),(63,500),(64,930),(65,722),(66,667),(67,722),(68,722),(69,667),(70,611),(71,778),
    (72,778),(73,389),(74,500),(75,778),(76,667),(77,944),(78,722),(79,778),(80,611),(81,778),
    (82,722),(83,556),(84,667),(85,722),(86,722),(87,1000),(88,722),(89,722),(90,667),(91,333),
    (92,278),(93,333),(94,581),(95,500),(96,333),(97,500),(98,556),(99,444),(100,556),(101,444),
    (102,333),(103,500),(104,556),(105,278),(106,333),(107,556),(108,278),(109,833),(110,556),
    (111,500),(112,556),(113,556),(114,444),(115,389),(116,333),(117,556),(118,500),(119,722),
    (120,500),(121,500),(122,444),(123,394),(124,220),(125,394),(126,520),(161,333),(162,500),
    (163,500),(164,500),(165,500),(166,220),(167,500),(168,333),(169,747),(170,300),(171,500),
    (172,570),(174,747),(175,333),(176,400),(177,570),(178,300),(179,300),(180,333),(181,556),
    (182,540),(183,250),(184,333),(185,300),(186,330),(187,500),(188,750),(189,750),(190,750),
    (191,500),(192,722),(193,722),(194,722),(195,722),(196,722),(197,722),(198,1000),(199,722),
    (200,667),(201,667),(202,667),(203,667),(204,389),(205,389),(206,389),(207,389),(208,722),
    (209,722),(210,778),(211,778),(212,778),(213,778),(214,778),(215,570),(216,778),(217,722),
    (218,722),(219,722),(220,722),(221,722),(222,611),(223,556),(224,500),(225,500),(226,500),
    (227,500),(228,500),(229,500),(230,722),(231,444),(232,444),(233,444),(234,444),(235,444),
    (236,278),(237,278),(238,278),(239,278),(240,500),(241,556),(242,500),(243,500),(244,500),
    (245,500),(246,500),(247,570),(248,500),(249,556),(250,556),(251,556),(252,556),(253,500),
    (254,556),(255,500),(256,722),(257,500),(258,722),(259,500),(260,722),(261,500),(262,722),
    (263,444),(268,722),(269,444),(270,722),(271,672),(272,722),(273,556),(274,667),(275,444),
    (278,667),(279,444),(280,667),(281,444),(282,667),(283,444),(286,778),(287,500),(290,778),
    (291,500),(298,389),(299,278),(302,389),(303,278),(304,389),(305,278),(310,778),(311,556),
    (313,667),(314,278),(315,667),(316,278),(317,667),(318,394),(321,667),(322,278),(323,722),
    (324,556),(325,722),(326,556),(327,722),(328,556),(332,778),(333,500),(336,778),(337,500),
    (338,1000),(339,722),(340,722),(341,444),(342,722),(343,444),(344,722),(345,444),(346,556),
    (347,389),(350,556),(351,389),(352,556),(353,389),(354,667),(355,333),(356,667),(357,416),
    (362,722),(363,556),(366,722),(367,556),(368,722),(369,556),(370,722),(371,556),(376,722),
    (377,667),(378,444),(379,667),(380,444),(381,667),(382,444),(402,500),(536,556),(537,389),
    (710,333),(711,333),(728,333),(729,333),(730,333),(731,333),(732,333),(733,333),(8211,500),
    (8212,1000),(8216,333),(8217,333),(8218,333),(8220,500),(8221,500),(8222,500),(8224,500),
    (8225,500),(8226,350),(8230,1000),(8240,1000),(8249,333),(8250,333),(8260,167),(8482,1000),
    (8706,494),(8710,612),(8721,600),(8722,570),(8730,549),(8800,549),(8804,549),(8805,549),
    (9674,494),(63171,250),(64257,556),(64258,556),
];

#[rustfmt::skip]
static TIMES_ITALIC: &[(u32, u16)] = &[
    (32,250),(33,333),(34,420),(35,500),(36,500),(37,833),(38,778),(39,214),(40,333),(41,333),
    (42,500),(43,675),(44,250),(45,333),(46,250),(47,278),(48,500),(49,500),(50,500),(51,500),
    (52,500),(53,500),(54,500),(55,500),(56,500),(57,500),(58,333),(59,333),(60,675),(61,675),
    (62,675),(63,500),(64,920),(65,611),(66,611),(67,667),(68,722),(69,611),(70,611),(71,722),
    (72,722),(73,333),(74,444),(75,667),(76,556),(77,833),(78,667),(79,722),(80,611),(81,722),
    (82,611),(83,500),(84,556),(85,722),(86,611),(87,833),(88,611),(89,556),(90,556),(91,389),
    (92,278),(93,389),(94,422),(95,500),(96,333),(97,500),(98,500),(99,444),(100,500),(101,444),
    (102,278),(103,500),(104,500),(105,278),(106,278),(107,444),(108,278),(109,722),(110,500),
    (111,500),(112,500),(113,500),(114,389),(115,389),(116,278),(117,500),(118,444),(119,667),
    (120,444),(121,444),(122,389),(123,400),(124,275),(125,400),(126,541),(161,389),(162,500),
    (163,500),(164,500),(165,500),(166,275),(167,500),(168,333),(169,760),(170,276),(171,500),
    (172,675),(174,760),(175,333),(176,400),(177,675),(178,300),(179,300),(180,333),(181,500),
    (182,523),(183,250),(184,333),(185,300),(186,310),(187,500),(188,750),(189,750),(190,750),
    (191,500),(192,611),(193,611),(194,611),(195,611),(196,611),(197,611),(198,889),(199,667),
    (200,611),(201,611),(202,611),(203,611),(204,333),(205,333),(206,333),(207,333),(208,722),
    (209,667),(210,722),(211,722),(212,722),(213,722),(214,722),(215,675),(216,722),(217,722),
    (218,722),(219,722),(220,722),(221,556),(222,611),(223,500),(224,500),(225,500),(226,500),
    (227,500),(228,500),(229,500),(230,667),(231,444),(232,444),(233,444),(234,444),(235,444),
    (236,278),(237,278),(238,278),(239,278),(240,500),(241,500),(242,500),(243,500),(244,500),
    (245,500),(246,500),(247,675),(248,500),(249,500),(250,500),(251,500),(252,500),(253,444),
    (254,500),(255,444),(256,611),(257,500),(258,611),(259,500),(260,611),(261,500),(262,667),
    (263,444),(268,667),(269,444),(270,722),(271,544),(272,722),(273,500),(274,611),(275,444),
    (278,611),(279,444),(280,611),(281,444),(282,611),(283,444),(286,722),(287,500),(290,722),
    (291,500),(298,333),(299,278),(302,333),(303,278),(304,333),(305,278),(310,667),(311,444),
    (313,556),(314,278),(315,556),(316,278),(317,611),(318,300),(321,556),(322,278),(323,667),
    (324,500),(325,667),(326,500),(327,667),(328,500),(332,722),(333,500),(336,722),(337,500),
    (338,944),(339,667),(340,611),(341,389),(342,611),(343,389),(344,611),(345,389),(346,500),
    (347,389),(350,500),(351,389),(352,500),(353,389),(354,556),(355,278),(356,556),(357,300),
    (362,722),(363,500),(366,722),(367,500),(368,722),(369,500),(370,722),(371,500),(376,556),
    (377,556),(378,389),(379,556),(380,389),(381,556),(382,389),(402,500),(536,500),(537,389),
    (710,333),(711,333),(728,333),(729,333),(730,333),(731,333),(732,333),(733,333),(8211,500),
    (8212,889),(8216,333),(8217,333),(8218,333),(8220,556),(8221,556),(8222,556),(8224,500),
    (8225,500),(8226,350),(8230,889),(8240,1000),(8249,333),(8250,333),(8260,167),(8482,980),
    (8706,476),(8710,612),(8721,600),(8722,675),(8730,453),(8800,549),(8804,549),(8805,549),
    (9674,471),(63171,250),(64257,500),(64258,500),
];

#[rustfmt::skip]
static TIMES_BOLD_ITALIC: &[(u32, u16)] = &[
    (32,250),(33,389),(34,555),(35,500),(36,500),(37,833),(38,778),(39,278),(40,333),(41,333),
    (42,500),(43,570),(44,250),(45,333),(46,250),(47,278),(48,500),(49,500),(50,500),(51,500),
    (52,500),(53,500),(54,500),(55,500),(56,500),(57,500),(58,333),(59,333),(60,570),(61,570),
    (62,570),(63,500),(64,832),(65,667),(66,667),(67,667),(68,722),(69,667),(70,667),(71,722),
    (72,778),(73,389),(74,500),(75,667),(76,611),(77,889),(78,722),(79,722),(80,611),(81,722),
    (82,667),(83,556),(84,611),(85,722),(86,667),(87,889),(88,667),(89,611),(90,611),(91,333),
    (92,278),(93,333),(94,570),(95,500),(96,333),(97,500),(98,500),(99,444),(100,500),(101,444),
    (102,333),(103,500),(104,556),(105,278),(106,278),(107,500),(108,278),(109,778),(110,556),
    (111,500),(112,500),(113,500),(114,389),(115,389),(116,278),(117,556),(118,444),(119,667),
    (120,500),(121,444),(122,389),(123,348),(124,220),(125,348),(126,570),(161,389),(162,500),
    (163,500),(164,500),(165,500),(166,220),(167,500),(168,333),(169,747),(170,266),(171,500),
    (172,606),(174,747),(175,333),(176,400),(177,570),(178,300),(179,300),(180,333),(181,576),
    (182,500),(183,250),(184,333),(185,300),(186,300),(187,500),(188,750),(189,750),(190,750),
    (191,500),(192,667),(193,667),(194,667),(195,667),(196,667),(197,667),(198,944),(199,667),
    (200,667),(201,667),(202,667),(203,667),(204,389),(205,389),(206,389),(207,389),(208,722),
    (209,722),(210,722),(211,722),(212,722),(213,722),(214,722),(215,570),(216,722),(217,722),
    (218,722),(219,722),(220,722),(221,611),(222,611),(223,500),(224,500),(225,500),(226,500),
    (227,500),(228,500),(229,500),(230,722),(231,444),(232,444),(233,444),(234,444),(235,444),
    (236,278),(237,278),(238,278),(239,278),(240,500),(241,556),(242,500),(243,500),(244,500),
    (245,500),(246,500),(247,570),(248,500),(249,556),(250,556),(251,556),(252,556),(253,444),
    (254,500),(255,444),(256,667),(257,500),(258,667),(259,500),(260,667),(261,500),(262,667),
    (263,444),(268,667),(269,444),(270,722),(271,608),(272,722),(273,500),(274,667),(275,444),
    (278,667),(279,444),(280,667),(281,444),(282,667),(283,444),(286,722),(287,500),(290,722),
    (291,500),(298,389),(299,278),(302,389),(303,278),(304,389),(305,278),(310,667),(311,500),
    (313,611),(314,278),(315,611),(316,278),(317,611),(318,382),(321,611),(322,278),(323,722),
    (324,556),(325,722),(326,556),(327,722),(328,556),(332,722),(333,500),(336,722),(337,500),
    (338,944),(339,722),(340,667),(341,389),(342,667),(343,389),(344,667),(345,389),(346,556),
    (347,389),(350,556),(351,389),(352,556),(353,389),(354,611),(355,278),(356,611),(357,366),
    (362,722),(363,556),(366,722),(367,556),(368,722),(369,556),(370,722),(371,556),(376,611),
    (377,611),(378,389),(379,611),(380,389),(381,611),(382,389),(402,500),(536,556),(537,389),
    (710,333),(711,333),(728,333),(729,333),(730,333),(731,333),(732,333),(733,333),(8211,500),
    (8212,1000),(8216,333),(8217,333),(8218,333),(8220,500),(8221,500),(8222,500),(8224,500),
    (8225,500),(8226,350),(8230,1000),(8240,1000),(8249,333),(8250,333),(8260,167),(8482,1000),
    (8706,494),(8710,612),(8721,600),(8722,606),(8730,549),(8800,549),(8804,549),(8805,549),
    (9674,494),(63171,250),(64257,556),(64258,556),
];

/// Width table for a normalized standard-14 family, or `None` when the face
/// is not one of the twelve text faces (Symbol/ZapfDingbats included).
/// `base` is the `/BaseFont` name with any `ABCDEF+` subset prefix stripped.
pub(crate) fn widths_for(base: &[u8]) -> Option<Std14Widths> {
    // Aliases per the PDF spec's standard-14 substitution table: Arial ->
    // Helvetica, TimesNewRoman -> Times, CourierNew -> Courier; a `,Bold` /
    // `,Italic` / `-Bold` / `-Oblique` suffix picks the face.
    let s = std::str::from_utf8(base).ok()?.trim();
    let lower = s.to_ascii_lowercase();
    let (family, style) = match lower.split_once(['-', ',']) {
        Some((f, st)) => (f.trim().to_string(), st.trim().to_string()),
        None => (lower.clone(), String::new()),
    };
    let bold = style.contains("bold");
    let italic = style.contains("italic") || style.contains("oblique");
    match family.as_str() {
        "courier" | "couriernew" => Some(Std14Widths::Fixed(COURIER_WIDTH)),
        "helvetica" | "arial" => Some(Std14Widths::Table(if bold {
            HELVETICA_BOLD
        } else {
            HELVETICA
        })),
        "times" | "timesnewroman" => Some(Std14Widths::Table(match (bold, italic) {
            (true, true) => TIMES_BOLD_ITALIC,
            (true, false) => TIMES_BOLD,
            (false, true) => TIMES_ITALIC,
            (false, false) => TIMES_ROMAN,
        })),
        _ => None,
    }
}

/// A standard-14 face's metrics: fixed-pitch, or a sorted `(codepoint, width)`
/// table in 1000-unit glyph space.
pub(crate) enum Std14Widths {
    Fixed(f64),
    Table(&'static [(u32, u16)]),
}

impl Std14Widths {
    /// The advance for `ch`, or `None` when the face has no such glyph.
    pub(crate) fn width(&self, ch: char) -> Option<f64> {
        match self {
            Std14Widths::Fixed(w) => Some(*w),
            Std14Widths::Table(t) => t
                .binary_search_by_key(&(ch as u32), |&(cp, _)| cp)
                .ok()
                .map(|i| f64::from(t[i].1)),
        }
    }
}