{"id":40477154,"url":"https://github.com/mlightcad/shx-parser","last_synced_at":"2026-01-20T18:25:46.780Z","repository":{"id":319311161,"uuid":"1073685796","full_name":"mlightcad/shx-parser","owner":"mlightcad","description":"AutoCAD SHX font JavaScript Paser","archived":false,"fork":false,"pushed_at":"2025-12-23T05:09:01.000Z","size":157,"stargazers_count":1,"open_issues_count":1,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-12-24T19:59:02.058Z","etag":null,"topics":["autocad","javascript","parser","shx","shx-font","typescript"],"latest_commit_sha":null,"homepage":"https://mlightcad.github.io/shx-parser/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mlightcad.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-10-10T13:22:30.000Z","updated_at":"2025-12-23T05:09:04.000Z","dependencies_parsed_at":null,"dependency_job_id":"9acb3ce2-09c4-4a21-a46a-25b716e24734","html_url":"https://github.com/mlightcad/shx-parser","commit_stats":null,"previous_names":["mlightcad/shx-parser"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mlightcad/shx-parser","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mlightcad%2Fshx-parser","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mlightcad%2Fshx-parser/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mlightcad%2Fshx-parser/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mlightcad%2Fshx-parser/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mlightcad","download_url":"https://codeload.github.com/mlightcad/shx-parser/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mlightcad%2Fshx-parser/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28609117,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-20T16:10:39.856Z","status":"ssl_error","status_checked_at":"2026-01-20T16:10:39.493Z","response_time":117,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["autocad","javascript","parser","shx","shx-font","typescript"],"created_at":"2026-01-20T18:25:46.691Z","updated_at":"2026-01-20T18:25:46.769Z","avatar_url":"https://github.com/mlightcad.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SHX Parser\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![npm version](https://badge.fury.io/js/@mlightcad%2Fshx-parser.svg)](https://badge.fury.io/js/@mlightcad/shx-parser)\n\nA TypeScript library for parsing AutoCAD SHX font files. It is ported from [this project](https://github.com/yzylovepmn/YFonts.SHX) written by C#. This project fixed many bugs on the original parser. Moreover, support parsing [extended big font](https://help.autodesk.com/view/OARX/2023/ENU/?guid=GUID-00ED0CC6-A4BE-4591-93FA-598CC40AA43D).\n\nIf you are interested in the format of SHX font, please refer to [this document](https://help.autodesk.com/view/OARX/2023/ENU/?guid=GUID-06832147-16BE-4A66-A6D0-3ADF98DC8228).\n\n[**🌐 Live Demo**](https://mlightcad.gitlab.io/shx-parser/)\n\n## Features\n\n- Parse SHX font files and extract font data\n- Support for various SHX font types:\n  - Shapes\n  - Bigfont (including Extended Big Font)\n  - Unifont\n- Shape parsing with performance optimization:\n  - On-demand parsing\n  - Shape caching by character code\n- Modern TypeScript implementation\n- Object-oriented design\n- Comprehensive test coverage\n\n## Installation\n\nUsing npm:\n```bash\nnpm install @mlightcad/shx-parser\n```\n\nUsing pnpm:\n```bash\npnpm add @mlightcad/shx-parser\n```\n\nUsing yarn:\n```bash\nyarn add @mlightcad/shx-parser\n```\n\n## Demo app\n\nThe [demo app](https://mlightcad.gitlab.io/shx-parser/) is provided with a web-based interface for viewing and exploring SHX font files with the following features:\n\n- **Dual Loading Modes**:\n  - Upload local SHX files\n  - Select from a remote font library\n\n- **Main Features**:\n  - View all characters in a responsive grid layout\n  - Search characters by code (decimal/hex)\n  - Click characters to see them in a larger modal view\n  - Toggle between decimal and hexadecimal code display\n\n- **Display Information**:\n  - Shows font type, version, and character count\n  - Renders characters as SVG graphics\n  - Responsive grid layout that works on different screen sizes\n\n\n## Quick Start\n\n```typescript\nimport { ShxFont } from '@mlightcad/shx-parser';\n\n// Load the font file\nconst fontFileData = /* ArrayBuffer containing SHX font file data */;\nconst font = new ShxFont(fontFileData);\n\n// Get shape for a character\nconst charCode = 65; // ASCII code for 'A'\nconst fontSize = 12;\nconst shape = font.getCharShape(charCode, fontSize);\n\nif (shape) {\n  console.log(shape.polylines); // Array of polylines representing the character\n  console.log(shape.lastPoint); // End point of the character\n}\n\n// Clean up resources when done\nfont.release();\n```\n\n## API Documentation\n\n### `ShxFont`\n\nThe main class for working with SHX fonts.\n\n```typescript\nclass ShxFont {\n  fontData: ShxFontData;\n  constructor(data: ArrayBuffer);\n  getCharShape(charCode: number, size: number): ShxShape | null;\n  release(): void;\n}\n```\n\n### `ShxShape`\n\nRepresents a parsed character shape.\n\n```typescript\ninterface ShxShape {\n  polylines: Array\u003c{ x: number; y: number }[]\u003e; // Array of polyline points\n  lastPoint?: { x: number; y: number };         // End point of the shape (optional)\n  bbox: {                                       // Bounding box of the shape\n    minX: number;\n    minY: number;\n    maxX: number;\n    maxY: number;\n  };\n}\n```\n\n### Font Data Structure\n\nThe library parses SHX font files into the following structure:\n\n```typescript\ninterface ShxFontData {\n  header: {\n    fontType: ShxFontType;     // 'shapes' | 'bigfont' | 'unifont'\n    fileHeader: string;        // Font file header information\n    fileVersion: string;       // Font file version\n  };\n  content: {\n    data: Record\u003cnumber, Uint8Array\u003e;  // Character code to bytecode data mapping\n    info: string;              // Additional font information\n    orientation: string;       // Text orientation ('horizontal' | 'vertical')\n    height: number;            // Character height (units used to scale primitives)\n    width: number;             // Character width (units used to scale primitives)\n    isExtended: boolean;       // Flag to indicate if the font is an extended big font\n  };\n}\n```\n\n## Example\n\n### Loading and Displaying Font Information\n\n```typescript\nimport { readFile } from 'fs/promises';\nimport { ShxFont } from '@mlightcad/shx-parser';\n\nasync function loadFont(filePath: string) {\n  const buffer = await readFile(filePath);\n  const font = new ShxFont(buffer.buffer);\n  \n  // Display font information\n  const fontData = font.fontData;\n  console.log('Font Information:');\n  console.log('----------------');\n  console.log('Font Type:', fontData.header.fontType);\n  console.log('Header:', fontData.header.fileHeader);\n  console.log('Version:', fontData.header.fileVersion);\n  console.log('Info:', fontData.content.info);\n  console.log('Orientation:', fontData.content.orientation);\n  console.log('Height:', fontData.content.height);\n  console.log('Width:', fontData.content.width);\n  console.log('Number of shapes:', Object.keys(fontData.content.data).length);\n  \n  return font;\n}\n```\n\n### Converting Shape to SVG Path\n\n```typescript\nfunction shapeToSvgPath(shape: ShxShape, x: number = 0, y: number = 0): string {\n  if (!shape?.polylines.length) return '';\n  \n  return shape.polylines.map(polyline =\u003e {\n    if (!Array.isArray(polyline) || polyline.length === 0) return '';\n    \n    return polyline.map((point, i) =\u003e {\n      const scaledX = (Number(point.x) || 0) + x;\n      const scaledY = -(Number(point.y) || 0) + y; // Flip Y coordinate for SVG\n      const command = i === 0 ? 'M' : 'L';\n      return `${command} ${scaledX.toFixed(2)} ${scaledY.toFixed(2)}`;\n    }).join(' ');\n  }).filter(Boolean).join(' ');\n}\n```\n\n### Rendering Text to SVG\n\n```typescript\ninterface SvgOptions {\n  width?: number;\n  height?: number;\n  strokeWidth?: string;\n  strokeColor?: string;\n  isAutoFit?: boolean;\n}\n\nfunction renderTextToSvg(\n  font: ShxFont,\n  text: string,\n  fontSize: number,\n  options: SvgOptions = {}\n): SVGElement {\n  const {\n    width = 1000,\n    height = 1000,\n    strokeWidth = '0.1%',\n    strokeColor = 'black',\n    isAutoFit = false\n  } = options;\n\n  // Create SVG element\n  const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n  svg.setAttribute('width', width.toString());\n  svg.setAttribute('height', height.toString());\n  svg.setAttribute('viewBox', `0 0 ${width} ${height}`);\n\n  const padding = fontSize;\n  let currentX = padding;\n  let maxHeight = 0;\n\n  // Process each character\n  for (const char of text) {\n    const charCode = char.charCodeAt(0);\n    const shape = font.getCharShape(charCode, fontSize);\n    \n    if (shape) {\n      const group = document.createElementNS('http://www.w3.org/2000/svg', 'g');\n      \n      if (isAutoFit) {\n        // Auto-fit positioning\n        const bbox = shape.bbox;\n        const padding = 0.2; // 20% padding\n        const charBBoxWidth = bbox.maxX - bbox.minX;\n        const charBBoxHeight = bbox.maxY - bbox.minY;\n        const centerX = (bbox.minX + bbox.maxX) / 2;\n        const centerY = (bbox.minY + bbox.maxY) / 2;\n        group.setAttribute('transform', `translate(${currentX - centerX}, ${-centerY})`);\n      } else {\n        // Fixed positioning\n        group.setAttribute('transform', `translate(${currentX + width / 2}, ${height / 2})`);\n      }\n\n      // Create path for the character\n      const pathData = shapeToSvgPath(shape);\n      const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');\n      path.setAttribute('d', pathData);\n      path.setAttribute('fill', 'none');\n      path.setAttribute('stroke', strokeColor);\n      path.setAttribute('stroke-width', strokeWidth);\n      \n      group.appendChild(path);\n      svg.appendChild(group);\n\n      // Update position for next character\n      if (shape.lastPoint) {\n        currentX += shape.lastPoint.x + fontSize * 0.5;\n      } else {\n        currentX += fontSize;\n      }\n      \n      maxHeight = Math.max(maxHeight, fontSize);\n    }\n  }\n\n  return svg;\n}\n\n// Example usage:\nasync function main() {\n  try {\n    const font = await loadFont('path/to/your/font.shx');\n    \n    // Example 1: Basic rendering\n    const svgElement1 = renderTextToSvg(font, \"Hello\", 12);\n    document.body.appendChild(svgElement1);\n    \n    // Example 2: Auto-fit rendering with custom options\n    const svgElement2 = renderTextToSvg(font, \"Hello\", 12, {\n      width: 1000,\n      height: 1000,\n      strokeWidth: '0.1%',\n      strokeColor: 'black',\n      isAutoFit: true\n    });\n    document.body.appendChild(svgElement2);\n    \n    // Clean up resources when done\n    font.release();\n  } catch (error) {\n    console.error('Error:', error instanceof Error ? error.message : 'An unknown error occurred');\n  }\n}\n```\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.\n\n1. Fork the repository\n2. Create your feature branch (`git checkout -b feature/amazing-feature`)\n3. Commit your changes (`git commit -m 'Add some amazing feature'`)\n4. Push to the branch (`git push origin feature/amazing-feature`)\n5. Open a Pull Request\n\nPlease make sure to update tests as appropriate.\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n## Support\n\nIf you have any questions or run into issues, please:\n1. Check the [GitHub Issues](https://gitlab.com/mlightcad/shx-parser/-/issues) page\n2. Open a new issue if your problem hasn't been reported yet\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmlightcad%2Fshx-parser","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmlightcad%2Fshx-parser","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmlightcad%2Fshx-parser/lists"}