
/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */


#include "SkPDFCatalog.h"
#include "SkPDFDevice.h"
#include "SkPDFDocument.h"
#include "SkPDFFont.h"
#include "SkPDFPage.h"
#include "SkPDFTypes.h"
#include "SkStream.h"
#include "SkTSet.h"

static void addResourcesToCatalog(bool firstPage,
                                  SkTSet<SkPDFObject*>* resourceSet,
                                  SkPDFCatalog* catalog) {
    for (int i = 0; i < resourceSet->count(); i++) {
        catalog->addObject((*resourceSet)[i], firstPage);
    }
}

static void perform_font_subsetting(SkPDFCatalog* catalog,
                                    const SkTDArray<SkPDFPage*>& pages,
                                    SkTDArray<SkPDFObject*>* substitutes) {
    SkASSERT(catalog);
    SkASSERT(substitutes);

    SkPDFGlyphSetMap usage;
    for (int i = 0; i < pages.count(); ++i) {
        usage.merge(pages[i]->getFontGlyphUsage());
    }
    SkPDFGlyphSetMap::F2BIter iterator(usage);
    const SkPDFGlyphSetMap::FontGlyphSetPair* entry = iterator.next();
    while (entry) {
        SkPDFFont* subsetFont =
            entry->fFont->getFontSubset(entry->fGlyphSet);
        if (subsetFont) {
            catalog->setSubstitute(entry->fFont, subsetFont);
            substitutes->push(subsetFont);  // Transfer ownership to substitutes
        }
        entry = iterator.next();
    }
}

SkPDFDocument::SkPDFDocument(Flags flags)
        : fXRefFileOffset(0),
          fTrailerDict(NULL) {
    fCatalog.reset(new SkPDFCatalog(flags));
    fDocCatalog = SkNEW_ARGS(SkPDFDict, ("Catalog"));
    fCatalog->addObject(fDocCatalog, true);
    fFirstPageResources = NULL;
    fOtherPageResources = NULL;
}

SkPDFDocument::~SkPDFDocument() {
    fPages.safeUnrefAll();

    // The page tree has both child and parent pointers, so it creates a
    // reference cycle.  We must clear that cycle to properly reclaim memory.
    for (int i = 0; i < fPageTree.count(); i++) {
        fPageTree[i]->clear();
    }
    fPageTree.safeUnrefAll();

    if (fFirstPageResources) {
        fFirstPageResources->safeUnrefAll();
    }
    if (fOtherPageResources) {
        fOtherPageResources->safeUnrefAll();
    }

    fSubstitutes.safeUnrefAll();

    fDocCatalog->unref();
    SkSafeUnref(fTrailerDict);
    SkDELETE(fFirstPageResources);
    SkDELETE(fOtherPageResources);
}

namespace {
class Streamer {
public:
    Streamer(SkPDFCatalog* cat, SkWStream* out)
        : fCat(cat), fOut(out), fBaseOffset(SkToOffT(out->bytesWritten())) {
    }

    void stream(SkPDFObject* obj) {
        fCat->setFileOffset(obj, this->offset());
        obj->emit(fOut, fCat, true);
    }

    off_t offset() {
        return SkToOffT(fOut->bytesWritten()) - fBaseOffset;
    }

private:
    SkPDFCatalog* const fCat;
    SkWStream* const fOut;
    const off_t fBaseOffset;
};
}  // namespace

