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