U+FFFF (supplemental * characters) which requires special treatment depending on the * programming language and development environment. * * You can initialize PHP strings with supplemental characters in the * following ways: * * - Supply the Unicode code point in hexadecimal format (surrogate pairs are * not supported): * $unistring = "\u{1F0CF}"; * * - Supply the Unicode character directly in the PHP source and store the * source file in UTF-8 format. * * - PDFlib character references are independent of the development environment * and can be enabled with the "charref" option, e.g. * p.fit_textline("🃏", 100, 100, * "charref=true fontname=EmojiOneColor fontsize=50"); */ /* This is where the data files are. Adjust as necessary. */ $searchpath = dirname(__FILE__,3)."/input"; $outfile = ""; $title = "Emoji sequences"; $exitcode = 0; $llx = 25; $lly = 25; $urx = 820; $ury = 550; /* This font will be used unless another one is specified in the table */ $defaulttestfont = "EmojiOneColor"; $headers = array( "Description", "Font name", "Raw input", "Isolated characters", "Combined characters" ); class testcase { public function __construct($description, $fontname, $text) { $this->description = $description; $this->fontname = $fontname; $this->text = $text; } public $description; public $fontname; public $text; } $testcases = array( new testcase("ZWJ grouping", "", "👨‍👩‍👧"), new testcase("skin tone", "", "👦🏻👦🏼👦🏽" . "👦🏾👦🏿"), new testcase("emoji flag", "", "🇲🇹 🇦🇪 🇬🇧"), new testcase("emoji keycap", "", "0️⃣ 9️⃣ #️⃣"), /* The following examples don't work with EmojiOneColor, but e.g. * with the Windows font "Segoe UI Emoji". new testcase("ZWJ gender", "Segoe UI Emoji", "🏊‍♀️" . "🏊‍♂️"), new testcase("ZWJ gender", "Segoe UI Emoji", "🧜‍♂ 🧜‍♀"), new testcase("skin tone and ZWJ gender", "Segoe UI Emoji", "🧜🏿‍♂ 🧜🏿‍♀"), new testcase("ZWJ hair components: red/bald/white", "Segoe UI Emoji", "👨‍🦰" . "👨‍🦲" . "👨‍🦳"), new testcase("ZWJ role: man farmer", "Segoe UI Emoji", "👨‍🌾"), new testcase("ZWJ role: woman farmer", "Segoe UI Emoji", "👩‍🌾"), */ ); try { $p = new pdflib(); $p->set_option("searchpath={" . $searchpath . "}"); $p->set_option("charref=true"); /* * This means that formatting and other errors will raise an * exception. This simplifies our sample code, but is not * recommended for production code. */ $p->set_option("errorpolicy=exception"); /* Set an output path according to the name of the topic */ if ($p->begin_document($outfile, "") == 0) { throw new Exception("Error: " . $p->get_errmsg()); } $p->set_info("Creator", "PDFlib Cookbook"); $p->set_info("Title", $title); $table = 0; /* Table header */ for ($i = 0; $i < count($headers); $i++) { $col = $i + 1; $optlist = "fittextline={fontname=NotoSerif-Bold fontsize=12} margin=4"; $table = $p->add_table_cell($table, $col, 1, $headers[$i], $optlist); } /* Create a table with feature samples, one feature per table row */ for ($i = 0; $i < count($testcases); $i += 1) { $testcase = $testcases[$i]; $row = $i + 2; /* * Use the entry in the test table if available, and the default * test font otherwise. */ $testfont = strlen($testcase->fontname) > 0 ? $testcase->fontname : $defaulttestfont; $col = 1; /* Common option list for columns 1-3 */ $optlist = "fittextline={fontname=NotoSerif-Regular fontsize=12} " . "margin=4 colwidth=10%"; /* Column 1: feature description */ $table = $p->add_table_cell($table, $col++, $row, $testcase->description, $optlist); /* Column 2: font name */ $table = $p->add_table_cell($table, $col++, $row, $testfont, $optlist); /* Column 3: raw input */ $tf = $p->add_textflow(0, $testcase->text, "charref=false fontname=NotoSerif-Regular " . "fontsize=" .(strlen($testcase->text) < 35 ? 12 : 8) . " alignment=center"); $table = $p->add_table_cell($table, $col++, $row, "", "colwidth=20% textflow=" . $tf . " margin=4"); /* Column 4: raw input text with all features disabled */ $optlist = "fittextline={features=_none colormode=combined fontname={" . $testfont . "} fontsize=20} margin=4"; $table = $p->add_table_cell($table, $col++, $row, $testcase->text, $optlist); /* Column 5: text with enabled feature */ $optlist = "fittextline={fontname={" . $testfont . "} fontsize=20} margin=4"; $table = $p->add_table_cell($table, $col++, $row, $testcase->text, $optlist); } /* * Loop until all of the table is placed; create new pages as long * as more table instances need to be placed. */ do { $p->begin_page_ext(0, 0, "width=a4.height height=a4.width"); /* Place the table */ $optlist = "header=1 fill={{area=rowodd " . "fillcolor={gray 0.9}}} stroke={{line=other}} "; $result = $p->fit_table($table, $llx, $lly, $urx, $ury, $optlist); if ($result == "_error") { throw new Exception("Couldn't place table: " . $p->get_errmsg()); } $p->end_page_ext(""); } while ($result == "_boxfull"); $p->end_document(""); $buf = $p->get_buffer(); $len = strlen($buf); header("Content-type: application/pdf"); header("Content-Length: $len"); header("Content-Disposition: inline; filename=emoji_sequences.pdf"); print $buf; } catch (PDFlibException $e) { echo ("PDFlib exception occurred:\n" . "[" . $e->get_errnum() . "] " . $e->get_apiname() . ": " . $e->get_errmsg() . "\n"); exit(1); } catch (Throwable $e) { echo ("PHP exception occurred: " . $e->getMessage() . "\n"); exit(1); } $p = 0; ?>