コード例 #1
0
SkRefPtr<SkPDFArray> SkPDFDevice::getMediaBox() const {
    SkRefPtr<SkPDFInt> zero = new SkPDFInt(0);
    zero->unref();  // SkRefPtr and new both took a reference.

    SkRefPtr<SkPDFArray> mediaBox = new SkPDFArray();
    mediaBox->unref();  // SkRefPtr and new both took a reference.
    mediaBox->reserve(4);
    mediaBox->append(zero.get());
    mediaBox->append(zero.get());
    mediaBox->append(new SkPDFInt(fWidth))->unref();
    mediaBox->append(new SkPDFInt(fHeight))->unref();
    return mediaBox;
}
コード例 #2
0
// static
void SkPDFPage::GeneratePageTree(const SkTDArray<SkPDFPage*>& pages,
                                 SkPDFCatalog* catalog,
                                 SkTDArray<SkPDFDict*>* pageTree,
                                 SkPDFDict** rootNode) {
    // PDF wants a tree describing all the pages in the document.  We arbitrary
    // choose 8 (kNodeSize) as the number of allowed children.  The internal
    // nodes have type "Pages" with an array of children, a parent pointer, and
    // the number of leaves below the node as "Count."  The leaves are passed
    // into the method, have type "Page" and need a parent pointer. This method
    // builds the tree bottom up, skipping internal nodes that would have only
    // one child.
    static const int kNodeSize = 8;

    SkRefPtr<SkPDFName> kidsName = new SkPDFName("Kids");
    kidsName->unref();  // SkRefPtr and new both took a reference.
    SkRefPtr<SkPDFName> countName = new SkPDFName("Count");
    countName->unref();  // SkRefPtr and new both took a reference.
    SkRefPtr<SkPDFName> parentName = new SkPDFName("Parent");
    parentName->unref();  // SkRefPtr and new both took a reference.

    // curNodes takes a reference to its items, which it passes to pageTree.
    SkTDArray<SkPDFDict*> curNodes;
    curNodes.setReserve(pages.count());
    for (int i = 0; i < pages.count(); i++) {
        SkSafeRef(pages[i]);
        curNodes.push(pages[i]);
    }

    // nextRoundNodes passes its references to nodes on to curNodes.
    SkTDArray<SkPDFDict*> nextRoundNodes;
    nextRoundNodes.setReserve((pages.count() + kNodeSize - 1)/kNodeSize);

    int treeCapacity = kNodeSize;
    do {
        for (int i = 0; i < curNodes.count(); ) {
            if (i > 0 && i + 1 == curNodes.count()) {
                nextRoundNodes.push(curNodes[i]);
                break;
            }

            SkPDFDict* newNode = new SkPDFDict("Pages");
            SkRefPtr<SkPDFObjRef> newNodeRef = new SkPDFObjRef(newNode);
            newNodeRef->unref();  // SkRefPtr and new both took a reference.

            SkRefPtr<SkPDFArray> kids = new SkPDFArray;
            kids->unref();  // SkRefPtr and new both took a reference.
            kids->reserve(kNodeSize);

            int count = 0;
            for (; i < curNodes.count() && count < kNodeSize; i++, count++) {
                curNodes[i]->insert(parentName.get(), newNodeRef.get());
                kids->append(new SkPDFObjRef(curNodes[i]))->unref();

                // TODO(vandebo): put the objects in strict access order.
                // Probably doesn't matter because they are so small.
                if (curNodes[i] != pages[0]) {
                    pageTree->push(curNodes[i]);  // Transfer reference.
                    catalog->addObject(curNodes[i], false);
                } else {
                    SkSafeUnref(curNodes[i]);
                    catalog->addObject(curNodes[i], true);
                }
            }

            newNode->insert(kidsName.get(), kids.get());
            int pageCount = treeCapacity;
            if (count < kNodeSize) {
                pageCount = pages.count() % treeCapacity;
            }
            newNode->insert(countName.get(), new SkPDFInt(pageCount))->unref();
            nextRoundNodes.push(newNode);  // Transfer reference.
        }

        curNodes = nextRoundNodes;
        nextRoundNodes.rewind();
        treeCapacity *= kNodeSize;
    } while (curNodes.count() > 1);

    pageTree->push(curNodes[0]);  // Transfer reference.
    catalog->addObject(curNodes[0], false);
    if (rootNode) {
        *rootNode = curNodes[0];
    }
}
コード例 #3
0
static void TestPDFPrimitives(skiatest::Reporter* reporter) {
    SkRefPtr<SkPDFInt> int42 = new SkPDFInt(42);
    int42->unref();  // SkRefPtr and new both took a reference.
    SimpleCheckObjectOutput(reporter, int42.get(), "42");

    SkRefPtr<SkPDFScalar> realHalf = new SkPDFScalar(SK_ScalarHalf);
    realHalf->unref();  // SkRefPtr and new both took a reference.
    SimpleCheckObjectOutput(reporter, realHalf.get(), "0.5");

#if defined(SK_SCALAR_IS_FLOAT)
    SkRefPtr<SkPDFScalar> bigScalar = new SkPDFScalar(110999.75f);
    bigScalar->unref();  // SkRefPtr and new both took a reference.
#if !defined(SK_ALLOW_LARGE_PDF_SCALARS)
    SimpleCheckObjectOutput(reporter, bigScalar.get(), "111000");
#else
    SimpleCheckObjectOutput(reporter, bigScalar.get(), "110999.75");

    SkRefPtr<SkPDFScalar> biggerScalar = new SkPDFScalar(50000000.1);
    biggerScalar->unref();  // SkRefPtr and new both took a reference.
    SimpleCheckObjectOutput(reporter, biggerScalar.get(), "50000000");

    SkRefPtr<SkPDFScalar> smallestScalar = new SkPDFScalar(1.0/65536);
    smallestScalar->unref();  // SkRefPtr and new both took a reference.
    SimpleCheckObjectOutput(reporter, smallestScalar.get(), "0.00001526");
#endif
#endif

    SkRefPtr<SkPDFString> stringSimple = new SkPDFString("test ) string ( foo");
    stringSimple->unref();  // SkRefPtr and new both took a reference.
    SimpleCheckObjectOutput(reporter, stringSimple.get(),
                            "(test \\) string \\( foo)");
    SkRefPtr<SkPDFString> stringComplex =
        new SkPDFString("\ttest ) string ( foo");
    stringComplex->unref();  // SkRefPtr and new both took a reference.
    SimpleCheckObjectOutput(reporter, stringComplex.get(),
                            "<0974657374202920737472696E67202820666F6F>");

    SkRefPtr<SkPDFName> name = new SkPDFName("Test name\twith#tab");
    name->unref();  // SkRefPtr and new both took a reference.
    const char expectedResult[] = "/Test#20name#09with#23tab";
    CheckObjectOutput(reporter, name.get(), expectedResult,
                      strlen(expectedResult), false, false);

    SkRefPtr<SkPDFName> escapedName = new SkPDFName("A#/%()<>[]{}B");
    escapedName->unref();  // SkRefPtr and new both took a reference.
    const char escapedNameExpected[] = "/A#23#2F#25#28#29#3C#3E#5B#5D#7B#7DB";
    CheckObjectOutput(reporter, escapedName.get(), escapedNameExpected,
                      strlen(escapedNameExpected), false, false);

    // Test that we correctly handle characters with the high-bit set.
    const unsigned char highBitCString[] = {0xDE, 0xAD, 'b', 'e', 0xEF, 0};
    SkRefPtr<SkPDFName> highBitName = new SkPDFName((const char*)highBitCString);
    highBitName->unref();  // SkRefPtr and new both took a reference.
    const char highBitExpectedResult[] = "/#DE#ADbe#EF";
    CheckObjectOutput(reporter, highBitName.get(), highBitExpectedResult,
                      strlen(highBitExpectedResult), false, false);

    SkRefPtr<SkPDFArray> array = new SkPDFArray;
    array->unref();  // SkRefPtr and new both took a reference.
    SimpleCheckObjectOutput(reporter, array.get(), "[]");
    array->append(int42.get());
    SimpleCheckObjectOutput(reporter, array.get(), "[42]");
    array->append(realHalf.get());
    SimpleCheckObjectOutput(reporter, array.get(), "[42 0.5]");
    SkRefPtr<SkPDFInt> int0 = new SkPDFInt(0);
    int0->unref();  // SkRefPtr and new both took a reference.
    array->append(int0.get());
    SimpleCheckObjectOutput(reporter, array.get(), "[42 0.5 0]");
    SkRefPtr<SkPDFInt> int1 = new SkPDFInt(1);
    int1->unref();  // SkRefPtr and new both took a reference.
    array->setAt(0, int1.get());
    SimpleCheckObjectOutput(reporter, array.get(), "[1 0.5 0]");

    SkRefPtr<SkPDFDict> dict = new SkPDFDict;
    dict->unref();  // SkRefPtr and new both took a reference.
    SimpleCheckObjectOutput(reporter, dict.get(), "<<>>");
    SkRefPtr<SkPDFName> n1 = new SkPDFName("n1");
    n1->unref();  // SkRefPtr and new both took a reference.
    dict->insert(n1.get(), int42.get());
    SimpleCheckObjectOutput(reporter, dict.get(), "<</n1 42\n>>");
    SkRefPtr<SkPDFName> n2 = new SkPDFName("n2");
    n2->unref();  // SkRefPtr and new both took a reference.
    SkRefPtr<SkPDFName> n3 = new SkPDFName("n3");
    n3->unref();  // SkRefPtr and new both took a reference.
    dict->insert(n2.get(), realHalf.get());
    dict->insert(n3.get(), array.get());
    SimpleCheckObjectOutput(reporter, dict.get(),
                            "<</n1 42\n/n2 0.5\n/n3 [1 0.5 0]\n>>");

    TestPDFStream(reporter);

    TestCatalog(reporter);

    TestObjectRef(reporter);

    TestSubstitute(reporter);
}
コード例 #4
0
const SkRefPtr<SkPDFDict>& SkPDFDevice::getResourceDict() {
    if (fResourceDict.get() == NULL) {
        fResourceDict = new SkPDFDict;
        fResourceDict->unref();  // SkRefPtr and new both took a reference.

        if (fGraphicStateResources.count()) {
            SkRefPtr<SkPDFDict> extGState = new SkPDFDict();
            extGState->unref();  // SkRefPtr and new both took a reference.
            for (int i = 0; i < fGraphicStateResources.count(); i++) {
                SkString nameString("G");
                nameString.appendS32(i);
                extGState->insert(
                    nameString.c_str(),
                    new SkPDFObjRef(fGraphicStateResources[i]))->unref();
            }
            fResourceDict->insert("ExtGState", extGState.get());
        }

        if (fXObjectResources.count()) {
            SkRefPtr<SkPDFDict> xObjects = new SkPDFDict();
            xObjects->unref();  // SkRefPtr and new both took a reference.
            for (int i = 0; i < fXObjectResources.count(); i++) {
                SkString nameString("X");
                nameString.appendS32(i);
                xObjects->insert(
                    nameString.c_str(),
                    new SkPDFObjRef(fXObjectResources[i]))->unref();
            }
            fResourceDict->insert("XObject", xObjects.get());
        }

        if (fFontResources.count()) {
            SkRefPtr<SkPDFDict> fonts = new SkPDFDict();
            fonts->unref();  // SkRefPtr and new both took a reference.
            for (int i = 0; i < fFontResources.count(); i++) {
                SkString nameString("F");
                nameString.appendS32(i);
                fonts->insert(nameString.c_str(),
                              new SkPDFObjRef(fFontResources[i]))->unref();
            }
            fResourceDict->insert("Font", fonts.get());
        }

        if (fShaderResources.count()) {
            SkRefPtr<SkPDFDict> patterns = new SkPDFDict();
            patterns->unref();  // SkRefPtr and new both took a reference.
            for (int i = 0; i < fShaderResources.count(); i++) {
                SkString nameString("P");
                nameString.appendS32(i);
                patterns->insert(nameString.c_str(),
                                 new SkPDFObjRef(fShaderResources[i]))->unref();
            }
            fResourceDict->insert("Pattern", patterns.get());
        }

        // For compatibility, add all proc sets (only used for output to PS
        // devices).
        const char procs[][7] = {"PDF", "Text", "ImageB", "ImageC", "ImageI"};
        SkRefPtr<SkPDFArray> procSets = new SkPDFArray();
        procSets->unref();  // SkRefPtr and new both took a reference.
        procSets->reserve(SK_ARRAY_COUNT(procs));
        for (size_t i = 0; i < SK_ARRAY_COUNT(procs); i++)
            procSets->append(new SkPDFName(procs[i]))->unref();
        fResourceDict->insert("ProcSet", procSets.get());
    }
    return fResourceDict;
}
コード例 #5
0
ファイル: SkPDFImage.cpp プロジェクト: rburchell/skia
SkPDFImage::SkPDFImage(const SkBitmap& bitmap, const SkPaint& paint) {
    SkBitmap::Config config = bitmap.getConfig();

    // TODO(vandebo) Handle alpha and alpha only images correctly.
    SkASSERT(config == SkBitmap::kRGB_565_Config ||
             config == SkBitmap::kARGB_4444_Config ||
             config == SkBitmap::kARGB_8888_Config ||
             config == SkBitmap::kIndex8_Config ||
             config == SkBitmap::kRLE_Index8_Config);

    SkMemoryStream* image_data = extractImageData(bitmap);
    SkAutoUnref image_data_unref(image_data);
    fStream = new SkPDFStream(image_data);
    fStream->unref();  // SkRefPtr and new both took a reference.

    SkRefPtr<SkPDFName> typeValue = new SkPDFName("XObject");
    typeValue->unref();  // SkRefPtr and new both took a reference.
    insert("Type", typeValue.get());

    SkRefPtr<SkPDFName> subTypeValue = new SkPDFName("Image");
    subTypeValue->unref();  // SkRefPtr and new both took a reference.
    insert("Subtype", subTypeValue.get());

    SkRefPtr<SkPDFInt> widthValue = new SkPDFInt(bitmap.width());
    widthValue->unref();  // SkRefPtr and new both took a reference.
    insert("Width", widthValue.get());

    SkRefPtr<SkPDFInt> heightValue = new SkPDFInt(bitmap.height());
    heightValue->unref();  // SkRefPtr and new both took a reference.
    insert("Height", heightValue.get());

    // if (!image mask) {
    SkRefPtr<SkPDFObject> colorSpaceValue;
    if (config == SkBitmap::kIndex8_Config ||
        config == SkBitmap::kRLE_Index8_Config) {
        colorSpaceValue = makeIndexedColorSpace(bitmap.getColorTable());
    } else {
        colorSpaceValue = new SkPDFName("DeviceRGB");
    }
    colorSpaceValue->unref();  // SkRefPtr and new both took a reference.
    insert("ColorSpace", colorSpaceValue.get());
    // }

    int bitsPerComp = bitmap.bytesPerPixel() * 2;
    if (bitsPerComp == 0) {
        SkASSERT(config == SkBitmap::kA1_Config);
        bitsPerComp = 1;
    } else if (bitsPerComp == 2 ||
               (bitsPerComp == 4 && config == SkBitmap::kRGB_565_Config)) {
        bitsPerComp = 8;
    }
    SkRefPtr<SkPDFInt> bitsPerCompValue = new SkPDFInt(bitsPerComp);
    bitsPerCompValue->unref();  // SkRefPtr and new both took a reference.
    insert("BitsPerComponent", bitsPerCompValue.get());

    if (config == SkBitmap::kRGB_565_Config) {
        SkRefPtr<SkPDFInt> zeroVal = new SkPDFInt(0);
        zeroVal->unref();  // SkRefPtr and new both took a reference.
        SkRefPtr<SkPDFScalar> scale5Val = new SkPDFScalar(8.2258);  // 255/2^5-1
        scale5Val->unref();  // SkRefPtr and new both took a reference.
        SkRefPtr<SkPDFScalar> scale6Val = new SkPDFScalar(4.0476);  // 255/2^6-1
        scale6Val->unref();  // SkRefPtr and new both took a reference.
        SkRefPtr<SkPDFArray> decodeValue = new SkPDFArray();
        decodeValue->unref();  // SkRefPtr and new both took a reference.
        decodeValue->reserve(6);
        decodeValue->append(zeroVal.get());
        decodeValue->append(scale5Val.get());
        decodeValue->append(zeroVal.get());
        decodeValue->append(scale6Val.get());
        decodeValue->append(zeroVal.get());
        decodeValue->append(scale5Val.get());
        insert("Decode", decodeValue.get());
    }
}