@@ -218,8 +218,11 @@ function updateTableRows() {
218218 } ) ;
219219}
220220
221+ let currentFontIndex = - 1 ;
222+
221223// Visualization Logic
222224window . showVisualization = function ( index ) {
225+ currentFontIndex = index ;
223226 const result = window . processedFonts [ index ] ;
224227 if ( ! result ) return ;
225228
@@ -235,6 +238,171 @@ window.showVisualization = function(index) {
235238 updateInfo ( 'info-o' , result . o ) ;
236239}
237240
241+ window . printReport = function ( ) {
242+ if ( currentFontIndex === - 1 ) return ;
243+ const result = window . processedFonts [ currentFontIndex ] ;
244+
245+ const canvasI = document . getElementById ( 'canvas-i' ) . toDataURL ( 'image/png' ) ;
246+ const canvasH = document . getElementById ( 'canvas-h' ) . toDataURL ( 'image/png' ) ;
247+ const canvasO = document . getElementById ( 'canvas-o' ) . toDataURL ( 'image/png' ) ;
248+
249+ function getPoints ( char ) {
250+ if ( ! result . original ) return '' ;
251+ const path = result . original . getPath ( char , 0 , 150 , 72 ) ;
252+ return path . commands . filter ( c => c . x !== undefined && c . y !== undefined )
253+ . map ( c => `(${ Math . round ( c . x ) } , ${ Math . round ( c . y ) } )` ) . join ( ', ' ) ;
254+ }
255+
256+ const ptsI = getPoints ( 'I' ) ;
257+ const ptsH = getPoints ( 'H' ) ;
258+ const ptsO = getPoints ( 'O' ) ;
259+
260+ const w = window . open ( '' , '_blank' ) ;
261+ w . document . write ( `
262+ <html>
263+ <head>
264+ <title>ADAFontCheck Report - ${ result . name } </title>
265+ <style>
266+ body { font-family: sans-serif; font-size: 12px; padding: 20px; max-width: 800px; margin: 0 auto; }
267+ h1 { margin-bottom: 5px; font-size: 18px; }
268+ .header { display: flex; justify-content: space-between; border-bottom: 2px solid #333; padding-bottom: 10px; margin-bottom: 15px; align-items: flex-end; }
269+ .timestamp { font-size: 0.9em; color: #666; }
270+ .watermark { font-weight: bold; font-size: 14px; }
271+ .watermark a { color: #0369a1; text-decoration: none; }
272+ .disclaimer { font-size: 0.75em; color: #777; margin-top: 30px; border-top: 1px solid #eee; padding-top: 10px; line-height: 1.3; }
273+ .compliance { font-size: 0.75em; color: #555; margin-top: 10px; line-height: 1.3; }
274+ .compliance a { color: #0369a1; }
275+ .section { margin-bottom: 15px; display: flex; align-items: flex-start; gap: 20px; border-bottom: 1px solid #f0f0f0; padding-bottom: 15px; break-inside: avoid; }
276+ .canvas-container { text-align: center; }
277+ .canvas-img { border: 1px solid #ddd; width: 140px; height: 140px; object-fit: contain; background: #fff; }
278+ .glyph-label { font-weight: bold; font-size: 16px; margin-top: 5px; }
279+ .metrics { flex: 1; }
280+ .coords-label { font-weight: bold; margin-top: 5px; display: block; font-size: 0.9em; }
281+ .coords { font-family: monospace; font-size: 0.85em; color: #444; word-break: break-all; line-height: 1.4; }
282+ .status-pass { color: green; font-weight: bold; }
283+ .status-fail { color: red; font-weight: bold; }
284+ .results-table { width: 100%; border-collapse: collapse; margin-bottom: 20px; }
285+ .results-table th, .results-table td { border: 1px solid #ccc; padding: 6px 10px; text-align: left; font-size: 11px; }
286+ .results-table th { background: #f2f2f2; }
287+ .req-info { font-weight: normal; font-size: 0.85em; color: #666; display: block; margin-top: 2px; }
288+ @media print {
289+ body { padding: 0; }
290+ button { display: none; }
291+ }
292+ </style>
293+ </head>
294+ <body>
295+ <div class="header">
296+ <div>
297+ <h1>${ result . name } </h1>
298+ <div class="timestamp">${ new Date ( ) . toLocaleString ( ) } </div>
299+ </div>
300+ <div class="watermark"><a href="https://adafontcheck.xyz">adafontcheck.xyz</a></div>
301+ </div>
302+
303+ <div class="results">
304+ <h3 style="margin-top:0;">Compliance Summary</h3>
305+ <table class="results-table">
306+ <tr>
307+ <th>Test</th>
308+ <th>Federal Requirements</th>
309+ <th>California Requirements</th>
310+ </tr>
311+ <tr>
312+ <td>
313+ <strong>Tactile</strong><br>
314+ <small>Measured - Stroke: ${ result . stroke . ratio } %, Body: ${ result . body . ratio } %</small>
315+ </td>
316+ <td class="${ result . test . federal . tactile ? 'status-pass' : 'status-fail' } ">
317+ ${ result . test . federal . tactile ? 'PASS' : 'FAIL' }
318+ <span class="req-info">Body: 55-110%, Stroke: 0-15%</span>
319+ </td>
320+ <td class="${ result . test . california . tactile ? 'status-pass' : 'status-fail' } ">
321+ ${ result . test . california . tactile ? 'PASS' : 'FAIL' }
322+ <span class="req-info">Body: 60-110%, Stroke: 0-15%</span>
323+ </td>
324+ </tr>
325+ <tr>
326+ <td>
327+ <strong>Visual</strong><br>
328+ <small>Measured - Stroke: ${ result . stroke . ratio } %, Body: ${ result . body . ratio } %</small>
329+ </td>
330+ <td class="${ result . test . federal . visual ? 'status-pass' : 'status-fail' } ">
331+ ${ result . test . federal . visual ? 'PASS' : 'FAIL' }
332+ <span class="req-info">Body: 55-110%, Stroke: 10-30%</span>
333+ </td>
334+ <td class="${ result . test . california . visual ? 'status-pass' : 'status-fail' } ">
335+ ${ result . test . california . visual ? 'PASS' : 'FAIL' }
336+ <span class="req-info">Body: 60-110%, Stroke: 10-20%</span>
337+ </td>
338+ </tr>
339+ </table>
340+ </div>
341+
342+ <div class="section">
343+ <div class="canvas-container">
344+ <img src="${ canvasI } " class="canvas-img">
345+ <div class="glyph-label">I</div>
346+ </div>
347+ <div class="metrics">
348+ <strong>Stroke Width Ratio:</strong> ${ result . i . ratio } % <br>
349+ Width: ${ result . i . width ? result . i . width . toFixed ( 2 ) : 'N/A' } , Height: ${ result . i . height ? result . i . height . toFixed ( 2 ) : 'N/A' }
350+ <span class="coords-label">Coordinates (Green Dots):</span>
351+ <div class="coords">${ ptsI } </div>
352+ </div>
353+ </div>
354+
355+ <div class="section">
356+ <div class="canvas-container">
357+ <img src="${ canvasH } " class="canvas-img">
358+ <div class="glyph-label">H</div>
359+ </div>
360+ <div class="metrics">
361+ <strong>Body Width Ratio:</strong> ${ result . h . ratio } % <br>
362+ Width: ${ result . h . width ? result . h . width . toFixed ( 2 ) : 'N/A' } , Height: ${ result . h . height ? result . h . height . toFixed ( 2 ) : 'N/A' }
363+ <span class="coords-label">Coordinates (Green Dots):</span>
364+ <div class="coords">${ ptsH } </div>
365+ </div>
366+ </div>
367+
368+ <div class="section" style="border-bottom: none;">
369+ <div class="canvas-container">
370+ <img src="${ canvasO } " class="canvas-img">
371+ <div class="glyph-label">O</div>
372+ </div>
373+ <div class="metrics">
374+ <strong>Body Width Ratio:</strong> ${ result . o . ratio } % <br>
375+ Width: ${ result . o . width ? result . o . width . toFixed ( 2 ) : 'N/A' } , Height: ${ result . o . height ? result . o . height . toFixed ( 2 ) : 'N/A' }
376+ <span class="coords-label">Coordinates (Green Dots):</span>
377+ <div class="coords">${ ptsO } </div>
378+ </div>
379+ </div>
380+
381+ <div class="disclaimer">
382+ <strong>Disclaimer:</strong> ADAFontCheck is not endorsed by the United States Access Board or anyone else. The creators of ADAFontCheck assume no liability or responsibility whatsoever for any direct, indirect, special, or other consequential damages relating to any use of this online service or the contents of this website. Use at your own discretion with confidence.
383+ </div>
384+
385+ <div class="compliance">
386+ This service is based on <a href="https://archive.ada.gov/regs2010/2010ADAStandards/2010ADAStandards.pdf">2010 Americans with Disabilities Act Accessibility Guidelines</a> and <a href="https://up.codes/viewer/california/ibc-2018/chapter/new_11B/accessibility-to-public-buildings-public-accommodations-commercial-buildings-and#new_11B-703">2019 California Building Standards Code</a>.
387+ </div>
388+
389+ <div style="margin-top: 30px; text-align: center; font-size: 0.8em; color: #555; padding: 10px; border-top: 1px solid #ddd;">
390+ Copyright © 2026 - All rights reserved by Crooks Design.
391+ </div>
392+
393+ <script>
394+ window.onload = function() {
395+ setTimeout(function() {
396+ window.print();
397+ }, 500);
398+ }
399+ </script>
400+ </body>
401+ </html>
402+ ` ) ;
403+ w . document . close ( ) ;
404+ }
405+
238406function updateInfo ( id , metrics ) {
239407 const el = document . getElementById ( id ) ;
240408 if ( el ) {
0 commit comments