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 | 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, LdmlKeyboardTypes } from "@keymanapp/common-types"; import { build_strs_index, BUILDER_STR_REF, BUILDER_STRS } from "./build-strs.js"; import { BUILDER_SECTION, BUILDER_U32CHAR } from "./builder-section.js"; import { build_uset_index, BUILDER_USET, BUILDER_USET_REF } from "./build-uset.js"; import Elem = KMXPlus.Elem; /* ------------------------------------------------------------------ * elem section ------------------------------------------------------------------ */ /** return from build_elem_index */ export type BUILDER_ELEM_REF = number; interface BUILDER_ELEM_ELEMENT { element: BUILDER_STR_REF | BUILDER_USET_REF | BUILDER_U32CHAR; // str | UTF-32 char flags: number; _value: string; }; interface BUILDER_ELEM_STRING { offset: number; length: number; items: BUILDER_ELEM_ELEMENT[]; _value: LdmlKeyboardTypes.ElementString; }; /** * Builder for the 'elem' section */ export interface BUILDER_ELEM extends BUILDER_SECTION { count: number; strings: BUILDER_ELEM_STRING[]; }; function binaryElemCompare(a: BUILDER_ELEM_STRING, b: BUILDER_ELEM_STRING): number { for(let i = 0; i < a.items.length && i < b.items.length; i++) { if(a.items[i]._value < b.items[i]._value) return -1; if(a.items[i]._value > b.items[i]._value) return 1; if(a.items[i].flags < b.items[i].flags) return -1; if(a.items[i].flags > b.items[i].flags) return 1; } if(a.items.length < b.items.length) return -1; if(a.items.length > b.items.length) return 1; return 0; } export function build_elem(source_elem: Elem, sect_strs: BUILDER_STRS, sect_uset: BUILDER_USET): BUILDER_ELEM { const result: BUILDER_ELEM = { ident: constants.hex_section_id(constants.section.elem), size: 0, // finalized below _offset: 0, count: source_elem.strings.length, strings: [], // finalized below }; result.strings = source_elem.strings.map(item => { const res: BUILDER_ELEM_STRING = { offset: 0, // finalized below length: item.length, items: [], _value: item }; res.items = item.map(v => { let element; const type = (v.flags & constants.elem_flags_type); if (type === constants.elem_flags_type_char || type == constants.elem_flags_type_str) { element = build_strs_index(sect_strs, v.value); } else if (type == constants.elem_flags_type_uset) { element = build_uset_index(sect_uset, v.uset); } else { throw Error(`Internal Error: Unknown element type 0x${type.toString(16)}`); } return { element, flags: v.flags | // ((v.order ?? 0) << constants.elem_flags_order_bitshift) | // -128 to +127; used only by reorder element values ((v.tertiary ?? 0) << constants.elem_flags_tertiary_bitshift), // -128 to +127; used only by reorder element values _value: v.value.value }; }); return res; }); result.strings.sort((a,b) => binaryElemCompare(a, b)); /* Calculate offsets and total size */ let offset = constants.length_elem + constants.length_elem_item * result.count; for(const item of result.strings) { if (item.length === 0) { // no length gets a zero offset item.offset = 0; } else { item.offset = offset; offset += item.length * constants.length_elem_item_element; } } result.size = offset; return result; } export function build_elem_index(sect_elem: BUILDER_ELEM, value: LdmlKeyboardTypes.ElementString) : BUILDER_ELEM_REF{ if(!(value instanceof LdmlKeyboardTypes.ElementString)) { throw new Error('unexpected value '+value); } const result = sect_elem.strings.findIndex(v => value.isEqual(v._value)); if(result < 0) { throw new Error('unexpectedly missing StrsItem '+value); } return <BUILDER_ELEM_REF>result; } |