description = $description; $this->optlist = $optlist; $this->feature = $feature; $this->text = $text; } } $testcases = array( new testcase("Localized forms for simplified Chinese", "features={locl} script=hang language=ZHS", "locl", "\u{2E95}\u{2EDD}\u{38C0}"), new testcase("Localized forms for traditional Chinese", "features={locl} script=hang language=ZHT", "locl", "\u{328B}\u{35EB}\u{3B35}"), new testcase("Localized forms for Korean", "features={locl} script=hang language=KOR", "locl", "\u{4E73}\u{52E4}\u{52FB}"), new testcase("Simplified forms", "features={smpl}", "smpl", "\u{6AAF} \u{81FA} \u{98B1}"), new testcase("Traditional forms", "features={trad}", "trad", "\u{53F0}\u{4E03}\u{4E0E}\u{4E31}\u{7D1B}\u{9912}\u{96B8}" . "\u{9698}\u{966A}\u{939A}"), new testcase("Expert forms", "features={expt}", "expt", "\u{5516}\u{82A6}\u{98F4}\u{9E78}\u{9D60}\u{6F23}\u{84EE}\u{7BDD}"), new testcase("Full widths", "features={fwid}", "fwid", "0123-456(789)=25"), new testcase("Horizontal kana alternates", "features={hkna}", "hkna", "\u{3041}\u{3042}\u{3043}\u{3044} \u{30A1}\u{30A2}\u{30A3}" . "\u{30A4}\u{30E5}\u{30E4}\u{30B4}\u{30A7}"), new testcase("Hangul", "features={hngl}", "hngl", "\u{4F3D}"), new testcase("Hojo kanji forms (JIS X 0212-1990)", "features={hojo}", "hojo", "\u{6FF9}\u{9B35}\u{8200}\u{9CE6}\u{9B2D}\u{9721}\u{884B}"), new testcase("Half widths", "features={hwid}", "hwid", "0123-456(789)=25"), new testcase("Italics", "features={ital}", "ital", "ABCD abcd 1234"), new testcase("JIS2004 forms", "features={jp04}", "jp04", "\u{9022}\u{98F4}\u{6EA2}\u{8328}\u{9C2F}\u{6DEB}\u{8FC2}"), new testcase("JIS78 forms", "features={jp78}", "jp78", "\u{5516}\u{53F1}\u{63B4}\u{8000}"), new testcase("JIS83 forms", "features={jp83}", "jp83", "\u{4E08}\u{51A4}"), new testcase("JIS90 forms", "features={jp90}", "jp90", "\u{5026}\u{6994}"), new testcase("Alternate annotation forms", "features={nalt}", "nalt", "ABC123\u{002F}\u{30B4}\u{217B}\u{4E0B}\u{7981}\u{2F29}\u{4E2D}\u{2F42}"), new testcase("NLC kanji forms", "features={nlck}", "nlck", "\u{4FA0}\u{64B9}"), new testcase("Proportional kana", "features={pkna}", "pkna", "\u{3041}\u{3042} \u{30A1}\u{30A2} \u{FF66} \u{FF67}"), new testcase("Proportional widths", "features={pwid}", "pwid", "\u{3041}\u{3042} \u{30A1}\u{30A2} \u{301C}\u{FF21}\u{FF23}\u{FF28}" . "\u{FF29}\u{FF2D} ABCD abcd 1234"), new testcase("Quarter widths", "features={qwid}", "qwid", "0123-456(789)=25"), new testcase("Ruby notation forms", "features={ruby}", "ruby", "\u{3042}\u{304A}\u{307D}\u{30AA}\u{30BC}\u{30F1}\u{25C9}\u{31F0}\u{31FF}"), new testcase("Traditional name forms", "features={tnam}", "tnam", "\u{4E9C}"), new testcase("Third widths", "features={twid}", "twid", "0123-456(789)=25"), new testcase("Vertical kana alternates", "vertical features={vkna}", "vkna", "\u{3041}\u{3042}\u{3043}\u{3044}\u{31FF}\u{31F8}\u{30CB}\u{30BB}"), // "vrt2" and "vert" are activated automatically in vertical mode new testcase("Vertical alternates and rotation (vrt2)", "vertical", "vrt2", "\u{FF08}ab\u{FF09}\u{FF1A}\u{300C}ab\u{300D}\u{3348}"), new testcase("Vertical alternates (vert)", "vertical", "vert", "\u{FF08}ab\u{FF09}\u{FF1A}\u{300C}ab\u{300D}\u{3348}"), ); try { $p = new pdflib(); $p->set_option("searchpath={" . $searchpath . "}"); $p->set_option("charref=true"); $p->set_option("escapesequence=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", "opentype_features_for_cjk"); $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; $col = 1; /* Common option list for columns 1-3 */ $optlist = "fittextline={fontname=NotoSerif-Regular fontsize=12} " . "margin=4"; /* Column 1: feature description */ $table = $p->add_table_cell($table, $col++, $row, $testcase->description, $optlist); /* Column 2: option list */ $table = $p->add_table_cell($table, $col++, $row, $testcase->optlist, $optlist); /* Column 3: font name */ $table = $p->add_table_cell($table, $col++, $row, $testfont, $optlist); /* Column 4: raw input text with feature disabled */ $optlist = "fittextline={fontname={" . $testfont . "} fontsize=12 } margin=4"; $table = $p->add_table_cell($table, $col++, $row, $testcase->text, $optlist); /* * Column 5: text with enabled feature, or warning if the * feature is not available in the font */ $font = $p->load_font($testfont, "unicode", ""); /* Check whether font contains the required feature table */ $optlist = "name=" . $testcase->feature; if ($p->info_font($font, "feature", $optlist) == 1) { /* feature is available: apply it to the text */ $optlist = "margin=4 fittextline={fontname={" . $testfont . "} fontsize=12 " . $testcase->optlist . "}"; $table = $p->add_table_cell($table, $col++, $row, $testcase->text, $optlist); } else { /* feature is not available: emit a warning */ $optlist = "fittextline={fontname=NotoSerif-Regular " . "fontsize=12 fillcolor=red} margin=4"; $table = $p->add_table_cell($table, $col++, $row, "(feature not available in this font)", $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"); $optlist = "header=1 fill={{area=rowodd fillcolor={gray 0.9}}} " . "stroke={{line=other}} debugshow"; /* Place the table instance */ $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=opentype_features_for_cjk.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; ?>