Ошибка анализа OTS: неправильный entrySelector для каталога таблицы (ошибка шрифта OpenType) - PullRequest
0 голосов
/ 16 января 2019

У меня есть эта таблица cmap примерно:

{ name: 'cmap',
   fields:
    { version: { type: 'USHORT', value: 0 },
      numTables: { type: 'USHORT', value: 1 },
      platformID: { type: 'USHORT', value: 0 },
      encodingID: { type: 'USHORT', value: 6 },
      offset: { type: 'ULONG', value: 12 },
      format: { type: 'USHORT', value: 4 },
      cmap4Length: { type: 'USHORT', value: 16 },
      language: { type: 'USHORT', value: 0 },
      segCountX2: { type: 'USHORT', value: 126 },
      searchRange: { type: 'USHORT', value: 64 },
      entrySelector: { type: 'USHORT', value: 5 },
      rangeShift: { type: 'USHORT', value: 62 },
      end_0: { type: 'USHORT', value: 48 },
      end_1: { type: 'USHORT', value: 49 },
      end_2: { type: 'USHORT', value: 50 },
      end_3: { type: 'USHORT', value: 51 },
      end_4: { type: 'USHORT', value: 52 },
      end_5: { type: 'USHORT', value: 53 },
      end_6: { type: 'USHORT', value: 54 },
      end_7: { type: 'USHORT', value: 55 },
      end_8: { type: 'USHORT', value: 56 },
      end_9: { type: 'USHORT', value: 57 },
      end_10: { type: 'USHORT', value: 65 },
      end_11: { type: 'USHORT', value: 66 },
      end_12: { type: 'USHORT', value: 67 },
      end_13: { type: 'USHORT', value: 68 },
      end_14: { type: 'USHORT', value: 69 },
      end_15: { type: 'USHORT', value: 70 },
      end_16: { type: 'USHORT', value: 71 },
      end_17: { type: 'USHORT', value: 72 },
      end_18: { type: 'USHORT', value: 73 },
      end_19: { type: 'USHORT', value: 74 },
      end_20: { type: 'USHORT', value: 75 },
      end_21: { type: 'USHORT', value: 76 },
      end_22: { type: 'USHORT', value: 77 },
      end_23: { type: 'USHORT', value: 78 },
      end_24: { type: 'USHORT', value: 79 },
      end_25: { type: 'USHORT', value: 80 },
      end_26: { type: 'USHORT', value: 81 },
      end_27: { type: 'USHORT', value: 82 },
      end_28: { type: 'USHORT', value: 83 },
      end_29: { type: 'USHORT', value: 84 },
      end_30: { type: 'USHORT', value: 85 },
      end_31: { type: 'USHORT', value: 86 },
      end_32: { type: 'USHORT', value: 87 },
      end_33: { type: 'USHORT', value: 88 },
      end_34: { type: 'USHORT', value: 89 },
      end_35: { type: 'USHORT', value: 90 },
      end_36: { type: 'USHORT', value: 97 },
      end_37: { type: 'USHORT', value: 98 },
      end_38: { type: 'USHORT', value: 99 },
      end_39: { type: 'USHORT', value: 100 },
      end_40: { type: 'USHORT', value: 101 },
      end_41: { type: 'USHORT', value: 102 },
      end_42: { type: 'USHORT', value: 103 },
      end_43: { type: 'USHORT', value: 104 },
      end_44: { type: 'USHORT', value: 105 },
      end_45: { type: 'USHORT', value: 106 },
      end_46: { type: 'USHORT', value: 107 },
      end_47: { type: 'USHORT', value: 108 },
      end_48: { type: 'USHORT', value: 109 },
      end_49: { type: 'USHORT', value: 110 },
      end_50: { type: 'USHORT', value: 111 },
      end_51: { type: 'USHORT', value: 112 },
      end_52: { type: 'USHORT', value: 113 },
      end_53: { type: 'USHORT', value: 114 },
      end_54: { type: 'USHORT', value: 115 },
      end_55: { type: 'USHORT', value: 116 },
      end_56: { type: 'USHORT', value: 117 },
      end_57: { type: 'USHORT', value: 118 },
      end_58: { type: 'USHORT', value: 119 },
      end_59: { type: 'USHORT', value: 120 },
      end_60: { type: 'USHORT', value: 121 },
      end_61: { type: 'USHORT', value: 122 },
      end_62: { type: 'USHORT', value: 65535 },
      reservedPad: { type: 'USHORT', value: 0 },
      start_0: { type: 'USHORT', value: 48 },
      start_1: { type: 'USHORT', value: 49 },
      start_2: { type: 'USHORT', value: 50 },
      start_3: { type: 'USHORT', value: 51 },
      start_4: { type: 'USHORT', value: 52 },
      start_5: { type: 'USHORT', value: 53 },
      start_6: { type: 'USHORT', value: 54 },
      start_7: { type: 'USHORT', value: 55 },
      start_8: { type: 'USHORT', value: 56 },
      start_9: { type: 'USHORT', value: 57 },
      start_10: { type: 'USHORT', value: 65 },
      start_11: { type: 'USHORT', value: 66 },
      start_12: { type: 'USHORT', value: 67 },
      start_13: { type: 'USHORT', value: 68 },
      start_14: { type: 'USHORT', value: 69 },
      start_15: { type: 'USHORT', value: 70 },
      start_16: { type: 'USHORT', value: 71 },
      start_17: { type: 'USHORT', value: 72 },
      start_18: { type: 'USHORT', value: 73 },
      start_19: { type: 'USHORT', value: 74 },
      start_20: { type: 'USHORT', value: 75 },
      start_21: { type: 'USHORT', value: 76 },
      start_22: { type: 'USHORT', value: 77 },
      start_23: { type: 'USHORT', value: 78 },
      start_24: { type: 'USHORT', value: 79 },
      start_25: { type: 'USHORT', value: 80 },
      start_26: { type: 'USHORT', value: 81 },
      start_27: { type: 'USHORT', value: 82 },
      start_28: { type: 'USHORT', value: 83 },
      start_29: { type: 'USHORT', value: 84 },
      start_30: { type: 'USHORT', value: 85 },
      start_31: { type: 'USHORT', value: 86 },
      start_32: { type: 'USHORT', value: 87 },
      start_33: { type: 'USHORT', value: 88 },
      start_34: { type: 'USHORT', value: 89 },
      start_35: { type: 'USHORT', value: 90 },
      start_36: { type: 'USHORT', value: 97 },
      start_37: { type: 'USHORT', value: 98 },
      start_38: { type: 'USHORT', value: 99 },
      start_39: { type: 'USHORT', value: 100 },
      start_40: { type: 'USHORT', value: 101 },
      start_41: { type: 'USHORT', value: 102 },
      start_42: { type: 'USHORT', value: 103 },
      start_43: { type: 'USHORT', value: 104 },
      start_44: { type: 'USHORT', value: 105 },
      start_45: { type: 'USHORT', value: 106 },
      start_46: { type: 'USHORT', value: 107 },
      start_47: { type: 'USHORT', value: 108 },
      start_48: { type: 'USHORT', value: 109 },
      start_49: { type: 'USHORT', value: 110 },
      start_50: { type: 'USHORT', value: 111 },
      start_51: { type: 'USHORT', value: 112 },
      start_52: { type: 'USHORT', value: 113 },
      start_53: { type: 'USHORT', value: 114 },
      start_54: { type: 'USHORT', value: 115 },
      start_55: { type: 'USHORT', value: 116 },
      start_56: { type: 'USHORT', value: 117 },
      start_57: { type: 'USHORT', value: 118 },
      start_58: { type: 'USHORT', value: 119 },
      start_59: { type: 'USHORT', value: 120 },
      start_60: { type: 'USHORT', value: 121 },
      start_61: { type: 'USHORT', value: 122 },
      start_62: { type: 'USHORT', value: 65535 },
      idDelta_0: { type: 'SHORT', value: 4 },
      idDelta_1: { type: 'SHORT', value: 4 },
      idDelta_2: { type: 'SHORT', value: 4 },
      idDelta_3: { type: 'SHORT', value: 4 },
      idDelta_4: { type: 'SHORT', value: 4 },
      idDelta_5: { type: 'SHORT', value: 4 },
      idDelta_6: { type: 'SHORT', value: 4 },
      idDelta_7: { type: 'SHORT', value: 4 },
      idDelta_8: { type: 'SHORT', value: 4 },
      idDelta_9: { type: 'SHORT', value: 4 },
      idDelta_10: { type: 'SHORT', value: -39 },
      idDelta_11: { type: 'SHORT', value: -39 },
      idDelta_12: { type: 'SHORT', value: -39 },
      idDelta_13: { type: 'SHORT', value: -39 },
      idDelta_14: { type: 'SHORT', value: -39 },
      idDelta_15: { type: 'SHORT', value: -39 },
      idDelta_16: { type: 'SHORT', value: -39 },
      idDelta_17: { type: 'SHORT', value: -39 },
      idDelta_18: { type: 'SHORT', value: -39 },
      idDelta_19: { type: 'SHORT', value: -39 },
      idDelta_20: { type: 'SHORT', value: -39 },
      idDelta_21: { type: 'SHORT', value: -39 },
      idDelta_22: { type: 'SHORT', value: -39 },
      idDelta_23: { type: 'SHORT', value: -39 },
      idDelta_24: { type: 'SHORT', value: -39 },
      idDelta_25: { type: 'SHORT', value: -39 },
      idDelta_26: { type: 'SHORT', value: -39 },
      idDelta_27: { type: 'SHORT', value: -39 },
      idDelta_28: { type: 'SHORT', value: -39 },
      idDelta_29: { type: 'SHORT', value: -39 },
      idDelta_30: { type: 'SHORT', value: -39 },
      idDelta_31: { type: 'SHORT', value: -39 },
      idDelta_32: { type: 'SHORT', value: -39 },
      idDelta_33: { type: 'SHORT', value: -39 },
      idDelta_34: { type: 'SHORT', value: -39 },
      idDelta_35: { type: 'SHORT', value: -39 },
      idDelta_36: { type: 'SHORT', value: -97 },
      idDelta_37: { type: 'SHORT', value: -97 },
      idDelta_38: { type: 'SHORT', value: -97 },
      idDelta_39: { type: 'SHORT', value: -97 },
      idDelta_40: { type: 'SHORT', value: -97 },
      idDelta_41: { type: 'SHORT', value: -97 },
      idDelta_42: { type: 'SHORT', value: -97 },
      idDelta_43: { type: 'SHORT', value: -97 },
      idDelta_44: { type: 'SHORT', value: -97 },
      idDelta_45: { type: 'SHORT', value: -97 },
      idDelta_46: { type: 'SHORT', value: -97 },
      idDelta_47: { type: 'SHORT', value: -97 },
      idDelta_48: { type: 'SHORT', value: -97 },
      idDelta_49: { type: 'SHORT', value: -97 },
      idDelta_50: { type: 'SHORT', value: -97 },
      idDelta_51: { type: 'SHORT', value: -97 },
      idDelta_52: { type: 'SHORT', value: -97 },
      idDelta_53: { type: 'SHORT', value: -97 },
      idDelta_54: { type: 'SHORT', value: -97 },
      idDelta_55: { type: 'SHORT', value: -97 },
      idDelta_56: { type: 'SHORT', value: -97 },
      idDelta_57: { type: 'SHORT', value: -97 },
      idDelta_58: { type: 'SHORT', value: -97 },
      idDelta_59: { type: 'SHORT', value: -97 },
      idDelta_60: { type: 'SHORT', value: -97 },
      idDelta_61: { type: 'SHORT', value: -97 },
      idDelta_62: { type: 'SHORT', value: 1 },
      idRangeOffset_0: { type: 'USHORT', value: 0 },
      idRangeOffset_1: { type: 'USHORT', value: 0 },
      idRangeOffset_2: { type: 'USHORT', value: 0 },
      idRangeOffset_3: { type: 'USHORT', value: 0 },
      idRangeOffset_4: { type: 'USHORT', value: 0 },
      idRangeOffset_5: { type: 'USHORT', value: 0 },
      idRangeOffset_6: { type: 'USHORT', value: 0 },
      idRangeOffset_7: { type: 'USHORT', value: 0 },
      idRangeOffset_8: { type: 'USHORT', value: 0 },
      idRangeOffset_9: { type: 'USHORT', value: 0 },
      idRangeOffset_10: { type: 'USHORT', value: 0 },
      idRangeOffset_11: { type: 'USHORT', value: 0 },
      idRangeOffset_12: { type: 'USHORT', value: 0 },
      idRangeOffset_13: { type: 'USHORT', value: 0 },
      idRangeOffset_14: { type: 'USHORT', value: 0 },
      idRangeOffset_15: { type: 'USHORT', value: 0 },
      idRangeOffset_16: { type: 'USHORT', value: 0 },
      idRangeOffset_17: { type: 'USHORT', value: 0 },
      idRangeOffset_18: { type: 'USHORT', value: 0 },
      idRangeOffset_19: { type: 'USHORT', value: 0 },
      idRangeOffset_20: { type: 'USHORT', value: 0 },
      idRangeOffset_21: { type: 'USHORT', value: 0 },
      idRangeOffset_22: { type: 'USHORT', value: 0 },
      idRangeOffset_23: { type: 'USHORT', value: 0 },
      idRangeOffset_24: { type: 'USHORT', value: 0 },
      idRangeOffset_25: { type: 'USHORT', value: 0 },
      idRangeOffset_26: { type: 'USHORT', value: 0 },
      idRangeOffset_27: { type: 'USHORT', value: 0 },
      idRangeOffset_28: { type: 'USHORT', value: 0 },
      idRangeOffset_29: { type: 'USHORT', value: 0 },
      idRangeOffset_30: { type: 'USHORT', value: 0 },
      idRangeOffset_31: { type: 'USHORT', value: 0 },
      idRangeOffset_32: { type: 'USHORT', value: 0 },
      idRangeOffset_33: { type: 'USHORT', value: 0 },
      idRangeOffset_34: { type: 'USHORT', value: 0 },
      idRangeOffset_35: { type: 'USHORT', value: 0 },
      idRangeOffset_36: { type: 'USHORT', value: 0 },
      idRangeOffset_37: { type: 'USHORT', value: 0 },
      idRangeOffset_38: { type: 'USHORT', value: 0 },
      idRangeOffset_39: { type: 'USHORT', value: 0 },
      idRangeOffset_40: { type: 'USHORT', value: 0 },
      idRangeOffset_41: { type: 'USHORT', value: 0 },
      idRangeOffset_42: { type: 'USHORT', value: 0 },
      idRangeOffset_43: { type: 'USHORT', value: 0 },
      idRangeOffset_44: { type: 'USHORT', value: 0 },
      idRangeOffset_45: { type: 'USHORT', value: 0 },
      idRangeOffset_46: { type: 'USHORT', value: 0 },
      idRangeOffset_47: { type: 'USHORT', value: 0 },
      idRangeOffset_48: { type: 'USHORT', value: 0 },
      idRangeOffset_49: { type: 'USHORT', value: 0 },
      idRangeOffset_50: { type: 'USHORT', value: 0 },
      idRangeOffset_51: { type: 'USHORT', value: 0 },
      idRangeOffset_52: { type: 'USHORT', value: 0 },
      idRangeOffset_53: { type: 'USHORT', value: 0 },
      idRangeOffset_54: { type: 'USHORT', value: 0 },
      idRangeOffset_55: { type: 'USHORT', value: 0 },
      idRangeOffset_56: { type: 'USHORT', value: 0 },
      idRangeOffset_57: { type: 'USHORT', value: 0 },
      idRangeOffset_58: { type: 'USHORT', value: 0 },
      idRangeOffset_59: { type: 'USHORT', value: 0 },
      idRangeOffset_60: { type: 'USHORT', value: 0 },
      idRangeOffset_61: { type: 'USHORT', value: 0 },
      idRangeOffset_62: { type: 'USHORT', value: 0 } } }

