modeling/src/text/vectorChar.js

  1. const vectorParams = require('./vectorParams')
  2. /**
  3. * Represents a character as a list of segments
  4. * @typedef {Object} VectorCharObject
  5. * @property {Float} width - character width
  6. * @property {Float} height - character height (uppercase)
  7. * @property {Array} segments - character segments [[[x, y], ...], ...]
  8. */
  9. /** Construct a {@link VectorCharObject} from a ascii character whose code is between 31 and 127,
  10. * if the character is not supported it is replaced by a question mark.
  11. * @param {Object|String} [options] - options for construction or ascii character
  12. * @param {Float} [options.xOffset=0] - x offset
  13. * @param {Float} [options.yOffset=0] - y offset
  14. * @param {Float} [options.height=21] - font size (uppercase height)
  15. * @param {Float} [options.extrudeOffset=0] - width of the extrusion that will be applied (manually) after the creation of the character
  16. * @param {String} [options.input='?'] - ascii character (ignored/overwrited if provided as seconds parameter)
  17. * @param {String} [char='?'] - ascii character
  18. * @returns {VectorCharObject}
  19. * @alias module:modeling/text.vectorChar
  20. *
  21. * @example
  22. * let vectorCharObject = vectorChar()
  23. * or
  24. * let vectorCharObject = vectorChar('A')
  25. * or
  26. * let vectorCharObject = vectorChar({ xOffset: 57 }, 'C')
  27. * or
  28. * let vectorCharObject = vectorChar({ xOffset: 78, input: '!' })
  29. */
  30. const vectorChar = (options, char) => {
  31. const {
  32. xOffset, yOffset, input, font, height, extrudeOffset
  33. } = vectorParams(options, char)
  34. let code = input.charCodeAt(0)
  35. if (!code || !font[code]) {
  36. code = 63 // 63 => ?
  37. }
  38. const glyph = [].concat(font[code])
  39. const ratio = (height - extrudeOffset) / font.height
  40. const extrudeYOffset = (extrudeOffset / 2)
  41. const width = glyph.shift() * ratio
  42. const segments = []
  43. let polyline = []
  44. for (let i = 0, il = glyph.length; i < il; i += 2) {
  45. const gx = ratio * glyph[i] + xOffset
  46. const gy = ratio * glyph[i + 1] + yOffset + extrudeYOffset
  47. if (glyph[i] !== undefined) {
  48. polyline.push([gx, gy])
  49. continue
  50. }
  51. segments.push(polyline)
  52. polyline = []
  53. i--
  54. }
  55. if (polyline.length) {
  56. segments.push(polyline)
  57. }
  58. return { width, height, segments }
  59. }
  60. module.exports = vectorChar