// MissingGlyphExample.cpp

#include <iostream>
#include <fstream>
#include <stdexcept>
#include <LASi.h>

#ifndef MAX
#define MAX( a, b )                      ( ( ( a ) > ( b ) ) ? ( a ) : ( b ) )
#endif
#ifndef MIN
#define MIN( a, b )                      ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) )
#endif

using namespace LASi;
using namespace std;

int main(const int argc, char* const argv[]) 
{
  ofstream strm;

  try {
    PostscriptDocument doc;
    int i, x=10, y=800, fixed_lineSpacing=25;
    double xAdvance,yMinimum,yMaximum,lineSpacing;
    double llx=x,urx=x,lly=y,ury=y;
    int nstrings = 17;
    const char * strings[17] = {
      "Display range of glyphs (chosen such that one or more of them normally are missing or",
      "correspond to pure bitmapped fonts) to verify that libLASi does something with low",
      "impact in these cases, i.e., uses the default replacement glyph (normally an empty box)",
      "for all freetype errors generated by missing glyphs or pure bitmap fonts that are",
      "unsuitable for libLASi needs.",
      "",
      "Unicode U+0802 SAMARITAN LETTER GAMAN: ࠂ",
      "Unicode U+08AA ARABIC LETTER REH WITH LOOP: ࢪ",
      "Unicode U+2AF4 TRIPLE VERTICAL BAR BINARY RELATION: ⫴", 
      "Unicode U+2AF5 TRIPLE VERTICAL BAR WITH HORIZONTAL STROKE: ⫵", 
      "Unicode U+2AF6 TRIPLE COLON OPERATOR: ⫶", 
      "Unicode U+2AF7 TRIPLE NESTED LESS-THAN: ⫷", 
      "Unicode U+2AF8 TRIPLE NESTED GREATER-THAN: ⫸", 
      "Unicode U+1010A AEGEAN NUMBER FOUR: 𐄊",
      "Unicode U+1F70A ALCHEMICAL SYMBOL FOR VINEGAR: 🜊",
      "Unicode U+2648 ARIES (twice): ♈♈",
      "Embedded newlines a\\nb\\nc: a\nb\nc",
    };

    //
    // Set font to generic "serif":
    //
    doc.osBody() << setFont("serif") << setFontSize(18) << endl;
    doc.osBody() << x << " " << y << " moveto" << endl;
    for(i=0;i<nstrings; i++)
    {
      doc.osBody() << show(strings[i]);
      doc.get_dimensions(strings[i],&lineSpacing,&xAdvance,&yMinimum,&yMaximum);
      // Calculate total bounding box
      llx = x-1;
      urx = MAX(urx, x+xAdvance+1);
      lly = MIN(lly, y+yMinimum-1);
      ury = MAX(ury, y+yMaximum+1);
      y -= fixed_lineSpacing;
      doc.osBody() << x << " " << y << " moveto" << endl;
    }

    //
    // Postscript showpage:
    //
    doc.osBody() << "showpage" << endl;
    
    // Write out postscript document, including bounding box. 
    // If the bounding box arguments are omitted then no
    // bounding box is included in the file.
    //
    if (argc == 1) {
      doc.write(cout,llx,lly,urx,ury);
    }
    else {
      strm.open(argv[1]);
      doc.write(strm,llx,lly,urx,ury);
      strm.close();
    }
    
  } catch (runtime_error& e) {
  
    cerr << e.what() << endl;
    return 1;
    
  }

  return 0;
  
}