С закодированным выводом в виде массива 8-битных целых чисел, как это:

0 0 0 1 0 0 0 6 0 0 0 12 0 4 0 16 0 0 0 126 0 64 0 5 0 62 0 48 0 49 0 50 0 51 0 52 0 53 0 54 0 55 0 56 0 57 0 65 0 66 0 67 0 68 0 69 0 70 0 71 0 72 0 73 0 74 0 75 0 76 0 77 0 78 0 79 0 80 0 81 0 82 0 83 0 84 0 85 0 86 0 87 0 88 0 89 0 90 0 97 0 98 0 99 0 100 0 101 0 102 0 103 0 104 0 105 0 106 0 107 0 108 0 109 0 110 0 111 0 112 0 113 0 114 0 115 0 116 0 117 0 118 0 119 0 120 0 121 0 122 255 255 0 0 0 48 0 49 0 50 0 51 0 52 0 53 0 54 0 55 0 56 0 57 0 65 0 66 0 67 0 68 0 69 0 70 0 71 0 72 0 73 0 74 0 75 0 76 0 77 0 78 0 79 0 80 0 81 0 82 0 83 0 84 0 85 0 86 0 87 0 88 0 89 0 90 0 97 0 98 0 99 0 100 0 101 0 102 0 103 0 104 0 105 0 106 0 107 0 108 0 109 0 110 0 111 0 112 0 113 0 114 0 115 0 116 0 117 0 118 0 119 0 120 0 121 0 122 255 255 0 4 0 4 0 4 0 4 0 4 0 4 0 4 0 4 0 4 0 4 255 217 255 217 255 217 255 217 255 217 255 217 255 217 255 217 255 217 255 217 255 217 255 217 255 217 255 217 255 217 255 217 255 217 255 217 255 217 255 217 255 217 255 217 255 217 255 217 255 217 255 217 255 217 255 217 25 5 159 255 159 255 159 255 159 255 159 255 159 255 159 255 159 255 159 255 159 255 159 255 159 255 159 255 159 255 159 255 159 255 159 255 159 255 159 255 159 255 159 255 159 255 159 159 159 255 159 155 159 255 255 159 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

