#lang racket
(require rackunit racket/runtime-path fontland)

#|
approximates
https://github.com/mbutterick/fontkit/blob/master/test/glyph_mapping.js
|#

(define-runtime-path open-sans-ttf "data/OpenSans/OpenSans-Regular.ttf")
(define-runtime-path source-sans-otf "data/SourceSansPro/SourceSansPro-Regular.otf")
(define-runtime-path mada-ttf "data/Mada/Mada-Regular.subset1.ttf")

 (define font (open-font open-sans-ttf))

#|
import fontkit from '../src';
import assert from 'assert';

describe('character to glyph mapping', function() {
  describe('basic cmap handling', function() {
    let font = fontkit.openSync(__dirname + '/data/OpenSans/OpenSans-Regular.ttf');

    it('should get characterSet', function() {
      assert(Array.isArray(font.characterSet));
      return assert.equal(font.characterSet.length, 884);
    });

    it('should check if a character is supported', function() {
      assert(font.hasGlyphForCodePoint('a'.charCodeAt()));
      return assert(!font.hasGlyphForCodePoint(0));
    });

    it('should get a glyph for a character code', function() {
      let glyph = font.glyphForCodePoint('a'.charCodeAt());
      assert.equal(glyph.id, 68);
      return assert.deepEqual(glyph.codePoints, [97]);
    });

    it('should map a string to glyphs', function() {
      let glyphs = font.glyphsForString('hello', []);
      assert(Array.isArray(glyphs));
      assert.equal(glyphs.length, 5);
      assert.deepEqual(glyphs.map(g => g.id), [75, 72, 79, 79, 82]);
      return assert.deepEqual(glyphs.map(g => g.codePoints), [[104], [101], [108], [108], [111]]);
    });

    it('should support unicode variation selectors', function() {
      let font = fontkit.openSync(__dirname + '/data/fonttest/TestCMAP14.otf');
      let glyphs = font.glyphsForString('\u{82a6}\u{82a6}\u{E0100}\u{82a6}\u{E0101}');
      assert.deepEqual(glyphs.map(g => g.id), [1, 1, 2]);
    });

    it('should support legacy encodings when no unicode cmap is found', function() {
      let font = fontkit.openSync(__dirname + '/data/fonttest/TestCMAPMacTurkish.ttf');
      let glyphs = font.glyphsForString("“ABÇĞIİÖŞÜ”");
      assert.deepEqual(glyphs.map(g => g.id), [200, 34, 35, 126, 176, 42, 178, 140, 181, 145, 201]);
    });
  });

  describe('opentype features', function() {
    let font = fontkit.openSync(__dirname + '/data/SourceSansPro/SourceSansPro-Regular.otf');

    it('should list available features', () =>
      assert.deepEqual(font.availableFeatures, [
        'aalt', 'c2sc', 'case', 'ccmp', 'dnom', 'frac', 'liga', 'numr',
        'onum', 'ordn', 'pnum', 'salt', 'sinf', 'smcp', 'ss01', 'ss02',
        'ss03', 'ss04', 'ss05', 'subs', 'sups', 'zero', 'kern', 'mark',
        'mkmk', 'size'
      ])
    );

    it('should apply opentype GSUB features', function() {
      let {glyphs} = font.layout('ffi', ['dlig']);
      assert.equal(glyphs.length, 2);
      assert.deepEqual(glyphs.map(g => g.id), [ 514, 36 ]);
      return assert.deepEqual(glyphs.map(g => g.codePoints), [[102, 102], [105]]);
    });

    it('should enable fractions when using fraction slash', function() {
      let {glyphs} = font.layout('123 1⁄16 123');
      return assert.deepEqual(glyphs.map(g => g.id), [ 1088, 1089, 1090, 1, 1617, 1724, 1603, 1608, 1, 1088, 1089, 1090 ]);
    });

    it('should not break if can’t enable fractions when using fraction slash', function() {
      let {glyphs} = font.layout('a⁄b ⁄ 1⁄ ⁄2');
      return assert.deepEqual(glyphs.map(g => g.id), [ 28, 1724, 29, 1, 1724, 1, 1617, 1724, 1, 1724, 1604 ]);
    });
  });

  describe('AAT features', function() {
    let font = fontkit.openSync(__dirname + '/data/Play/Play-Regular.ttf');

    it('should list available features', () => assert.deepEqual(font.availableFeatures, [ 'tnum', 'sups', 'subs', 'numr', 'onum', 'lnum', 'liga', 'kern' ]));

    it('should apply default AAT morx features', function() {
      let {glyphs} = font.layout('ffi 1⁄2');
      assert.equal(glyphs.length, 5);
      assert.deepEqual(glyphs.map(g => g.id), [ 767, 3, 20, 645, 21 ]);
      return assert.deepEqual(glyphs.map(g => g.codePoints), [[102, 102, 105], [32], [49], [8260], [50]]);
    });

    it('should apply user specified features', function() {
      let {glyphs} = font.layout('ffi 1⁄2', [ 'numr' ]);
      assert.equal(glyphs.length, 3);
      assert.deepEqual(glyphs.map(g => g.id), [ 767, 3, 126 ]);
      return assert.deepEqual(glyphs.map(g => g.codePoints), [[102, 102, 105], [32], [49, 8260, 50]]);
    });

    it('should handle rtl direction', function() {
      let {glyphs} = font.layout('ffi', [], null, null, "rtl");
      assert.equal(glyphs.length, 3);
      assert.deepEqual(glyphs.map(g => g.id), [ 76, 73, 73 ]);
      return assert.deepEqual(glyphs.map(g => g.codePoints), [[105], [102], [102]]);
    });

    it('should apply indic reordering features', function() {
      let f = fontkit.openSync(__dirname + '/data/Khmer/Khmer.ttf');
      let {glyphs} = f.layout('ខ្ញុំអាចញ៉ាំកញ្ចក់បាន ដោយគ្មានបញ្ហា');
      assert.deepEqual(glyphs.map(g => g.id), [
        45, 153, 177, 112, 248, 188, 49, 296, 44, 187, 149, 44, 117, 236, 188, 63, 3, 107,
        226, 188, 69, 218, 169, 188, 63, 64, 255, 175, 188
      ]);

      return assert.deepEqual(glyphs.map(g => g.codePoints), [
        [ 6017 ], [ 6098, 6025 ], [ 6075 ], [ 6086 ], [ 6050 ], [ 6070 ], [ 6021 ],
        [ 6025, 6089, 6070, 6086 ], [ 6016 ], [ 6025 ], [ 6098, 6021 ], [ 6016 ],
        [ 6091 ], [ 6036 ], [ 6070 ], [ 6035 ], [ 32 ], [ 6084 ], [ 6026 ], [ 6070 ],
        [ 6041 ], [ 6018 ], [ 6098, 6040 ], [ 6070 ], [ 6035 ], [ 6036 ], [ 6025 ],
        [ 6098, 6048 ], [ 6070 ]
      ]);
    });
  });

  describe('glyph id to strings', function () {
    it('should return strings from cmap that map to a given glyph', function () {
      let font = fontkit.openSync(__dirname + '/data/OpenSans/OpenSans-Regular.ttf');
      let strings = font.stringsForGlyph(68);
      assert.deepEqual(strings, ['a']);
    });

    it('should return strings from AAT morx table that map to the given glyph', function () {
      let font = fontkit.openSync(__dirname + '/data/Play/Play-Regular.ttf');
      let strings = font.stringsForGlyph(767);
      assert.deepEqual(strings, ['ffi']);
    });
  });
});

|#
