mirroring.js 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. import data from './data/bidiMirroring.data.js'
  2. import { parseCharacterMap } from './util/parseCharacterMap.js'
  3. let mirrorMap
  4. function parse () {
  5. if (!mirrorMap) {
  6. //const start = performance.now()
  7. const { map, reverseMap } = parseCharacterMap(data, true)
  8. // Combine both maps into one
  9. reverseMap.forEach((value, key) => {
  10. map.set(key, value)
  11. })
  12. mirrorMap = map
  13. //console.log(`mirrored chars parsed in ${performance.now() - start}ms`)
  14. }
  15. }
  16. /**
  17. * Get the mirrored character for a given character, if one exists.
  18. * @param {string} char
  19. * @return {string|null}
  20. */
  21. export function getMirroredCharacter (char) {
  22. parse()
  23. return mirrorMap.get(char) || null
  24. }
  25. /**
  26. * Given a string and its resolved embedding levels, build a map of indices to replacement chars
  27. * for any characters in right-to-left segments that have defined mirrored characters.
  28. * @param {string} string
  29. * @param {Uint8Array} embeddingLevels
  30. * @param {number?} [start]
  31. * @param {number?} [end]
  32. * @return {Map<number, string>}
  33. */
  34. export function getMirroredCharactersMap(string, embeddingLevels, start, end) {
  35. let strLen = string.length
  36. start = Math.max(0, start == null ? 0 : +start)
  37. end = Math.min(strLen - 1, end == null ? strLen - 1 : +end)
  38. const map = new Map()
  39. for (let i = start; i <= end; i++) {
  40. if (embeddingLevels[i] & 1) { //only odd (rtl) levels
  41. const mirror = getMirroredCharacter(string[i])
  42. if (mirror !== null) {
  43. map.set(i, mirror)
  44. }
  45. }
  46. }
  47. return map
  48. }