bool SkPDFDocument::emitPDF(SkWStream* stream) {
    if (fPages.isEmpty()) {
        return false;
    }
    for (int i = 0; i < fPages.count(); i++) {
        if (fPages[i] == NULL) {
            return false;
        }
    }

    fFirstPageResources = SkNEW(SkTSet<SkPDFObject*>);
    fOtherPageResources = SkNEW(SkTSet<SkPDFObject*>);

    // We haven't emitted the document before if fPageTree is empty.
    if (fPageTree.isEmpty()) {
        SkPDFDict* pageTreeRoot;
        SkPDFPage::GeneratePageTree(fPages, fCatalog.get(), &fPageTree,
                                    &pageTreeRoot);
        fDocCatalog->insert("Pages", new SkPDFObjRef(pageTreeRoot))->unref();

        /* TODO(vandebo): output intent
        SkAutoTUnref<SkPDFDict> outputIntent = new SkPDFDict("OutputIntent");
        outputIntent->insert("S", new SkPDFName("GTS_PDFA1"))->unref();
        outputIntent->insert("OutputConditionIdentifier",
                             new SkPDFString("sRGB"))->unref();
        SkAutoTUnref<SkPDFArray> intentArray = new SkPDFArray;
        intentArray->append(outputIntent.get());
        fDocCatalog->insert("OutputIntent", intentArray.get());
        */

        SkAutoTUnref<SkPDFDict> dests(SkNEW(SkPDFDict));

        bool firstPage = true;
        /* The references returned in newResources are transfered to
         * fFirstPageResources or fOtherPageResources depending on firstPage and
         * knownResources doesn't have a reference but just relies on the other
         * two sets to maintain a reference.
         */
        SkTSet<SkPDFObject*> knownResources;

        // mergeInto returns the number of duplicates.
        // If there are duplicates, there is a bug and we mess ref counting.
        SkDEBUGCODE(int duplicates =) knownResources.mergeInto(*fFirstPageResources);
        SkASSERT(duplicates == 0);

        for (int i = 0; i < fPages.count(); i++) {
            if (i == 1) {
                firstPage = false;
                SkDEBUGCODE(duplicates =) knownResources.mergeInto(*fOtherPageResources);
            }
            SkTSet<SkPDFObject*> newResources;
            fPages[i]->finalizePage(
                fCatalog.get(), firstPage, knownResources, &newResources);
            addResourcesToCatalog(firstPage, &newResources, fCatalog.get());
            if (firstPage) {
                SkDEBUGCODE(duplicates =) fFirstPageResources->mergeInto(newResources);
            } else {
                SkDEBUGCODE(duplicates =) fOtherPageResources->mergeInto(newResources);
            }
            SkASSERT(duplicates == 0);

            SkDEBUGCODE(duplicates =) knownResources.mergeInto(newResources);
            SkASSERT(duplicates == 0);

            fPages[i]->appendDestinations(dests);
        }

        if (dests->size() > 0) {
            SkPDFDict* raw_dests = dests.get();
            fFirstPageResources->add(dests.detach());  // Transfer ownership.
            fCatalog->addObject(raw_dests, true /* onFirstPage */);
            fDocCatalog->insert("Dests", SkNEW_ARGS(SkPDFObjRef, (raw_dests)))->unref();
        }

        // Build font subsetting info before proceeding.
        perform_font_subsetting(fCatalog.get(), fPages, &fSubstitutes);
    }

    Streamer out(fCatalog, stream);
    emitHeader(stream);

    out.stream(fDocCatalog);
    out.stream(fPages[0]);
    out.stream(fPages[0]->getContentStream());

    for (int i = 0; i < fFirstPageResources->count(); i++) {
        out.stream((*fFirstPageResources)[i]);
    }

    SkTSet<SkPDFObject*>* firstPageSubstituteResources =
            fCatalog->getSubstituteList(true);
    for (int i = 0; i < firstPageSubstituteResources->count(); ++i) {
        out.stream((*firstPageSubstituteResources)[i]);
    }
    // TODO(vandebo): Support linearized format
    // if (fPages.size() > 1) {
    //     // TODO(vandebo): Save the file offset for the first page xref table.
    //     fCatalog->emitXrefTable(stream, true);
    // }

    for (int i = 0; i < fPageTree.count(); i++) {
        out.stream(fPageTree[i]);
    }

    for (int i = 1; i < fPages.count(); i++) {
        out.stream(fPages[i]->getContentStream());
    }

    for (int i = 0; i < fOtherPageResources->count(); i++) {
        out.stream((*fOtherPageResources)[i]);
    }

    SkTSet<SkPDFObject*>* otherSubstituteResources =
            fCatalog->getSubstituteList(false);
    for (int i = 0; i < otherSubstituteResources->count(); ++i) {
        out.stream((*otherSubstituteResources)[i]);
    }

    fXRefFileOffset = out.offset();
    int64_t objCount = fCatalog->emitXrefTable(stream, fPages.count() > 1);
    emitFooter(stream, objCount);
    return true;
}

