#!/usr/bin/env ruby
#
# Starter sample for OpenType font features
#
# Demonstrate various typographic OpenType features after checking
# whether a particular feature is supported in a font.
#
# Required data: suitable font with OpenType feature tables
#
# This sample uses a default font which includes various features.
# Depending on the implementation of the features you
# may have to replace the sample text below.
#

require 'PDFlib'

# This is where the data files are. Adjust as necessary.
searchpath = "../data"
outfile = "starter_opentype.pdf"

llx = 50
lly = 50
urx = 800
ury = 550

# This font will be used unless another one is specified in the table
defaulttestfont = "NotoSerif-Regular"

headers = [
    "OpenType feature",
    "Option list",
    "Font name",
    "Raw input (feature disabled)",
    "Feature enabled"
]

testcases = [
{
  "description" => "ligatures",
  "fontname" => "",
  "feature" => "liga",
  "text" => "ff fi fl ffi ffl"
},
{
  "description" => "discretionary ligatures",
  "fontname" => "",
  "feature" => "dlig",
  "text" => "ch tz"
},
{
  "description" => "small capitals",
  "fontname" => "",
  "feature" => "smcp",
  "text" => "PostScript"
},
{
  "description" => "ordinals",
  "fontname" => "",
  "feature" => "ordn",
  "text" => "1o 2a 3o"
},
{
  "description" => "fractions",
  "fontname" => "",
  "feature" => "frac",
  "text" => "1/2 1/4 3/4"
},
{
  "description" => "slashed zero",
  "fontname" => "",
  "feature" => "zero",
  "text" => "0"
},
{
  "description" => "historical forms",
  "fontname" => "",
  "feature" => "hist",
  "text" => "s"
},
{
  "description" => "proportional figures",
  "fontname" => "",
  "feature" => "pnum",
  "text" => "0123456789"
},
{
  "description" => "old-style figures",
  "fontname" => "",
  "feature" => "onum",
  "text" => "0123456789"
},
{
  "description" => "lining figures",
  "fontname" => "",
  "feature" => "lnum",
  "text" => "0123456789"
},
{
  "description" => "superscript",
  "fontname" => "",
  "feature" => "sups",
  "text" => "123"
},
{
  "description" => "subscript",
  "fontname" => "",
  "feature" => "subs",
  "text" => "H2SO4"
}
]

begin
  p = PDFlib.new

  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, "") == -1)
      raise "Error: " + p.get_errmsg()
  end

  p.set_info("Creator", "PDFlib starter sample")
  p.set_info("Title", "starter_opentype")

  table = -1
  row = 1
  col = 1

  # Table header
  headers.each do |header|
    optlist = "fittextline={fontname=NotoSerif-Regular " +
       "fontsize=12} margin=4"
    table = p.add_table_cell(table, col, row, header, optlist)
    col += 1
  end

  # Create a table with feature samples, one feature per table row
  row = 2
  testcases.each do |test|
    # Use the entry in the test table if available, and the
    # default test font otherwise. This way we can easily check
    # a font for all features, as well as insert suitable fonts
    # for individual features.
    #/
    if (test["fontname"] != "")
	testfont = test["fontname"]
    else
	testfont = defaulttestfont
    end

    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, test["description"], optlist)
    col += 1

    # Column 2: option list
    buf = "features={" + test["feature"] + "}"
    table = p.add_table_cell(table, col, row, buf, optlist)
    col += 1

    # Column 3: font name
    table = p.add_table_cell(table, col, row, testfont, optlist)
    col += 1

    # Column 4: raw input text with  feature disabled
    optlist = "fittextline={fontname={" + testfont + "} " +
	 "fontsize=12} margin=4"
    table = p.add_table_cell(table, col, row, test["text"], optlist)
    col += 1

    # 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=" + test["feature"]
    if (p.info_font(font, "feature", optlist) == 1)
	# feature is available: apply it to the text
	optlist = "fittextline={fontname={" + testfont + "} " +
	    "fontsize=12 features={" + test["feature"] + "}} margin=4"
	table = p.add_table_cell(table, col, row, test["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)
    end
    row += 1
  end

  # Loop until all of the table is placed; create new pages
  # as long as more table instances need to be placed.
  #
  begin
    p.begin_page_ext(0, 0, "width=a4.height height=a4.width")

    # Shade every other row; draw lines for all table cells.
    optlist = "header=1 fill={{area=rowodd " +
  "fillcolor={gray 0.9}}} stroke={{line=other}} "

    # Place the table instance
    result = p.fit_table(table, llx, lly, urx, ury, optlist)

    if (result == "_error")
  raise "Couldn't place table: " + p.get_errmsg(p)
    end

    p.end_page_ext("")

  end while (result == "_boxfull")

  p.end_document("")

rescue  PDFlibException => pe
  print "PDFlib exception occurred:\n"
  print "[" + pe.get_errnum.to_s + "] " + pe.get_apiname + \
                  ": " + pe.get_errmsg + "\n"
rescue  Exception => e
  print e.backtrace.join("\n") + "\n" + e.to_s
ensure
  p.delete() if p
end

# vim: sw=2