Я не уверен, как лучше всего отладить это, но я хотел спросить, выглядит ли это правильно, или что я должен сделать для отладки. Не спрашиваю, верны ли точные значения, но значения, которые я почти уверен Я ввел правильно, все до rangeShift. После этого он генерируется. Но эти значения от segCountX2 до rangeShift, даже если я думаю, что я их правильно понимаю, я получаю эту ошибку: OTS parsing error: incorrect entrySelector for table directory, даже если я просто сделаю файл шрифта только со всеми полями до этого точка! Так что файл шрифта крошечный, но все та же ошибка. Я делаю вычисления в соответствии с spec , например:

var numTables = tables.length
var highestPowerOf2 = Math.pow(2, Math.log2(numTables))
var searchRange = 16 * highestPowerOf2
var entrySelector = Math.log2(highestPowerOf2) * 16
var rangeShift = (numTables * 16) - searchRange

var fields = {
  sfntVersion: { type: 'TAG', value: 'OTTO'},
  numTables: { type: 'USHORT', value: numTables},
  searchRange: { type: 'USHORT', value: searchRange},
  entrySelector: { type: 'USHORT', value: entrySelector},
  rangeShift: { type: 'USHORT', value: rangeShift},
}

Но все еще не работает. Я также пытался это .

1 Ответ