bool SkPDFDocument::setPage(int pageNumber, SkPDFDevice* pdfDevice) {
    if (!fPageTree.isEmpty()) {
        return false;
    }

    pageNumber--;
    SkASSERT(pageNumber >= 0);

    if (pageNumber >= fPages.count()) {
        int oldSize = fPages.count();
        fPages.setCount(pageNumber + 1);
        for (int i = oldSize; i <= pageNumber; i++) {
            fPages[i] = NULL;
        }
    }

    SkPDFPage* page = new SkPDFPage(pdfDevice);
    SkSafeUnref(fPages[pageNumber]);
    fPages[pageNumber] = page;  // Reference from new passed to fPages.
    return true;
}

bool SkPDFDocument::appendPage(SkPDFDevice* pdfDevice) {
    if (!fPageTree.isEmpty()) {
        return false;
    }

    SkPDFPage* page = new SkPDFPage(pdfDevice);
    fPages.push(page);  // Reference from new passed to fPages.
    return true;
}

// Deprecated.
void SkPDFDocument::getCountOfFontTypes(
        int counts[SkAdvancedTypefaceMetrics::kOther_Font + 2]) const {
    sk_bzero(counts, sizeof(int) *
                     (SkAdvancedTypefaceMetrics::kOther_Font + 2));
    SkTDArray<SkFontID> seenFonts;
    int notEmbeddable = 0;

    for (int pageNumber = 0; pageNumber < fPages.count(); pageNumber++) {
        const SkTDArray<SkPDFFont*>& fontResources =
                fPages[pageNumber]->getFontResources();
        for (int font = 0; font < fontResources.count(); font++) {
            SkFontID fontID = fontResources[font]->typeface()->uniqueID();
            if (seenFonts.find(fontID) == -1) {
                counts[fontResources[font]->getType()]++;
                seenFonts.push(fontID);
                if (!fontResources[font]->canEmbed()) {
                    notEmbeddable++;
                }
            }
        }
    }
    counts[SkAdvancedTypefaceMetrics::kOther_Font + 1] = notEmbeddable;
}

void SkPDFDocument::getCountOfFontTypes(
        int counts[SkAdvancedTypefaceMetrics::kOther_Font + 1],
        int* notSubsettableCount,
        int* notEmbeddableCount) const {
    sk_bzero(counts, sizeof(int) *
                     (SkAdvancedTypefaceMetrics::kOther_Font + 1));
    SkTDArray<SkFontID> seenFonts;
    int notSubsettable = 0;
    int notEmbeddable = 0;

    for (int pageNumber = 0; pageNumber < fPages.count(); pageNumber++) {
        const SkTDArray<SkPDFFont*>& fontResources =
                fPages[pageNumber]->getFontResources();
        for (int font = 0; font < fontResources.count(); font++) {
            SkFontID fontID = fontResources[font]->typeface()->uniqueID();
            if (seenFonts.find(fontID) == -1) {
                counts[fontResources[font]->getType()]++;
                seenFonts.push(fontID);
                if (!fontResources[font]->canSubset()) {
                    notSubsettable++;
                }
                if (!fontResources[font]->canEmbed()) {
                    notEmbeddable++;
                }
            }
        }
    }
    if (notSubsettableCount) {
        *notSubsettableCount = notSubsettable;

    }
    if (notEmbeddableCount) {
        *notEmbeddableCount = notEmbeddable;
    }
}

void SkPDFDocument::emitHeader(SkWStream* stream) {
    stream->writeText("%PDF-1.4\n%");
    // The PDF spec recommends including a comment with four bytes, all
    // with their high bits set.  This is "Skia" with the high bits set.
    stream->write32(0xD3EBE9E1);
    stream->writeText("\n");
}

size_t SkPDFDocument::headerSize() {
    SkDynamicMemoryWStream buffer;
    emitHeader(&buffer);
    return buffer.getOffset();
}

void SkPDFDocument::emitFooter(SkWStream* stream, int64_t objCount) {
    if (NULL == fTrailerDict) {
        fTrailerDict = SkNEW(SkPDFDict);

        // TODO(vandebo): Linearized format will take a Prev entry too.
        // TODO(vandebo): PDF/A requires an ID entry.
        fTrailerDict->insertInt("Size", int(objCount));
        fTrailerDict->insert("Root", new SkPDFObjRef(fDocCatalog))->unref();
    }

    stream->writeText("trailer\n");
    fTrailerDict->emitObject(stream, fCatalog.get());
    stream->writeText("\nstartxref\n");
    stream->writeBigDecAsText(fXRefFileOffset);
    stream->writeText("\n%%EOF");
}
