#!/usr/bin/perl
# $Id: starter_fallback.pl,v 1.1.2.1 2010/01/29 11:10:02 rjs Exp $
# Starter sample for fallback fonts
#
# Required software: PDFlib/PDFlib+PDI/PPS 8
# Required data: suitable fonts, Japanese CMaps

use pdflib_pl 8.0;
use strict;

# This is where the data files are. Adjust as necessary. 
use constant searchpath => "../data";
use constant outfile => "starter_fallback.pdf";

use constant {
    llx => 50.0,
    lly => 50.0,
    urx => 800.0,
    ury => 550.0
};

use constant headers => (
    "Use case",
    "Option list for the 'fallbackfonts' option",
    "Base font",
    "With fallback font"
);

# Key names used to make a dictionary for the description of the
# testcase entries
my @testcase_keys = qw(usecase fontname encoding fallbackoptions text);

# Function to create a hash describing each testcase
sub make_testcase_hash {
    my $values = $_[0]; # reference to array
    my %result;
    @result{@testcase_keys} = @{$values};
    return \%result;
}

# The testcases organized as an array of references to hashes
my @testcases = map { make_testcase_hash($_) } (
    [ # Add Euro glyph to an encoding which doesn't support it
      "Extend 8-bit encoding",  # usecase
      "Helvetica",              # fontname
      "iso8859-1",              # encoding
      "{fontname=Helvetica encoding=unicode forcechars=euro}", #fallbackoptions
      # Reference Euro glyph by name (since it is missing from the encoding) 
      "123&euro;"               # text
    ],
    [
      "Use Euro glyph from another font",
      "Courier",
      "winansi",
      "{fontname=Helvetica encoding=unicode forcechars=euro textrise=-5%}",
      "123&euro;"
    ],
    [
      "Enlarge all glyphs in a font",
      "Times-Italic",
      "winansi",
      # Enlarge all glyphs to better match other fonts of the same point size
      "{fontname=Times-Italic encoding=unicode forcechars={U+0020-U+00FF} " .
      "fontsize=120%}",
      "font size"
    ],
    [
      "Add enlarged pictogram",
      "Times-Roman",
      "unicode",
      # pointing hand pictogram 
      "{fontname=ZapfDingbats encoding=unicode forcechars=.a12 fontsize=150% " .
      "textrise=-15%}",
      "Bullet symbol: &.a12;"
    ],
    [
      "Add enlarged symbol glyph",
      "Times-Roman",
      "unicode",
      "{fontname=Symbol encoding=unicode forcechars=U+2663 fontsize=125%}",
      "Club symbol: &#x2663;"
    ],
    [ # Greek characters missing in the font will be pulled from Symbol font 
      "Add Greek characters to Latin font",
      "Times-Roman",
      "unicode",
      "{fontname=Symbol encoding=unicode}",
      "Greek text: &#x039B;&#x039F;&#x0393;&#x039F;&#x03A3;"
    ],
    [ # Font with end-user defined character (EUDC) 
      "Gaiji with EUDC font",
      "KozMinProVI-Regular",
      "unicode",
      "{fontname=EUDC encoding=unicode forcechars=U+E000 fontsize=140% " .
      "textrise=-20%}",
      "Gaiji: &#xE000;"
    ],
    [ # SING fontlet containing a single gaiji character 
      "Gaiji with SING font",
      "KozMinProVI-Regular",
      "unicode",
      "{fontname=PDFlibWing encoding=unicode forcechars=gaiji}",
      "Gaiji: &#xE000;"
    ],
    [ "Replace Latin characters in CJK font",
      "KozMinProVI-Regular",
      "unicode",
      "{fontname=Courier-Bold encoding=unicode forcechars={U+0020-U+007E}}",
      "Latin and &#x65E5;&#x672C;&#x8A9E;"
    ],
    # Requires "Unicode BMP Fallback SIL" font in fallback.ttf 
    [ # Identify missing glyphs caused by workflow problems 
      "Identify missing glyphs",
      "Times-Roman",
      "unicode",
      "{fontname=fallback encoding=unicode}",
      # deliberately use characters which are not available in the base font 
      "Missing glyphs: &#x1234; &#x672C; &#x8A9E;"
    ]
);

my $p = PDF_new();

eval {
    my $optlist;
    
    PDF_set_parameter($p, "SearchPath", searchpath);
    PDF_set_parameter($p, "textformat", "bytes");
    PDF_set_parameter($p, "charref", "true");
    PDF_set_parameter($p, "glyphcheck", "replace");

    # This means that formatting and other errors will raise an
    # exception. This simplifies our sample code, but is not
    # recommended for production code.
    PDF_set_parameter($p, "errorpolicy", "exception");

    # Set an output path according to the name of the topic 
    if (PDF_begin_document($p, outfile, "") == -1) {
        printf("Error: %s\n", PDF_get_errmsg($p));
        PDF_delete($p);
        exit(2);
    }

    PDF_set_info($p, "Creator", "PDFlib starter sample");
    PDF_set_info($p, "Title", "starter_fallback");

    # Start Page 
    PDF_begin_page_ext($p, 0, 0, "width=a4.height height=a4.width");

    my $table = -1;

    # Table header 
    my $col = 1;
    foreach my $header (headers) {
        $optlist =
           "fittextline={fontname=Helvetica-Bold encoding=unicode fontsize=11} " .
           "margin=4";
        $table = PDF_add_table_cell($p, $table, $col, 1, $header, $optlist);
        $col += 1;
    }

    # Create fallback samples, one use case per row
    my $row = 2;
    foreach my $testcase (@testcases) {
        $col = 1;

        # Column 1: description of the use case 
        $optlist = 
            "fittextline={fontname=Helvetica encoding=unicode fontsize=11} " .
            "margin=4";
        $table = PDF_add_table_cell($p, $table, $col++, $row,
                                    $testcase->{usecase}, $optlist);

        # Column 2: reproduce option list literally 
        $optlist = 
            "fittextline={fontname=Helvetica encoding=unicode fontsize=10} " .
            "margin=4";
        $table = PDF_add_table_cell($p, $table, $col++, $row,
                                    $testcase->{fallbackoptions}, $optlist);

        # Column 3: text with base font 
        $optlist = sprintf
             "fittextline={fontname=%s encoding=%s fontsize=11 " .
             "replacementchar=? } margin=4",
             $testcase->{fontname}, $testcase->{encoding};
        $table = PDF_add_table_cell($p, $table, $col++, $row,
                                    $testcase->{text}, $optlist);

        # Column 4: text with base font and fallback fonts 
        $optlist = sprintf
             "fittextline={fontname=%s encoding=%s " .
             "fontsize=11 fallbackfonts={%s}} margin=4",
             $testcase->{fontname},
             $testcase->{encoding},
             $testcase->{fallbackoptions};
        $table = PDF_add_table_cell($p, $table, $col++, $row,
                                    $testcase->{text}, $optlist);
        
        $row += 1;
    }

    # Place the table 
    $optlist = "header=1 fill={{area=rowodd fillcolor={gray 0.9}}} " .
                "stroke={{line=other}} ";
    my $result = PDF_fit_table($p, $table, llx, lly, urx, ury, $optlist);

    if ($result eq "_error")
    {
        printf("Couldn't place table: %s\n", PDF_get_errmsg($p));
        PDF_delete($p);
        exit(2);
    }

    PDF_end_page_ext($p, "");
    PDF_end_document($p, "");
};

if ($@) {
    printf("$0: PDFlib Exception occurred:\n");
    printf(" $@\n");
    exit(1);
}
