490 {
491 AppendPDFObject("%PDF-1.5\n%\xDE\xAD\xBE\xEB\n");
492
493
494 AppendPDFObject(
495 "1 0 obj\n"
496 "<<\n"
497 " /Type /Catalog\n"
498 " /Pages 2 0 R\n"
499 ">>\nendobj\n");
500
501
502
503
504 AppendPDFObject("");
505
506
507 AppendPDFObject(
508 "3 0 obj\n"
509 "<<\n"
510 " /BaseFont /GlyphLessFont\n"
511 " /DescendantFonts [ 4 0 R ]\n"
512 " /Encoding /Identity-H\n"
513 " /Subtype /Type0\n"
514 " /ToUnicode 6 0 R\n"
515 " /Type /Font\n"
516 ">>\n"
517 "endobj\n");
518
519
520 std::stringstream stream;
521
522 stream.imbue(std::locale::classic());
523 stream << "4 0 obj\n"
524 "<<\n"
525 " /BaseFont /GlyphLessFont\n"
526 " /CIDToGIDMap 5 0 R\n"
527 " /CIDSystemInfo\n"
528 " <<\n"
529 " /Ordering (Identity)\n"
530 " /Registry (Adobe)\n"
531 " /Supplement 0\n"
532 " >>\n"
533 " /FontDescriptor 7 0 R\n"
534 " /Subtype /CIDFontType2\n"
535 " /Type /Font\n"
536 " /DW "
537 << (1000 / kCharWidth)
538 << "\n"
539 ">>\n"
540 "endobj\n";
541 AppendPDFObject(stream.str().c_str());
542
543
544 const int kCIDToGIDMapSize = 2 * (1 << 16);
545 const std::unique_ptr<unsigned char[]> cidtogidmap(new unsigned char[kCIDToGIDMapSize]);
546 for (
int i = 0;
i < kCIDToGIDMapSize;
i++) {
547 cidtogidmap[
i] = (
i % 2) ? 1 : 0;
548 }
549 size_t len;
550 unsigned char *comp = zlibCompress(cidtogidmap.get(), kCIDToGIDMapSize, &len);
551 stream.str("");
552 stream << "5 0 obj\n"
553 "<<\n"
554 " /Length "
555 << len
556 << " /Filter /FlateDecode\n"
557 ">>\n"
558 "stream\n";
560 long objsize = stream.str().size();
561 AppendData(
reinterpret_cast<char *
>(comp), len);
562 objsize += len;
563 lept_free(comp);
564 const char *endstream_endobj =
565 "endstream\n"
566 "endobj\n";
568 objsize += strlen(endstream_endobj);
569 AppendPDFObjectDIY(objsize);
570
571 const char stream2[] =
572 "/CIDInit /ProcSet findresource begin\n"
573 "12 dict begin\n"
574 "begincmap\n"
575 "/CIDSystemInfo\n"
576 "<<\n"
577 " /Registry (Adobe)\n"
578 " /Ordering (UCS)\n"
579 " /Supplement 0\n"
580 ">> def\n"
581 "/CMapName /Adobe-Identify-UCS def\n"
582 "/CMapType 2 def\n"
583 "1 begincodespacerange\n"
584 "<0000> <FFFF>\n"
585 "endcodespacerange\n"
586 "1 beginbfrange\n"
587 "<0000> <FFFF> <0000>\n"
588 "endbfrange\n"
589 "endcmap\n"
590 "CMapName currentdict /CMap defineresource pop\n"
591 "end\n"
592 "end\n";
593
594
595 stream.str("");
596 stream << "6 0 obj\n"
597 "<< /Length "
598 << (sizeof(stream2) - 1)
599 << " >>\n"
600 "stream\n"
601 << stream2
602 << "endstream\n"
603 "endobj\n";
604 AppendPDFObject(stream.str().c_str());
605
606
607 stream.str("");
608 stream << "7 0 obj\n"
609 "<<\n"
610 " /Ascent 1000\n"
611 " /CapHeight 1000\n"
612 " /Descent -1\n"
613 " /Flags 5\n"
614 " /FontBBox [ 0 0 "
615 << (1000 / kCharWidth)
616 << " 1000 ]\n"
617 " /FontFile2 8 0 R\n"
618 " /FontName /GlyphLessFont\n"
619 " /ItalicAngle 0\n"
620 " /StemV 80\n"
621 " /Type /FontDescriptor\n"
622 ">>\n"
623 "endobj\n";
624 AppendPDFObject(stream.str().c_str());
625
626 stream.str("");
627 stream << datadir_.c_str() << "/pdf.ttf";
628 const uint8_t *font;
629 std::ifstream input(stream.str().c_str(), std::ios::in | std::ios::binary);
630 std::vector<unsigned char> buffer(std::istreambuf_iterator<char>(input), {});
631 auto size = buffer.size();
632 if (size) {
633 font = buffer.data();
634 } else {
635#if !defined(NDEBUG)
636 tprintf(
"Cannot open file \"%s\"!\nUsing internal glyphless font.\n", stream.str().c_str());
637#endif
638 font = pdf_ttf;
639 size = sizeof(pdf_ttf);
640 }
641
642
643 stream.str("");
644 stream << "8 0 obj\n"
645 "<<\n"
646 " /Length "
647 << size
648 << "\n"
649 " /Length1 "
650 << size
651 << "\n"
652 ">>\n"
653 "stream\n";
655 objsize = stream.str().size();
656 AppendData(
reinterpret_cast<const char *
>(font), size);
657 objsize += size;
659 objsize += strlen(endstream_endobj);
660 AppendPDFObjectDIY(objsize);
661 return true;
662}
void tprintf(const char *format,...)