0 голосов
/ 16 января 2019

Похоже, что это было исправлено переключением на использование ссылки Apple вместо Microsoft для расчетов:

https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6.html

Подтаблица смещения, задокументированная в таблице 4, начинается с типа масштабирующего шрифта. Количество помеченных таблиц в 'sfnt' следует. Сам каталог таблиц и любые подтаблицы не включены в это число. Записи для searchRange, entrySelector и rangeShift используются для облегчения быстрого двоичного поиска в каталоге таблицы, который следует. Если шрифт не имеет большого количества таблиц, последовательный поиск будет достаточно быстрым.

Если требуется более быстрый поиск, бинарный поиск легче всего выполнить по числу записей, которое является степенью двойки. Это позволяет сократить количество элементов для поиска в два раза путем сдвига. Оставшиеся записи смещаемых подтаблиц должны быть установлены следующим образом:

searchRange - это наибольшая степень двух, меньше или равная количеству элементов в таблице, то есть наибольшее количество элементов, которые можно легко найти. rangeShift - количество элементов минус searchRange; то есть количество элементов, которые не будут просматриваться, если вы посмотрите только на элементы searchRange. Перед началом цикла поиска сравните целевой элемент с элементом с номером rangeShift. Если целевой элемент меньше, чем rangeShift, выполните поиск с начала таблицы. Если оно больше, ищите, начиная с элемента с номером rangeShift.

entrySelector - это log2 (searchRange). Он говорит, сколько итераций цикла поиска необходимо. (т.е. сколько раз сократить диапазон пополам) Обратите внимание, что searchRange, entrySelector и rangeShift умножаются на 16, что соответствует размеру записи каталога.

...