nakarte

Source code of https://map.sikmir.ru (fork)
git clone git://git.sikmir.ru/nakarte
Log | Files | Refs | LICENSE

pdf.js (2989B)


      1 function header() {
      2     return '%PDF-1.3';
      3 }
      4 
      5 function eof() {
      6     return '%%EOF\n';
      7 }
      8 
      9 function recCatalog() {
     10     return (
     11 `1 0 obj
     12 << /Type /Catalog
     13 /Pages 2 0 R
     14 >>
     15 endobj`);
     16 }
     17 
     18 function recPages(count) {
     19     let kidsIds = [];
     20     for (let i = 0; i < count; i++) {
     21         kidsIds.push(`${i * 3 + 3} 0 R`);
     22     }
     23     kidsIds = kidsIds.join(' ');
     24     return (
     25 `2 0 obj
     26 << /Type /Pages        
     27 /Kids [ ${kidsIds} ]
     28 /Count ${count}
     29 >>
     30 endobj`);
     31 }
     32 
     33 function recPage(serialNum, width, height) {
     34     const pageRecId = serialNum * 3 + 3;
     35     const contentRecId = pageRecId + 1;
     36     const imageRecId = pageRecId + 2;
     37     return (
     38 `${pageRecId} 0 obj
     39 << /Type /Page
     40 /Parent 2 0 R
     41 /MediaBox [0 0 ${width} ${height}]
     42 /Contents ${contentRecId} 0 R
     43 /Rotate ${width > height ? 90 : 0}
     44 /Resources <<
     45     /XObject << /Im${serialNum} ${imageRecId} 0 R >>
     46     /ProcSet [ /PDF /Text /ImageC ] 
     47     >>
     48 >>
     49 endobj`);
     50 }
     51 
     52 function recContent(serialNum, width, height) {
     53     const pageRecId = serialNum * 3 + 3;
     54     const contentRecId = pageRecId + 1;
     55     const contents = (
     56 `q
     57 ${width} 0 0 ${height} 0 0 cm
     58 /Im${serialNum} Do
     59 Q   `);
     60     return (
     61 `${contentRecId} 0 obj
     62 <<
     63 /Length ${contents.length + 1}
     64 >>
     65 stream
     66 ${contents}   
     67 endstream
     68 endobj`);
     69 }
     70 
     71 function recImage(serialNum, widthPixels, heightPixels, data) {
     72     const pageRecId = serialNum * 3 + 3;
     73     const imageRecId = pageRecId + 2;
     74 
     75     return (
     76 `${imageRecId} 0 obj
     77 << /Type /XObject
     78 /Subtype /Image
     79 /Name /Im${serialNum}
     80 /Filter [ /DCTDecode ]
     81 /Width ${widthPixels}
     82 /Height ${heightPixels}
     83 /ColorSpace /DeviceRGB
     84 /BitsPerComponent 8
     85 /Length ${data.length}
     86 >>
     87 stream
     88 ${data}
     89 endstream
     90 endobj`);
     91 }
     92 
     93 function recTrailer(recOffsets, currentOffset) {
     94     const trailer = [];
     95     trailer.push(
     96 `xref
     97 0 ${recOffsets.length + 1}
     98 0000000000 65535 f `);
     99     const zeroes = '0000000000';
    100     for (let offset of recOffsets) {
    101         offset = offset.toString();
    102         let padding = zeroes.substr(offset.length);
    103         trailer.push(`${padding}${offset} 00000 n `);
    104     }
    105 
    106     trailer.push(
    107 `trailer
    108 << /Root 1 0 R
    109 /Size ${recOffsets.length + 1}
    110 >>
    111 startxref
    112 ${currentOffset}`);
    113     return trailer.join('\n');
    114 }
    115 
    116 function makePdf(imagesInfo, resolution) {
    117     let offset = 0;
    118     const offsets = [];
    119     let pdf = [];
    120 
    121     function addRec(s, skipOffset) {
    122         pdf.push(s);
    123         if (!skipOffset) {
    124             offsets.push(offset);
    125         }
    126         offset += s.length;
    127     }
    128 
    129     addRec(header(), true);
    130     addRec(recCatalog());
    131     addRec(recPages(imagesInfo.length));
    132     for (let [i, {data, width, height}] of imagesInfo.entries()) {
    133         let widthPoints = width / resolution * 72,
    134             heightPoints = height / resolution * 72;
    135         addRec(recPage(i, widthPoints, heightPoints));
    136         addRec(recContent(i, widthPoints, heightPoints));
    137         addRec(recImage(i, width, height, data));
    138     }
    139     addRec(recTrailer(offsets, offset), true);
    140     addRec(eof(), true);
    141 
    142     pdf = pdf.join('\n');
    143     return pdf;
    144 }
    145 
    146 export {makePdf};
    147