text: /**
   * @file 写cmap表
   * @author mengke01(kekee000@gmail.com)
   */
  
  
  
  
  
  
          /**
           * 创建`子表0`
           *
           * @param {Writer} writer 写对象
           * @param {Array} unicodes unicodes列表
           * @return {Writer}
           */
          function writeSubTable0(writer, unicodes) {
  
              writer.writeUint16(0); // format
              writer.writeUint16(262); // length
              writer.writeUint16(0); // language
  
              // Array of unicodes 0..255
              var i = -1;
              var unicode;
              while ((unicode = unicodes.shift())) {
                  while (++i < unicode[0]) {
                      writer.writeUint8(0);
                  }
  
                  writer.writeUint8(unicode[1]);
                  i = unicode[0];
              }
  
              while (++i < 256) {
                  writer.writeUint8(0);
              }
  
              return writer;
          }
  
  
          /**
           * 创建`子表4`
           *
           * @param {Writer} writer 写对象
           * @param {Array} segments 分块编码列表
           * @return {Writer}
           */
          function writeSubTable4(writer, segments) {
  
              writer.writeUint16(4); // format
              writer.writeUint16(24 + segments.length * 8); // length
              writer.writeUint16(0); // language
  
              var segCount = segments.length + 1;
              var maxExponent = Math.floor(Math.log(segCount) / Math.LN2);
              var searchRange = 2 * Math.pow(2, maxExponent);
  
              writer.writeUint16(segCount * 2); // segCountX2
              writer.writeUint16(searchRange); // searchRange
              writer.writeUint16(maxExponent); // entrySelector
              writer.writeUint16(2 * segCount - searchRange); // rangeShift
  
              // end list
              segments.forEach(function (segment) {
                  writer.writeUint16(segment.end);
              });
              writer.writeUint16(0xFFFF); // end code
              writer.writeUint16(0); // reservedPad
  
  
              // start list
              segments.forEach(function (segment) {
                  writer.writeUint16(segment.start);
              });
              writer.writeUint16(0xFFFF); // start code
  
              // id delta
              segments.forEach(function (segment) {
                  writer.writeUint16(segment.delta);
              });
              writer.writeUint16(1);
  
              // Array of range offsets, it doesn't matter when deltas present
              for (var i = 0, l = segments.length; i < l; i++) {
                  writer.writeUint16(0);
              }
              writer.writeUint16(0); // rangeOffsetArray should be finished with 0
  
              return writer;
          }
  
          /**
           * 创建`子表12`
           *
           * @param {Writer} writer 写对象
           * @param {Array} segments 分块编码列表
           * @return {Writer}
           */
          function writeSubTable12(writer, segments) {
  
              writer.writeUint16(12); // format
              writer.writeUint16(0); // reserved
              writer.writeUint32(16 + segments.length * 12); // length
              writer.writeUint32(0); // language
              writer.writeUint32(segments.length); // nGroups
  
              segments.forEach(function (segment) {
                  writer.writeUint32(segment.start);
                  writer.writeUint32(segment.end);
                  writer.writeUint32(segment.startId);
              });
  
              return writer;
          }
  
          /**
           * 写subtableheader
           *
           * @param {Writer} writer Writer对象
           * @param {number} platform 平台
           * @param {number} encoding 编码
           * @param {number} offset 偏移
           * @return {Writer}
           */
          function writeSubTableHeader(writer, platform, encoding, offset) {
              writer.writeUint16(platform); // platform
              writer.writeUint16(encoding); // encoding
              writer.writeUint32(offset); // offset
              return writer;
          }
  
  
          /**
           * 写cmap表数据
           *
           * @param  {Object} writer 写入器
           * @param  {Object} ttf    ttf对象
           * @return {Object}        写入器
           */
          function write(writer, ttf) {
              var hasGLyphsOver2Bytes = ttf.support.cmap.hasGLyphsOver2Bytes;
  
              // write table header.
              writer.writeUint16(0); // version
              writer.writeUint16(hasGLyphsOver2Bytes ? 4 : 3); // count
  
              // header size
              var subTableOffset = 4 + (hasGLyphsOver2Bytes ? 32 : 24);
              var format4Size = ttf.support.cmap.format4Size;
              var format0Size = ttf.support.cmap.format0Size;
  
              // subtable 4, unicode
              writeSubTableHeader(writer, 0, 3, subTableOffset);
  
              // subtable 0, mac standard
              writeSubTableHeader(writer, 1, 0, subTableOffset + format4Size);
  
              // subtable 4, windows standard
              writeSubTableHeader(writer, 3, 1, subTableOffset);
  
              if (hasGLyphsOver2Bytes) {
                  writeSubTableHeader(writer, 3, 10, subTableOffset + format4Size + format0Size);
              }
  
              // write tables, order of table seem to be magic, it is taken from TTX tool
              writeSubTable4(writer, ttf.support.cmap.format4Segments);
              writeSubTable0(writer, ttf.support.cmap.format0Segments);
  
              if (hasGLyphsOver2Bytes) {
                  writeSubTable12(writer, ttf.support.cmap.format12Segments);
              }
  
  
              return writer;
          }
  
          module.exports = write;
      
  