Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x | import { constants } from "@keymanapp/ldml-keyboard-constants"; import { KMXPlus } from "@keymanapp/common-types"; import { build_strs_index, BUILDER_STR_REF, BUILDER_STRS } from "./build-strs.js"; import { BUILDER_LIST } from "./build-list.js"; import { BUILDER_SECTION } from "./builder-section.js"; import KMXPlusData = KMXPlus.KMXPlusData; import LayrEntry = KMXPlus.LayrEntry; import LayrRow = KMXPlus.LayrRow; import StrsItem = KMXPlus.StrsItem; /* ------------------------------------------------------------------ * layr section - ------------------------------------------------------------------ */ /** * List of layers, the <layers> element */ interface BUILDER_LAYR_LIST { hardware: BUILDER_STR_REF; // hardware or 'touch' layer: number; // index of first layer in the list, in the count: number; // number of layer entries in the list minDeviceWidth: number; // width in millimeters _layers: LayrEntry[]; // original layer entry, for in-memory only }; /** * <layer> element */ interface BUILDER_LAYR_LAYER { id: BUILDER_STR_REF; // str of layer id _id: string; // original layer id, for sorting mod: number; // bitfield with modifier info row: number; // row index into row subtable _rows: LayrRow[]; // original rows, for in-memory only count: number; // number of row entries }; /** * <row> element */ interface BUILDER_LAYR_ROW { key: number; // index into key subtable count: number; // number of keys }; /** * portion of keys attribute of <row> */ interface BUILDER_LAYR_KEY { key: number; }; /** * Builder for the 'keys' section */ export interface BUILDER_LAYR extends BUILDER_SECTION { listCount: number, // number of entries in lists subtable layerCount: number, // number of entries in layers subtable rowCount: number, // number of entries in rows subtable keyCount: number, // number of entries in keys subtable lists: BUILDER_LAYR_LIST[], // subtable of <layers> elements layers: BUILDER_LAYR_LAYER[], // subtable of <layer> elements rows: BUILDER_LAYR_ROW[], // subtable of <row> elements keys: BUILDER_LAYR_KEY[], // subtable of key entries }; export function build_layr(kmxplus: KMXPlusData, sect_strs: BUILDER_STRS, sect_list: BUILDER_LIST): BUILDER_LAYR { if (!kmxplus.layr?.lists) { return null; // if there aren't any layers at all (which should be an invalid keyboard) } const layr: BUILDER_LAYR = { ident: constants.hex_section_id(constants.section.layr), size: constants.length_layr, _offset: 0, listCount: kmxplus.layr.lists.length, layerCount: 0, // calculated below rowCount: 0, // calculated below keyCount: 0, // calculated below lists: [], layers: [], rows: [], keys: [] }; layr.lists = kmxplus.layr.lists.map((list) => { const blist: BUILDER_LAYR_LIST = { hardware: build_strs_index(sect_strs, list.hardware), layer: null, // to be set below _layers: list.layers, count: list.layers.length, minDeviceWidth: list.minDeviceWidth, }; return blist; }); // now sort the lists layr.lists.sort((a, b) => { // sort by string # if (a.hardware < b.hardware) { return -1; } else if (a.hardware > b.hardware) { return 1; } if (a.minDeviceWidth < b.minDeviceWidth) { return -1; } else if (a.minDeviceWidth > b.minDeviceWidth) { return 1; } else { return 0; // same } }); // Now allocate the layers, rows, and keys layr.lists.forEach((list) => { list.layer = layr.layers.length; // index to first layer in list const blayers = list._layers.map((layer) => { const blayer: BUILDER_LAYR_LAYER = { _id: layer.id.value, // original id id: build_strs_index(sect_strs, layer.id), mod: layer.mod, row: null, // row ID, to be filled in _rows: layer.rows, // temporary count: layer.rows.length, // number of rows }; return blayer; }); // sort the new layers blayers.sort((a, b) => StrsItem.binaryStringCompare(a._id, b._id)); blayers.forEach((layer) => { layer.row = layr.rows.length; // index to first row in list layer._rows.forEach((row) => { const brow: BUILDER_LAYR_ROW = { key: layr.keys.length, count: row.keys.length, }; row.keys.forEach((key) => { const bkey: BUILDER_LAYR_KEY = { key: build_strs_index(sect_strs, key), }; layr.keys.push(bkey); }); layr.rows.push(brow); }); layr.layers.push(layer); }); }); layr.layerCount = layr.layers.length; layr.rowCount = layr.rows.length; layr.keyCount = layr.keys.length; const offset = constants.length_layr + (constants.length_layr_list * layr.listCount) + (constants.length_layr_entry * layr.layerCount) + (constants.length_layr_row * layr.rowCount) + (constants.length_layr_key * layr.keyCount); layr.size = offset; return layr; } |