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

#include "SkPdfRenderer.h"

#include "SkBitmapDevice.h"
#include "SkCanvas.h"
#include "SkDevice.h"
#include "SkForceLinking.h"
#include "SkGraphics.h"
#include "SkImageDecoder.h"
#include "SkImageEncoder.h"
#include "SkOSFile.h"
#include "SkPicture.h"
#include "SkPdfFont.h"
#include "SkPdfGraphicsState.h"
#include "SkPdfHeaders_autogen.h"
#include "SkPdfMapper_autogen.h"
#include "SkPdfNativeTokenizer.h"
#include "SkPdfRenderer.h"
#include "SkPdfReporter.h"
#include "SkPdfTokenLooper.h"
#include "SkPdfUtils.h"
#include "SkStream.h"
#include "SkTypeface.h"
#include "SkTArray.h"
#include "SkTDict.h"

// TODO(edisonn): #ifdef these ones, as they are used only for debugging.
extern "C" SkPdfContext* gPdfContext;

__SK_FORCE_IMAGE_DECODER_LINKING;

// TODO(edisonn): tool, show what objects were read during rendering - will help to identify
//                features with incomplete implementation
// TODO(edisonn): security - validate all the user input, all pdf!
// TODO(edisonn): testability -add option to render without text, or only render text

// Helper macros to load variables from stack, and automatically check their type.
#define EXPECT_OPERANDS(name,pdfContext,n) \
    bool __failed = pdfContext->fObjectStack.count() < n; \
    SkPdfREPORTCODE(const char* __operator_name = name); \
    SkPdfREPORTCODE((void)__operator_name); \
    SkPdfReportIf(pdfContext->fObjectStack.count() < n, \
                  kIgnoreError_SkPdfIssueSeverity, \
                  kStackOverflow_SkPdfIssue, \
                  "Not enought parameters.", NULL, pdfContext); \
    SkDEBUGCODE(int __cnt = n);

#define POP_OBJ(pdfContext,name) \
    SkDEBUGCODE(__cnt--); \
    SkASSERT(__cnt >= 0); \
    SkPdfNativeObject* name = NULL; \
    __failed = __failed || pdfContext->fObjectStack.count() == 0; \
    if (pdfContext->fObjectStack.count() > 0) { \
        name = pdfContext->fObjectStack.top(); \
        pdfContext->fObjectStack.pop(); \
    }

// TODO(edisonn): make all pop function to use name##_obj
#define POP_NUMBER(pdfContext,name) \
    SkDEBUGCODE(__cnt--); \
    SkASSERT(__cnt >= 0); \
    double name = 0; \
    SkPdfNativeObject* name##_obj = NULL; \
    __failed = __failed || pdfContext->fObjectStack.count() == 0; \
    if (pdfContext->fObjectStack.count() > 0) { \
        name##_obj = pdfContext->fObjectStack.top(); \
        pdfContext->fObjectStack.pop(); \
        if (!name##_obj || !name##_obj->isNumber()) { \
            SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, \
                                      __operator_name, \
                                      name##_obj, \
                                      SkPdfNativeObject::_kNumber_PdfObjectType, \
                                      NULL);\
            __failed = true;\
        } else { \
            name = name##_obj->numberValue(); \
        } \
    }

#define POP_INTEGER(pdfContext,name) \
    SkDEBUGCODE(__cnt--); \
    SkASSERT(__cnt >= 0); \
    int64_t name = 0; \
    __failed = __failed || pdfContext->fObjectStack.count() == 0; \
    SkPdfNativeObject* name##_obj = NULL; \
    if (pdfContext->fObjectStack.count() > 0) { \
        name##_obj = pdfContext->fObjectStack.top(); \
        pdfContext->fObjectStack.pop(); \
        if (!name##_obj || !name##_obj->isInteger()) { \
            SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, \
                                      __operator_name, \
                                      name##_obj, \
                                      SkPdfNativeObject::kInteger_PdfObjectType, \
                                      NULL);\
            __failed = true;\
        } else { \
            name = name##_obj->intValue(); \
        } \
    }

#define POP_NUMBER_INTO(pdfContext,var) \
    SkDEBUGCODE(__cnt--); \
    SkASSERT(__cnt >= 0); \
    __failed = __failed || pdfContext->fObjectStack.count() == 0; \
    if (pdfContext->fObjectStack.count() > 0) { \
        SkPdfNativeObject* tmp = pdfContext->fObjectStack.top(); \
        pdfContext->fObjectStack.pop(); \
        if (!tmp || !tmp->isNumber()) { \
            SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, \
                                      __operator_name, \
                                      tmp, \
                                      SkPdfNativeObject::kInteger_PdfObjectType | \
                                          SkPdfNativeObject::kReal_PdfObjectType, \
                                      NULL);\
            __failed = true;\
        } else { \
            var = tmp->numberValue(); \
        } \
    }


#define POP_NAME(pdfContext,name) \
    SkDEBUGCODE(__cnt--); \
    SkASSERT(__cnt >= 0); \
    SkPdfNativeObject* name = NULL; \
    __failed = __failed || pdfContext->fObjectStack.count() == 0; \
    if (pdfContext->fObjectStack.count() > 0) { \
        SkPdfNativeObject* tmp = pdfContext->fObjectStack.top(); \
        pdfContext->fObjectStack.pop(); \
        if (!tmp || !tmp->isName()) { \
            SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, \
                                      __operator_name, \
                                      tmp, \
                                      SkPdfNativeObject::kName_PdfObjectType, \
                                      NULL);\
            __failed = true;\
        } else { \
            name = tmp; \
        } \
    }

#define POP_STRING(pdfContext,name) \
    SkDEBUGCODE(__cnt--); \
    SkASSERT(__cnt >= 0); \
    SkPdfNativeObject* name = NULL; \
    __failed = __failed || pdfContext->fObjectStack.count() == 0; \
    if (pdfContext->fObjectStack.count() > 0) { \
        SkPdfNativeObject* tmp = pdfContext->fObjectStack.top(); \
        pdfContext->fObjectStack.pop(); \
        if (!tmp || !tmp->isAnyString()) { \
            SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, \
                                      __operator_name, \
                                      tmp, \
                                      SkPdfNativeObject::kString_PdfObjectType | \
                                          SkPdfNativeObject::kHexString_PdfObjectType, \
                                      NULL);\
            __failed = true;\
        } else { \
            name = tmp; \
        } \
    }

#define POP_ARRAY(pdfContext,name) \
    SkDEBUGCODE(__cnt--); \
    SkASSERT(__cnt >= 0); \
    SkPdfArray* name = NULL; \
    __failed = __failed || pdfContext->fObjectStack.count() == 0; \
    if (pdfContext->fObjectStack.count() > 0) { \
        SkPdfNativeObject* tmp = pdfContext->fObjectStack.top(); \
        pdfContext->fObjectStack.pop(); \
        if (!tmp || !tmp->isArray()) { \
            SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, \
                                      __operator_name, \
                                      tmp, \
                                      SkPdfNativeObject::kArray_PdfObjectType, \
                                      NULL);\
            __failed = true;\
        } else { \
            name = (SkPdfArray*)tmp; \
        } \
    }

#define CHECK_PARAMETERS() \
    SkASSERT(__cnt == 0); \
    if (__failed) return kIgnoreError_SkPdfResult;


NotOwnedString strings_DeviceRGB;
NotOwnedString strings_DeviceCMYK;

class StringsInit {
public:
    StringsInit() {
        NotOwnedString::init(&strings_DeviceRGB, "DeviceRGB");
        NotOwnedString::init(&strings_DeviceCMYK, "DeviceCMYK");
    }
};

// TODO(edisonn): this will not work in chrome! Find another solution!
StringsInit gStringsInit;

// TODO(edisonn): Document SkPdfTokenLooper and subclasses.
class PdfInlineImageLooper : public SkPdfTokenLooper {
public:
    explicit PdfInlineImageLooper(SkPdfTokenLooper* parent)
        : INHERITED(parent) {}

    virtual SkPdfResult consumeToken(PdfToken& token) SK_OVERRIDE;
    virtual void loop() SK_OVERRIDE;

private:
    typedef SkPdfTokenLooper INHERITED;
};

class PdfCompatibilitySectionLooper : public SkPdfTokenLooper {
public:
    explicit PdfCompatibilitySectionLooper(SkPdfTokenLooper* parent)
        : INHERITED (parent) {}

    virtual SkPdfResult consumeToken(PdfToken& token) SK_OVERRIDE;
    virtual void loop() SK_OVERRIDE;

private:
    typedef SkPdfTokenLooper INHERITED;
};

// Utilities
static void setup_bitmap(SkBitmap* bitmap, int width, int height, SkColor color = SK_ColorWHITE) {
    bitmap->allocN32Pixels(width, height);
    bitmap->eraseColor(color);
}

// TODO(edisonn): synonyms? /DeviceRGB and /RGB mean the same thing. Context dependent.
static int GetColorSpaceComponents(NotOwnedString& colorSpace) {
    if (colorSpace.equals("DeviceCMYK")) {
        return 4;
    } else if (colorSpace.equals("DeviceGray") ||
            colorSpace.equals("CalGray") ||
            colorSpace.equals("Indexed")) {
        return 1;
    } else if (colorSpace.equals("DeviceRGB") ||
            colorSpace.equals("CalRGB") ||
            colorSpace.equals("Lab")) {
        return 3;
    } else {
        return 0;
    }
}

SkMatrix SkMatrixFromPdfMatrix(double array[6]) {
    SkMatrix matrix;
    matrix.setAll(SkDoubleToScalar(array[0]),
                  SkDoubleToScalar(array[2]),
                  SkDoubleToScalar(array[4]),
                  SkDoubleToScalar(array[1]),
                  SkDoubleToScalar(array[3]),
                  SkDoubleToScalar(array[5]),
                  SkDoubleToScalar(0),
                  SkDoubleToScalar(0),
                  SkDoubleToScalar(1));

    return matrix;
}

SkMatrix SkMatrixFromPdfArray(SkPdfArray* pdfArray) {
    double array[6];

    // TODO(edisonn): security issue, ret if size() != 6
    if (pdfArray == NULL) {
        SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kNullObject_SkPdfIssue,
                    "null array passed to build matrix", NULL, NULL);
        return SkMatrix::I();
    }

    if (pdfArray->size() != 6) {
        SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kUnexpectedArraySize_SkPdfIssue,
                    "null array passed to build matrix", pdfArray, NULL);
        return SkMatrix::I();
    }

    for (int i = 0; i < 6; i++) {
        const SkPdfNativeObject* elem = pdfArray->operator [](i);
        if (elem == NULL || !elem->isNumber()) {
            SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, elem,
                                      SkPdfNativeObject::_kNumber_PdfObjectType, NULL);
            return SkMatrix::I();
        }
        array[i] = elem->numberValue();
    }

    return SkMatrixFromPdfMatrix(array);
}

// TODO(edisonn): debug code, used to analyze rendering when we find bugs.
extern "C" SkPdfNativeDoc* gDoc;

static SkPdfResult DrawText(SkPdfContext* pdfContext,
                   const SkPdfNativeObject* _str,
                   SkCanvas* canvas)
{
    SkPdfFont* skfont = pdfContext->fGraphicsState.fSkFont;
    if (skfont == NULL) {
        skfont = SkPdfFont::Default();
    }

    if (_str == NULL || !_str->isAnyString()) {
        SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity,
                                  "DrawText",
                                  _str,
                                  SkPdfNativeObject::_kAnyString_PdfObjectType,
                                  pdfContext);
        return kIgnoreError_SkPdfResult;
    }
    const SkPdfString* str = (const SkPdfString*)_str;

    SkUnencodedText binary(str);

    SkDecodedText decoded;

    if (skfont->encoding() == NULL) {
        SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kMissingEncoding_SkPdfIssue,
                    "draw text", _str, pdfContext);
        return kNYI_SkPdfResult;
    }

    skfont->encoding()->decodeText(binary, &decoded);

    SkPaint paint;
    // TODO(edisonn): does size 0 mean anything special?
    if (pdfContext->fGraphicsState.fCurFontSize != 0) {
        paint.setTextSize(SkDoubleToScalar(pdfContext->fGraphicsState.fCurFontSize));
    }

    // TODO(edisonn): implement font scaler
//    if (fCurFont && fCurFont->GetFontScale() != 0) {
//        paint.setTextScaleX(fCurFont->GetFontScale() / 100.0);
//    }

    pdfContext->fGraphicsState.applyGraphicsState(&paint, false);

    skfont->drawText(decoded, &paint, pdfContext, canvas);

    return kOK_SkPdfResult;
}

// TODO(edisonn): create header files with declarations!
SkPdfResult PdfOp_q(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper* parentLooper);
SkPdfResult PdfOp_Q(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper* parentLooper);
SkPdfResult PdfOp_Tw(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper* parentLooper);
SkPdfResult PdfOp_Tc(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper* parentLooper);

// TODO(edisonn): perf!!!
static SkColorTable* getGrayColortable() {
    static SkColorTable* grayColortable = NULL;
    if (grayColortable == NULL) {
        SkPMColor* colors = new SkPMColor[256];
        for (int i = 0 ; i < 256; i++) {
            colors[i] = SkPreMultiplyARGB(255, i, i, i);
        }
        grayColortable = new SkColorTable(colors, 256);
    }
    return grayColortable;
}

static SkBitmap* transferImageStreamToBitmap(const unsigned char* uncompressedStream,
                                             size_t uncompressedStreamLength,
                                             int width, int height, int bytesPerLine,
                                             int bpc, const SkString& colorSpace,
                                             bool transparencyMask) {
    SkBitmap* bitmap = new SkBitmap();

    //int components = GetColorSpaceComponents(colorSpace);
//#define MAX_COMPONENTS 10

    // TODO(edisonn): assume start of lines are aligned at 32 bits?
    // Is there a faster way to load the uncompressed stream into a bitmap?

    // minimal support for now
    if ((colorSpace.equals("DeviceRGB") || colorSpace.equals("RGB")) && bpc == 8) {
        SkColor* uncompressedStreamArgb = (SkColor*)malloc(width * height * sizeof(SkColor));

        for (int h = 0 ; h < height; h++) {
            long i = width * (h);
            for (int w = 0 ; w < width; w++) {
                uncompressedStreamArgb[i] = SkColorSetRGB(uncompressedStream[3 * w],
                                                          uncompressedStream[3 * w + 1],
                                                          uncompressedStream[3 * w + 2]);
                i++;
            }
            uncompressedStream += bytesPerLine;
        }

        const SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
        bitmap->installPixels(info, uncompressedStreamArgb, info.minRowBytes());
    }
    else if ((colorSpace.equals("DeviceGray") || colorSpace.equals("Gray")) && bpc == 8) {
        unsigned char* uncompressedStreamA8 = (unsigned char*)malloc(width * height);

        for (int h = 0 ; h < height; h++) {
            long i = width * (h);
            for (int w = 0 ; w < width; w++) {
                uncompressedStreamA8[i] = transparencyMask ? 255 - uncompressedStream[w] :
                                                             uncompressedStream[w];
                i++;
            }
            uncompressedStream += bytesPerLine;
        }

        const SkColorType ct = transparencyMask ? kAlpha_8_SkColorType : kIndex_8_SkColorType;
        const SkImageInfo info = SkImageInfo::Make(width, height, ct, kPremul_SkAlphaType);
        bitmap->installPixels(info, uncompressedStreamA8, info.minRowBytes(),
                              transparencyMask ? NULL : getGrayColortable(), NULL, NULL);
    }

    // TODO(edisonn): pass color space and context here?
    SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, "Color space NYI", NULL, NULL);
    return bitmap;
}
// TODO(edisonn): preserve A1 format that skia knows, + fast convert from 111, 222, 444 to closest
// skia format.

// This functions returns the image, it does not look at the smask.
static SkBitmap* getImageFromObjectCore(SkPdfContext* pdfContext,
                                        SkPdfImageDictionary* image, bool transparencyMask) {
    if (image == NULL || !image->hasStream()) {
        SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, "Missing stream", image,
                                  SkPdfNativeObject::_kStream_PdfObjectType, pdfContext);
        return NULL;
    }

    int bpc = (int)image->BitsPerComponent(pdfContext->fPdfDoc);
    int width = (int)image->Width(pdfContext->fPdfDoc);
    int height = (int)image->Height(pdfContext->fPdfDoc);
    SkString colorSpace("DeviceRGB");

    bool indexed = false;
    SkPMColor colors[256];
    int cnt = 0;

    if (image->isColorSpaceAName(pdfContext->fPdfDoc)) {
        colorSpace = image->getColorSpaceAsName(pdfContext->fPdfDoc);
    } else if (image->isColorSpaceAArray(pdfContext->fPdfDoc)) {
        SkPdfArray* array = image->getColorSpaceAsArray(pdfContext->fPdfDoc);
        if (array && array->size() == 4 && array->objAtAIndex(0)->isName("Indexed") &&
                                           (array->objAtAIndex(1)->isName("DeviceRGB") ||
                                                   array->objAtAIndex(1)->isName("RGB")) &&
                                           array->objAtAIndex(2)->isInteger() &&
                                           array->objAtAIndex(3)->isHexString()
                                           ) {
            SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, "Color space NYI",
                        image, pdfContext);
            indexed = true;
            cnt = (int)array->objAtAIndex(2)->intValue() + 1;
            if (cnt > 256) {
                SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue,
                            "Color space feature NYI, cnt > 256", image, pdfContext);
                return NULL;
            }
            NotOwnedString data = array->objAtAIndex(3)->strRef();
            if (data.fBytes != (unsigned int)cnt * 3) {
                SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kIncostistentSizes_SkPdfIssue,
                            "Image color table mismatch color space specs", array, pdfContext);
                return NULL;
            }
            for (int i = 0 ; i < cnt; i++) {
                colors[i] = SkPreMultiplyARGB(0xff,
                                              data.fBuffer[3 * i],
                                              data.fBuffer[3 * i + 1],
                                              data.fBuffer[3 * i + 2]);
            }
        }
    }

    //  TODO(edisonn): implement image masks.
/*  bool imageMask = image->imageMask();
    if (imageMask) {
        if (bpc != 0 && bpc != 1) {
            // TODO(edisonn): report warning to be used in testing.
            return SkBitmap();
        }
        bpc = 1;
    }
*/

    const unsigned char* uncompressedStream = NULL;
    size_t uncompressedStreamLength = 0;

    SkPdfStream* stream = (SkPdfStream*)image;

    if (!stream || !stream->GetFilteredStreamRef(&uncompressedStream, &uncompressedStreamLength) ||
            uncompressedStream == NULL || uncompressedStreamLength == 0) {
        SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, "Missing stream", stream,
                                  SkPdfNativeObject::_kStream_PdfObjectType, pdfContext);
        return NULL;
    }

    SkPdfStreamCommonDictionary* streamDict = (SkPdfStreamCommonDictionary*)stream;

    if (streamDict->has_Filter() &&
            ((streamDict->isFilterAName(NULL) &&
                  streamDict->getFilterAsName(NULL).equals("DCTDecode")) ||
             (streamDict->isFilterAArray(NULL) &&
                  streamDict->getFilterAsArray(NULL)->size() > 0 &&
                  streamDict->getFilterAsArray(NULL)->objAtAIndex(0)->isName() &&
                  streamDict->getFilterAsArray(NULL)->objAtAIndex(0)->nameValue2()
                                                                    .equals("DCTDecode")))) {
        SkBitmap* bitmap = new SkBitmap();
        SkImageDecoder::DecodeMemory(uncompressedStream, uncompressedStreamLength, bitmap);
        return bitmap;
    }

    // TODO(edisonn): assumes RGB for now, since it is the only one implemented
    if (indexed) {
        SkBitmap* bitmap = new SkBitmap();
        const SkImageInfo info = SkImageInfo::Make(width, height, kIndex_8_SkColorType,
                                                   kPremul_SkAlphaType);
        SkAutoTUnref<SkColorTable> colorTable(new SkColorTable(colors, cnt));
        bitmap->installPixels(info, (void*)uncompressedStream, info.minRowBytes(), colorTable,
                              NULL, NULL);
        return bitmap;
    }

    int bytesPerLine = (int)(uncompressedStreamLength / height);
#ifdef PDF_TRACE
    if (uncompressedStreamLength % height != 0) {
        printf("Warning uncompressedStreamLength modulo height != 0 !!!\n");
    }
#endif

    SkBitmap* bitmap = transferImageStreamToBitmap(
            (unsigned char*)uncompressedStream, uncompressedStreamLength,
            (int)width, (int)height, bytesPerLine,
            (int)bpc, colorSpace,
            transparencyMask);

    return bitmap;
}

static SkBitmap* getImageFromObject(SkPdfContext* pdfContext, SkPdfImageDictionary* image,
                                    bool transparencyMask) {
    if (!transparencyMask) {
        if (!image->hasData(SkPdfNativeObject::kBitmap_Data)) {
            SkBitmap* bitmap = getImageFromObjectCore(pdfContext, image, transparencyMask);
            image->setData(bitmap, SkPdfNativeObject::kBitmap_Data);
        }
        return (SkBitmap*) image->data(SkPdfNativeObject::kBitmap_Data);
    } else {
        return getImageFromObjectCore(pdfContext, image, transparencyMask);
    }
}

static SkBitmap* getSmaskFromObject(SkPdfContext* pdfContext, SkPdfImageDictionary* obj) {
    SkPdfImageDictionary* sMask = obj->SMask(pdfContext->fPdfDoc);

    if (sMask) {
        return getImageFromObject(pdfContext, sMask, true);
    }

    // TODO(edisonn): implement GS SMask. Default to empty right now.
    SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue,
                "implement GS SMask. Default to empty right now.", obj, pdfContext);

    return pdfContext->fGraphicsState.fSMask;
}

static SkPdfResult doXObject_Image(SkPdfContext* pdfContext, SkCanvas* canvas,
                                   SkPdfImageDictionary* skpdfimage) {
    if (skpdfimage == NULL) {
        return kIgnoreError_SkPdfResult;
    }

    SkBitmap* image = getImageFromObject(pdfContext, skpdfimage, false);
    SkBitmap* sMask = getSmaskFromObject(pdfContext, skpdfimage);

    canvas->save();
    canvas->setMatrix(pdfContext->fGraphicsState.fCTM);

    SkScalar z = SkIntToScalar(0);
    SkScalar one = SkIntToScalar(1);

    SkPoint from[4] = {SkPoint::Make(z, z), SkPoint::Make(one, z),
                       SkPoint::Make(one, one), SkPoint::Make(z, one)};
    SkPoint to[4] = {SkPoint::Make(z, one), SkPoint::Make(one, one),
                     SkPoint::Make(one, z), SkPoint::Make(z, z)};
    SkMatrix flip;
    SkAssertResult(flip.setPolyToPoly(from, to, 4));
    SkMatrix solveImageFlip = pdfContext->fGraphicsState.fCTM;
    solveImageFlip.preConcat(flip);
    canvas->setMatrix(solveImageFlip);

#ifdef PDF_TRACE
    SkPoint final[4] = {SkPoint::Make(z, z), SkPoint::Make(one, z),
                        SkPoint::Make(one, one), SkPoint::Make(z, one)};
    solveImageFlip.mapPoints(final, 4);
    printf("IMAGE rect = ");
    for (int i = 0; i < 4; i++) {
        printf("(%f %f) ", SkScalarToDouble(final[i].x()), SkScalarToDouble(final[i].y()));
    }
    printf("\n");
#endif  // PDF_TRACE

    SkRect dst = SkRect::MakeXYWH(SkDoubleToScalar(0.0), SkDoubleToScalar(0.0),
                                  SkDoubleToScalar(1.0), SkDoubleToScalar(1.0));

    // TODO(edisonn): soft mask type? alpha/luminosity.
    SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue,
                "implement soft mask type", skpdfimage, pdfContext);

    SkPaint paint;
    pdfContext->fGraphicsState.applyGraphicsState(&paint, false);

    if (!sMask || sMask->empty()) {
        canvas->drawBitmapRect(*image, dst, &paint);
    } else {
        canvas->saveLayer(&dst, &paint);
        canvas->drawBitmapRect(*image, dst, NULL);
        SkPaint xfer;
        xfer.setXfermodeMode(SkXfermode::kSrcOut_Mode);
        canvas->drawBitmapRect(*sMask, dst, &xfer);
        canvas->restore();
    }

    canvas->restore();

    return kPartial_SkPdfResult;
}

//TODO(edisonn): options for implementing isolation and knockout
// 1) emulate them (current solution)
//     PRO: simple
//     CON: will need to use readPixels, which means serious perf issues
// 2) Compile a plan for an array of matrixes, compose the result at the end
//     PRO: might be faster then 1, no need to readPixels
//     CON: multiple drawings (but on smaller areas), pay a price at loading pdf to
//          compute a pdf draw plan
//          on average, a load with empty draw is 100ms on all the skps we have, for complete sites
// 3) support them natively in SkCanvas
//     PRO: simple
//     CON: we would still need to use a form of readPixels anyway, so perf might be the same as 1)
// 4) compile a plan using pathops, and render once without any fancy rules with backdrop
//     PRO: simple, fast
//     CON: pathops must be bug free first + time to compute new paths
//          pay a price at loading pdf to compute a pdf draw plan
//          on average, a load with empty draw is 100ms on all the skps we have, for complete sites
// 5) for knockout, render the objects in reverse order, and add every object to the clip, and any
//          new draw will be cliped

static void doGroup_before(SkPdfContext* pdfContext, SkCanvas* canvas, SkRect bbox,
                           SkPdfTransparencyGroupDictionary* tgroup, bool page) {
    SkRect bboxOrig = bbox;
    SkBitmap backdrop;
    bool isolatedGroup = tgroup->I(pdfContext->fPdfDoc);
//  bool knockoutGroup = tgroup->K(pdfContext->fPdfDoc);
    SkPaint paint;
    pdfContext->fGraphicsState.applyGraphicsState(&paint, false);
    canvas->saveLayer(&bboxOrig, isolatedGroup ? &paint : NULL);
}

// TODO(edisonn): non isolation should probably be implemented in skia
//static void doGroup_after(SkPdfContext* pdfContext, SkCanvas* canvas, SkRect bbox,
//                          SkPdfTransparencyGroupDictionary* tgroup) {
//    if not isolated
//        canvas->drawBitmapRect(backdrop, bboxOrig, NULL);
//}

static SkPdfResult doXObject_Form(SkPdfContext* pdfContext, SkCanvas* canvas,
                                  SkPdfType1FormDictionary* skobj) {
    if (!skobj || !skobj->hasStream()) {
        SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, "Missing stream", skobj,
                                  SkPdfNativeObject::_kStream_PdfObjectType, pdfContext);
        return kIgnoreError_SkPdfResult;
    }

    if (!skobj->has_BBox()) {
        SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kMissingRequiredKey_SkPdfIssue, "BBox",
                    skobj, pdfContext);
        return kIgnoreError_SkPdfResult;
    }

    PdfOp_q(pdfContext, canvas, NULL);


    if (skobj->Resources(pdfContext->fPdfDoc)) {
        pdfContext->fGraphicsState.fResources = skobj->Resources(pdfContext->fPdfDoc);
    }

    SkTraceMatrix(pdfContext->fGraphicsState.fCTM, "Current matrix");

    if (skobj->has_Matrix()) {
        pdfContext->fGraphicsState.fCTM.preConcat(skobj->Matrix(pdfContext->fPdfDoc));
        SkMatrix matrix = pdfContext->fGraphicsState.fCTM;
        matrix.preScale(SkDoubleToScalar(1), SkDoubleToScalar(-1));
        pdfContext->fGraphicsState.fMatrixTm = matrix;
        pdfContext->fGraphicsState.fMatrixTlm = matrix;
        // TODO(edisonn): text matrixes mosltly NYI
    }

    SkTraceMatrix(pdfContext->fGraphicsState.fCTM, "Total matrix");
    pdfContext->fGraphicsState.fContentStreamMatrix = pdfContext->fGraphicsState.fCTM;

    canvas->setMatrix(pdfContext->fGraphicsState.fCTM);

    SkRect bbox = skobj->BBox(pdfContext->fPdfDoc);
    // TODO(edisonn): constants (AA) from settings.
    canvas->clipRect(bbox, SkRegion::kIntersect_Op, false);

    // This is a group?
    if (skobj->has_Group()) {
        SkPdfTransparencyGroupDictionary* tgroup = skobj->Group(pdfContext->fPdfDoc);
        doGroup_before(pdfContext, canvas, bbox, tgroup, false);
    }

    SkPdfStream* stream = (SkPdfStream*)skobj;

    pdfContext->parseStream(stream, canvas);

    if (skobj->has_Group()) {
        canvas->restore();
    }

    PdfOp_Q(pdfContext, canvas, NULL);
    return kPartial_SkPdfResult;
}

static SkPdfResult doXObject_Pattern(SkPdfContext* pdfContext, SkCanvas* canvas,
                                     SkPdfType1PatternDictionary* skobj) {
    if (!skobj || !skobj->hasStream()) {
        SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, "Missing stream",
                                  skobj, SkPdfNativeObject::_kStream_PdfObjectType, pdfContext);
        return kIgnoreError_SkPdfResult;
    }

    if (!skobj->has_BBox()) {
        SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kMissingRequiredKey_SkPdfIssue, "BBox",
                    skobj, pdfContext);
        return kIgnoreError_SkPdfResult;
    }

    PdfOp_q(pdfContext, canvas, NULL);


    if (skobj->Resources(pdfContext->fPdfDoc)) {
        pdfContext->fGraphicsState.fResources = skobj->Resources(pdfContext->fPdfDoc);
    }

    SkTraceMatrix(pdfContext->fGraphicsState.fContentStreamMatrix, "Current Content stream matrix");

    if (skobj->has_Matrix()) {
        pdfContext->fGraphicsState.fContentStreamMatrix.preConcat(
                skobj->Matrix(pdfContext->fPdfDoc));
    }

    SkTraceMatrix(pdfContext->fGraphicsState.fContentStreamMatrix, "Total Content stream matrix");

    canvas->setMatrix(pdfContext->fGraphicsState.fContentStreamMatrix);
    pdfContext->fGraphicsState.fCTM = pdfContext->fGraphicsState.fContentStreamMatrix;

    SkRect bbox = skobj->BBox(pdfContext->fPdfDoc);
    // TODO(edisonn): constants (AA) from settings.
    canvas->clipRect(bbox, SkRegion::kIntersect_Op, false);

    SkPdfStream* stream = (SkPdfStream*)skobj;

    pdfContext->parseStream(stream, canvas);

    PdfOp_Q(pdfContext, canvas, NULL);
    return kPartial_SkPdfResult;
}

// TODO(edisonn): PS NYI
//static SkPdfResult doXObject_PS(SkPdfContext* pdfContext, SkCanvas* canvas,
//                                const SkPdfNativeObject* obj) {
//    return kNYI_SkPdfResult;
//}

SkPdfResult doType3Char(SkPdfContext* pdfContext, SkCanvas* canvas, const SkPdfNativeObject* skobj,
                        SkRect bBox, SkMatrix matrix, double textSize) {
    if (!skobj || !skobj->hasStream()) {
        SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, "Missing stream", skobj,
                                  SkPdfNativeObject::_kStream_PdfObjectType, pdfContext);
        return kIgnoreError_SkPdfResult;
    }

    PdfOp_q(pdfContext, canvas, NULL);

    pdfContext->fGraphicsState.fMatrixTm.preConcat(matrix);
    pdfContext->fGraphicsState.fMatrixTm.preScale(SkDoubleToScalar(textSize),
                                                  SkDoubleToScalar(textSize));
    pdfContext->fGraphicsState.fMatrixTlm = pdfContext->fGraphicsState.fMatrixTm;

    pdfContext->fGraphicsState.fCTM = pdfContext->fGraphicsState.fMatrixTm;
    pdfContext->fGraphicsState.fCTM.preScale(SkDoubleToScalar(1), SkDoubleToScalar(-1));

    SkTraceMatrix(pdfContext->fGraphicsState.fCTM, "Total matrix");

    canvas->setMatrix(pdfContext->fGraphicsState.fCTM);

    SkRect rm = bBox;
    pdfContext->fGraphicsState.fCTM.mapRect(&rm);

    SkTraceRect(rm, "bbox mapped");

    // TODO(edisonn): constants (AA) from settings.
    canvas->clipRect(bBox, SkRegion::kIntersect_Op, false);

    SkPdfStream* stream = (SkPdfStream*)skobj;

    pdfContext->parseStream(stream, canvas);

    PdfOp_Q(pdfContext, canvas, NULL);

    return kPartial_SkPdfResult;
}

// The PDF could be corrupted so a dict refers recursively to the same dict, if this happens
// we end up with a stack overflow and crash.
class CheckRecursiveRendering {
    SkPdfNativeObject* fObj;
public:
    CheckRecursiveRendering(SkPdfNativeObject* obj) : fObj(obj) {
        SkASSERT(!obj->inRendering());
        obj->startRendering();
    }

    ~CheckRecursiveRendering() {
        SkASSERT(fObj->inRendering());
        fObj->doneRendering();
    }

    static bool IsInRendering(const SkPdfNativeObject* obj) {
        return obj->inRendering();
    }
};

static SkPdfResult doXObject(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfNativeObject* obj) {
    if (CheckRecursiveRendering::IsInRendering(obj)) {
        SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kRecursiveReferencing_SkPdfIssue,
                    "Recursive reverencing is invalid in draw objects", obj, pdfContext);
        return kIgnoreError_SkPdfResult;
    }

    CheckRecursiveRendering checkRecursion(obj);

    switch (pdfContext->fPdfDoc->mapper()->mapXObjectDictionary(obj))
    {
        case kImageDictionary_SkPdfNativeObjectType:
            return doXObject_Image(pdfContext, canvas, (SkPdfImageDictionary*)obj);
        case kType1FormDictionary_SkPdfNativeObjectType:
            return doXObject_Form(pdfContext, canvas, (SkPdfType1FormDictionary*)obj);
        //case kObjectDictionaryXObjectPS_SkPdfNativeObjectType:
            //return doXObject_PS(skxobj.asPS());
        default: {
            if (pdfContext->fPdfDoc->mapper()->mapType1PatternDictionary(obj) !=
                    kNone_SkPdfNativeObjectType) {
                SkPdfType1PatternDictionary* pattern = (SkPdfType1PatternDictionary*)obj;
                return doXObject_Pattern(pdfContext, canvas, pattern);
            }
            SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, "doXObject",
                        obj, pdfContext);
        }
    }
    return kIgnoreError_SkPdfResult;
}

static SkPdfResult doPage(SkPdfContext* pdfContext, SkCanvas* canvas,
                          SkPdfPageObjectDictionary* skobj) {
    if (!skobj || !skobj->isContentsAStream(pdfContext->fPdfDoc)) {
        SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, "Missing stream", skobj,
                                  SkPdfNativeObject::_kStream_PdfObjectType, pdfContext);
        return kNYI_SkPdfResult;
    }

    SkPdfStream* stream = skobj->getContentsAsStream(pdfContext->fPdfDoc);

    if (!stream) {
        SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, "Missing stream",
                                  skobj, SkPdfNativeObject::_kStream_PdfObjectType, pdfContext);
        return kIgnoreError_SkPdfResult;
    }

    // FIXME (scroggo): renderPage also sets fResources. Are these redundant?
    pdfContext->fGraphicsState.fResources = skobj->Resources(pdfContext->fPdfDoc);

    if (!pdfContext->fGraphicsState.fResources) {
        // It might be null because we have not implemented yet inheritance.
        return kIgnoreError_SkPdfResult;
    }

    if (CheckRecursiveRendering::IsInRendering(skobj)) {
        SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kRecursiveReferencing_SkPdfIssue,
                    "Recursive reverencing is invalid in draw objects", skobj, pdfContext);
        return kIgnoreError_SkPdfResult;
    }
    CheckRecursiveRendering checkRecursion(skobj);


    // FIXME (scroggo): Is this save necessary? May be needed for rendering a nested PDF.
    PdfOp_q(pdfContext, canvas, NULL);

    // TODO(edisonn): MediaBox can be inherited!!!!
    SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, "MediaBox inheritance NYI",
                NULL, pdfContext);
    SkRect bbox = skobj->MediaBox(pdfContext->fPdfDoc);
    if (skobj->has_Group()) {
        SkPdfTransparencyGroupDictionary* tgroup = skobj->Group(pdfContext->fPdfDoc);
        doGroup_before(pdfContext, canvas, bbox, tgroup, true);
    } else {
        canvas->save();
    }

    pdfContext->parseStream(stream, canvas);

    canvas->restore();
    PdfOp_Q(pdfContext, canvas, NULL);
    return kPartial_SkPdfResult;
}

SkPdfResult PdfOp_q(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    pdfContext->fStateStack.push(pdfContext->fGraphicsState);
    canvas->save();
    pdfContext->fObjectStack.nest();
    return kOK_SkPdfResult;
}

SkPdfResult PdfOp_Q(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    if (pdfContext->fStateStack.count() > 0) {
        pdfContext->fGraphicsState = pdfContext->fStateStack.top();
        pdfContext->fStateStack.pop();
        canvas->restore();

        if (pdfContext->fObjectStack.nestingLevel() == 0) {
            SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kStackNestingOverflow_SkPdfIssue,
                        "stack nesting overflow (q/Q)", NULL, pdfContext);
            return kIgnoreError_SkPdfResult;
        } else {
            pdfContext->fObjectStack.unnest();
        }
    } else {
        SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kStackOverflow_SkPdfIssue,
                    "stack overflow (q/Q)", NULL, pdfContext);
        return kIgnoreError_SkPdfResult;
    }

    return kOK_SkPdfResult;
}

static SkPdfResult PdfOp_cm(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    EXPECT_OPERANDS("cm", pdfContext, 6);
    POP_NUMBER(pdfContext, f);
    POP_NUMBER(pdfContext, e);
    POP_NUMBER(pdfContext, d);
    POP_NUMBER(pdfContext, c);
    POP_NUMBER(pdfContext, b);
    POP_NUMBER(pdfContext, a);
    CHECK_PARAMETERS();
    double array[6] = {a, b, c, d, e, f};

    // a b
    // c d
    // e f

    // 0 1
    // 2 3
    // 4 5

    // sx ky
    // kx sy
    // tx ty
    SkMatrix matrix = SkMatrixFromPdfMatrix(array);

    pdfContext->fGraphicsState.fCTM.preConcat(matrix);

#ifdef PDF_TRACE
    printf("cm ");
    for (int i = 0 ; i < 6 ; i++) {
        printf("%f ", array[i]);
    }
    printf("\n");
    SkTraceMatrix(pdfContext->fGraphicsState.fCTM, "cm");
#endif

    return kOK_SkPdfResult;
}

//leading TL Set the text leading, Tl
//, to leading, which is a number expressed in unscaled text
//space units. Text leading is used only by the T*, ', and " operators. Initial value: 0.
static SkPdfResult PdfOp_TL(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    EXPECT_OPERANDS("TL", pdfContext, 1);
    POP_NUMBER(pdfContext, ty);
    CHECK_PARAMETERS();

    pdfContext->fGraphicsState.fTextLeading = ty;

    return kOK_SkPdfResult;
}

static SkPdfResult PdfOp_Td(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    EXPECT_OPERANDS("Td", pdfContext, 2);
    POP_NUMBER(pdfContext, ty);
    POP_NUMBER(pdfContext, tx);
    CHECK_PARAMETERS();

    double array[6] = {1, 0, 0, 1, tx, -ty};
    SkMatrix matrix = SkMatrixFromPdfMatrix(array);

    pdfContext->fGraphicsState.fMatrixTm.preConcat(matrix);
    pdfContext->fGraphicsState.fMatrixTlm.preConcat(matrix);

    return kPartial_SkPdfResult;
}

static SkPdfResult PdfOp_TD(SkPdfContext* pdfContext, SkCanvas* canvas,
                            SkPdfTokenLooper* parentLooper) {
    EXPECT_OPERANDS("TD", pdfContext, 2)
    POP_NUMBER(pdfContext, ty);
    POP_NUMBER(pdfContext, tx);
    CHECK_PARAMETERS();

    // TODO(edisonn): Create factory methods or constructors so native is hidden
    SkPdfReal* _ty = pdfContext->fPdfDoc->createReal(-ty);
    pdfContext->fObjectStack.push(_ty);

    PdfOp_TL(pdfContext, canvas, parentLooper);

    SkPdfReal* vtx = pdfContext->fPdfDoc->createReal(tx);
    pdfContext->fObjectStack.push(vtx);

    SkPdfReal* vty = pdfContext->fPdfDoc->createReal(ty);
    pdfContext->fObjectStack.push(vty);

    SkPdfResult ret = PdfOp_Td(pdfContext, canvas, parentLooper);

    return ret;
}

static SkPdfResult PdfOp_Tm(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    EXPECT_OPERANDS("Tm", pdfContext, 6);
    POP_NUMBER(pdfContext, f);
    POP_NUMBER(pdfContext, e);
    POP_NUMBER(pdfContext, d);
    POP_NUMBER(pdfContext, c);
    POP_NUMBER(pdfContext, b);
    POP_NUMBER(pdfContext, a);
    CHECK_PARAMETERS();

    double array[6];
    array[0] = a;
    array[1] = b;
    array[2] = c;
    array[3] = d;
    array[4] = e;
    array[5] = f;

    SkMatrix matrix = SkMatrixFromPdfMatrix(array);
    matrix.postConcat(pdfContext->fGraphicsState.fCTM);
    matrix.preScale(SkDoubleToScalar(1), SkDoubleToScalar(-1));

    // TODO(edisonn): NYI - Text positioning.
    SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue,
                "Text positioning not implemented for 2+ chars", NULL, pdfContext);

    pdfContext->fGraphicsState.fMatrixTm = matrix;
    pdfContext->fGraphicsState.fMatrixTlm = matrix;;

    return kPartial_SkPdfResult;
}

//— T* Move to the start of the next line. This operator has the same effect as the code
//0 Tl Td
//where Tl is the current leading parameter in the text state
static SkPdfResult PdfOp_T_star(SkPdfContext* pdfContext, SkCanvas* canvas,
                                SkPdfTokenLooper* parentLooper) {
    SkPdfReal* zero = pdfContext->fPdfDoc->createReal(0.0);
    SkPdfReal* tl = pdfContext->fPdfDoc->createReal(pdfContext->fGraphicsState.fTextLeading);

    pdfContext->fObjectStack.push(zero);
    pdfContext->fObjectStack.push(tl);

    SkPdfResult ret = PdfOp_Td(pdfContext, canvas, parentLooper);

    return ret;
}

static SkPdfResult PdfOp_m(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    if (pdfContext->fGraphicsState.fPathClosed) {
        pdfContext->fGraphicsState.fPath.reset();
        pdfContext->fGraphicsState.fPathClosed = false;
    }

    EXPECT_OPERANDS("m", pdfContext, 2);
    POP_NUMBER(pdfContext, y);
    POP_NUMBER(pdfContext, x);
    CHECK_PARAMETERS();

    pdfContext->fGraphicsState.fCurPosY = y;
    pdfContext->fGraphicsState.fCurPosX = x;

    pdfContext->fGraphicsState.fPath.moveTo(SkDoubleToScalar(pdfContext->fGraphicsState.fCurPosX),
                                            SkDoubleToScalar(pdfContext->fGraphicsState.fCurPosY));

    return kOK_SkPdfResult;
}

static SkPdfResult PdfOp_l(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    if (pdfContext->fGraphicsState.fPathClosed) {
        pdfContext->fGraphicsState.fPath.reset();
        pdfContext->fGraphicsState.fPathClosed = false;
    }

    EXPECT_OPERANDS("l", pdfContext, 2);
    POP_NUMBER(pdfContext, y);
    POP_NUMBER(pdfContext, x);
    CHECK_PARAMETERS();

    pdfContext->fGraphicsState.fCurPosY = y;
    pdfContext->fGraphicsState.fCurPosX = x;

    pdfContext->fGraphicsState.fPath.lineTo(SkDoubleToScalar(pdfContext->fGraphicsState.fCurPosX),
                                            SkDoubleToScalar(pdfContext->fGraphicsState.fCurPosY));

    return kOK_SkPdfResult;
}

static SkPdfResult PdfOp_c(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    if (pdfContext->fGraphicsState.fPathClosed) {
        pdfContext->fGraphicsState.fPath.reset();
        pdfContext->fGraphicsState.fPathClosed = false;
    }

    EXPECT_OPERANDS("c", pdfContext, 6);
    POP_NUMBER(pdfContext, y3);
    POP_NUMBER(pdfContext, x3);
    POP_NUMBER(pdfContext, y2);
    POP_NUMBER(pdfContext, x2);
    POP_NUMBER(pdfContext, y1);
    POP_NUMBER(pdfContext, x1);
    CHECK_PARAMETERS();

    pdfContext->fGraphicsState.fPath.cubicTo(SkDoubleToScalar(x1), SkDoubleToScalar(y1),
                                             SkDoubleToScalar(x2), SkDoubleToScalar(y2),
                                             SkDoubleToScalar(x3), SkDoubleToScalar(y3));

    pdfContext->fGraphicsState.fCurPosX = x3;
    pdfContext->fGraphicsState.fCurPosY = y3;

    return kOK_SkPdfResult;
}

static SkPdfResult PdfOp_v(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    if (pdfContext->fGraphicsState.fPathClosed) {
        pdfContext->fGraphicsState.fPath.reset();
        pdfContext->fGraphicsState.fPathClosed = false;
    }

    EXPECT_OPERANDS("v", pdfContext, 4);
    POP_NUMBER(pdfContext, y3);
    POP_NUMBER(pdfContext, x3);
    POP_NUMBER(pdfContext, y2);
    POP_NUMBER(pdfContext, x2);
    CHECK_PARAMETERS();

    double y1 = pdfContext->fGraphicsState.fCurPosY;
    double x1 = pdfContext->fGraphicsState.fCurPosX;

    pdfContext->fGraphicsState.fPath.cubicTo(SkDoubleToScalar(x1), SkDoubleToScalar(y1),
                                             SkDoubleToScalar(x2), SkDoubleToScalar(y2),
                                             SkDoubleToScalar(x3), SkDoubleToScalar(y3));

    pdfContext->fGraphicsState.fCurPosX = x3;
    pdfContext->fGraphicsState.fCurPosY = y3;

    return kOK_SkPdfResult;
}

static SkPdfResult PdfOp_y(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    if (pdfContext->fGraphicsState.fPathClosed) {
        pdfContext->fGraphicsState.fPath.reset();
        pdfContext->fGraphicsState.fPathClosed = false;
    }

    EXPECT_OPERANDS("y", pdfContext, 4);
    POP_NUMBER(pdfContext, y3);
    POP_NUMBER(pdfContext, x3);
    POP_NUMBER(pdfContext, y1);
    POP_NUMBER(pdfContext, x1);
    CHECK_PARAMETERS();

    double y2 = pdfContext->fGraphicsState.fCurPosY;
    double x2 = pdfContext->fGraphicsState.fCurPosX;

    pdfContext->fGraphicsState.fPath.cubicTo(SkDoubleToScalar(x1), SkDoubleToScalar(y1),
                                             SkDoubleToScalar(x2), SkDoubleToScalar(y2),
                                             SkDoubleToScalar(x3), SkDoubleToScalar(y3));

    pdfContext->fGraphicsState.fCurPosX = x3;
    pdfContext->fGraphicsState.fCurPosY = y3;

    return kOK_SkPdfResult;
}

static SkPdfResult PdfOp_re(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    if (pdfContext->fGraphicsState.fPathClosed) {
        pdfContext->fGraphicsState.fPath.reset();
        pdfContext->fGraphicsState.fPathClosed = false;
    }

    EXPECT_OPERANDS("re", pdfContext, 4);
    POP_NUMBER(pdfContext, height);
    POP_NUMBER(pdfContext, width);
    POP_NUMBER(pdfContext, y);
    POP_NUMBER(pdfContext, x);
    CHECK_PARAMETERS();

    pdfContext->fGraphicsState.fPath.addRect(SkDoubleToScalar(x),
                                             SkDoubleToScalar(y),
                                             SkDoubleToScalar(x + width),
                                             SkDoubleToScalar(y + height));

    pdfContext->fGraphicsState.fCurPosX = x;
    pdfContext->fGraphicsState.fCurPosY = y + height;

    return kOK_SkPdfResult;
}

static SkPdfResult PdfOp_h(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    pdfContext->fGraphicsState.fPath.close();
    return kOK_SkPdfResult;
}

static SkPdfResult PdfOp_fillAndStroke(SkPdfContext* pdfContext, SkCanvas* canvas,
                                       bool fill, bool stroke, bool close, bool evenOdd) {
    SkPath path = pdfContext->fGraphicsState.fPath;

    if (close) {
        path.close();
    }

    canvas->setMatrix(pdfContext->fGraphicsState.fCTM);

    SkPaint paint;

    SkPoint line[2];
    if (fill && !stroke && path.isLine(line)) {
        paint.setStyle(SkPaint::kStroke_Style);

        // TODO(edisonn): implement this with patterns
        pdfContext->fGraphicsState.applyGraphicsState(&paint, false);
        paint.setStrokeWidth(SkDoubleToScalar(0));

        canvas->drawPath(path, paint);
    } else {
        if (fill) {
            if (strncmp((char*)pdfContext->fGraphicsState.fNonStroking.fColorSpace.fBuffer,
                        "Pattern", strlen("Pattern")) == 0 &&
                pdfContext->fGraphicsState.fNonStroking.fPattern != NULL) {

                // TODO(edisonn): we can use a shader here, like imageshader to draw fast.

                PdfOp_q(pdfContext, canvas, NULL);

                if (evenOdd) {
                    path.setFillType(SkPath::kEvenOdd_FillType);
                }
                canvas->clipPath(path);

                if (pdfContext->fPdfDoc
                              ->mapper()
                              ->mapType1PatternDictionary(pdfContext->fGraphicsState
                                                                    .fNonStroking
                                                                    .fPattern)
                                                         != kNone_SkPdfNativeObjectType) {
                    SkPdfType1PatternDictionary* pattern
                            = (SkPdfType1PatternDictionary*)pdfContext->fGraphicsState
                                                                      .fNonStroking
                                                                      .fPattern;

                    // TODO(edisonn): make PaintType constants
                    if (pattern->PaintType(pdfContext->fPdfDoc) == 1) {
                        // TODO(edisonn): don't use abs, iterate as asked, if the cells intersect
                        // it will change the result iterating in reverse
                        // remove then the following  bounds.sort();
                        int xStep = abs((int)pattern->XStep(pdfContext->fPdfDoc));
                        int yStep = abs((int)pattern->YStep(pdfContext->fPdfDoc));

                        SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue,
                                    "paterns x/y step is forced to positive number",
                                    pattern, pdfContext);

                        SkRect bounds = path.getBounds();
                        bounds.sort();

                        SkScalar x;
                        SkScalar y;

                        y = bounds.top();
                        int totalx = 0;
                        int totaly = 0;
                        while (y < bounds.bottom()) {
                            x = bounds.left();
                            totalx = 0;

                            while (x < bounds.right()) {
                                doXObject(pdfContext, canvas, pattern);

                                pdfContext->fGraphicsState.fContentStreamMatrix.preTranslate(
                                        SkIntToScalar(xStep), SkIntToScalar(0));
                                totalx += xStep;
                                x += SkIntToScalar(xStep);
                            }
                            pdfContext->fGraphicsState.fContentStreamMatrix.preTranslate(
                                    SkIntToScalar(-totalx), SkIntToScalar(0));

                            pdfContext->fGraphicsState.fContentStreamMatrix.preTranslate(
                                    SkIntToScalar(0), SkIntToScalar(-yStep));
                            totaly += yStep;
                            y += SkIntToScalar(yStep);
                        }
                        pdfContext->fGraphicsState.fContentStreamMatrix.preTranslate(
                                SkIntToScalar(0), SkIntToScalar(totaly));
                    }
                }

                PdfOp_Q(pdfContext, canvas, NULL);
            } else {
                paint.setStyle(SkPaint::kFill_Style);
                if (evenOdd) {
                    path.setFillType(SkPath::kEvenOdd_FillType);
                }

                pdfContext->fGraphicsState.applyGraphicsState(&paint, false);

                canvas->drawPath(path, paint);
            }
        }

        if (stroke) {
            if (false && strncmp((char*)pdfContext->fGraphicsState.fNonStroking.fColorSpace.fBuffer,
                                 "Pattern", strlen("Pattern")) == 0) {
                // TODO(edisonn): implement Pattern for strokes
                paint.setStyle(SkPaint::kStroke_Style);

                paint.setColor(SK_ColorGREEN);

                // reset it, just in case it messes up the stroke
                path.setFillType(SkPath::kWinding_FillType);
                canvas->drawPath(path, paint);
            } else {
                paint.setStyle(SkPaint::kStroke_Style);

                pdfContext->fGraphicsState.applyGraphicsState(&paint, true);

                // reset it, just in case it messes up the stroke
                path.setFillType(SkPath::kWinding_FillType);
                canvas->drawPath(path, paint);
            }
        }
    }

    pdfContext->fGraphicsState.fPath.reset();
    // TODO(edisonn): implement scale/zoom

    if (pdfContext->fGraphicsState.fHasClipPathToApply) {
#ifndef PDF_DEBUG_NO_CLIPING
        canvas->clipPath(pdfContext->fGraphicsState.fClipPath, SkRegion::kIntersect_Op, true);
#endif
    }

    //pdfContext->fGraphicsState.fClipPath.reset();
    pdfContext->fGraphicsState.fHasClipPathToApply = false;

    return kOK_SkPdfResult;

}

static SkPdfResult PdfOp_S(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    return PdfOp_fillAndStroke(pdfContext, canvas, false, true, false, false);
}

static SkPdfResult PdfOp_s(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    return PdfOp_fillAndStroke(pdfContext, canvas, false, true, true, false);
}

static SkPdfResult PdfOp_F(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    return PdfOp_fillAndStroke(pdfContext, canvas, true, false, false, false);
}

static SkPdfResult PdfOp_f(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    return PdfOp_fillAndStroke(pdfContext, canvas, true, false, false, false);
}

static SkPdfResult PdfOp_f_star(SkPdfContext* pdfContext, SkCanvas* canvas,
                                SkPdfTokenLooper*) {
    return PdfOp_fillAndStroke(pdfContext, canvas, true, false, false, true);
}

static SkPdfResult PdfOp_B(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    return PdfOp_fillAndStroke(pdfContext, canvas, true, true, false, false);
}

static SkPdfResult PdfOp_B_star(SkPdfContext* pdfContext, SkCanvas* canvas,
                                SkPdfTokenLooper*) {
    return PdfOp_fillAndStroke(pdfContext, canvas, true, true, false, true);
}

static SkPdfResult PdfOp_b(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    return PdfOp_fillAndStroke(pdfContext, canvas, true, true, true, false);
}

static SkPdfResult PdfOp_b_star(SkPdfContext* pdfContext, SkCanvas* canvas,
                                SkPdfTokenLooper*) {
    return PdfOp_fillAndStroke(pdfContext, canvas, true, true, true, true);
}

static SkPdfResult PdfOp_n(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    canvas->setMatrix(pdfContext->fGraphicsState.fCTM);
    if (pdfContext->fGraphicsState.fHasClipPathToApply) {
#ifndef PDF_DEBUG_NO_CLIPING
        canvas->clipPath(pdfContext->fGraphicsState.fClipPath, SkRegion::kIntersect_Op, true);
#endif
    }

    pdfContext->fGraphicsState.fHasClipPathToApply = false;

    pdfContext->fGraphicsState.fPathClosed = true;

    return kOK_SkPdfResult;
}

static SkPdfResult PdfOp_BT(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    pdfContext->fGraphicsState.fTextBlock   = true;
    SkMatrix matrix = pdfContext->fGraphicsState.fCTM;
    matrix.preScale(SkDoubleToScalar(1), SkDoubleToScalar(-1));
    pdfContext->fGraphicsState.fMatrixTm = matrix;
    pdfContext->fGraphicsState.fMatrixTlm = matrix;

    return kPartial_SkPdfResult;
}

static SkPdfResult PdfOp_ET(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    if (!pdfContext->fGraphicsState.fTextBlock) {
        SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kMissingBT_SkPdfIssue, "ET without BT", NULL,
                    pdfContext);

        return kIgnoreError_SkPdfResult;
    }

    pdfContext->fGraphicsState.fTextBlock = false;

    // TODO(edisonn): anything else to be done once we are done with draw text? Like restore stack?
    return kOK_SkPdfResult;
}

static SkPdfResult skpdfGraphicsStateApplyFontCore(SkPdfContext* pdfContext,
                                                   const SkPdfNativeObject* fontName, double fontSize) {
#ifdef PDF_TRACE
    printf("font name: %s\n", fontName->nameValue2().c_str());
#endif

    if (!pdfContext->fGraphicsState.fResources->Font(pdfContext->fPdfDoc)) {
        // TODO(edisonn): try to recover and draw it any way?
        SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kMissingFont_SkPdfIssue,
                    "No font", fontName, pdfContext);
        return kIgnoreError_SkPdfResult;
    }

    SkPdfNativeObject* objFont
            = pdfContext->fGraphicsState.fResources->Font(pdfContext->fPdfDoc)->get(fontName);
    objFont = pdfContext->fPdfDoc->resolveReference(objFont);
    if (kNone_SkPdfNativeObjectType == pdfContext->fPdfDoc->mapper()->mapFontDictionary(objFont)) {
        // TODO(edisonn): try to recover and draw it any way?
        SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kInvalidFont_SkPdfIssue,
                    "Invalid font", objFont, pdfContext);
        return kIgnoreError_SkPdfResult;
    }

    SkPdfFontDictionary* fd = (SkPdfFontDictionary*)objFont;

    SkPdfFont* skfont = SkPdfFont::fontFromPdfDictionary(pdfContext->fPdfDoc, fd);

    if (skfont) {
        pdfContext->fGraphicsState.fSkFont = skfont;
    }
    pdfContext->fGraphicsState.fCurFontSize = fontSize;
    return kOK_SkPdfResult;
}

//font size Tf Set the text font, Tf
//, to font and the text font size, Tfs, to size. font is the name of a
//font resource in the Fontsubdictionary of the current resource dictionary; size is
//a number representing a scale factor. There is no initial value for either font or
//size; they must be speciﬁed explicitly using Tf before any text is shown.
static SkPdfResult PdfOp_Tf(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    EXPECT_OPERANDS("Tf", pdfContext, 2);
    POP_NUMBER(pdfContext, fontSize);
    POP_NAME(pdfContext, fontName);
    CHECK_PARAMETERS();

    return skpdfGraphicsStateApplyFontCore(pdfContext, fontName, fontSize);
}

static SkPdfResult PdfOp_Tj(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    EXPECT_OPERANDS("Tj", pdfContext, 1);
    POP_STRING(pdfContext, str);
    CHECK_PARAMETERS();

    if (!pdfContext->fGraphicsState.fTextBlock) {
        // TODO(edisonn): try to recover and draw it any way?
        SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kMissingBT_SkPdfIssue, "Tj without BT", NULL,
                    pdfContext);
        return kIgnoreError_SkPdfResult;
    }

    SkPdfResult ret = DrawText(pdfContext, str, canvas);

    return ret;
}

static SkPdfResult PdfOp_quote(SkPdfContext* pdfContext, SkCanvas* canvas,
                               SkPdfTokenLooper* parentLooper) {
    if (!pdfContext->fGraphicsState.fTextBlock) {
        // TODO(edisonn): try to recover and draw it any way?
        SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kMissingBT_SkPdfIssue,
                    "' without BT", NULL, pdfContext);
        return kIgnoreError_SkPdfResult;
    }

    PdfOp_T_star(pdfContext, canvas, parentLooper);
    // Do not pop, and push, just transfer the param to Tj
    return PdfOp_Tj(pdfContext, canvas, parentLooper);
}

static SkPdfResult PdfOp_doublequote(SkPdfContext* pdfContext, SkCanvas* canvas,
                                     SkPdfTokenLooper* parentLooper) {
    if (!pdfContext->fGraphicsState.fTextBlock) {
        // TODO(edisonn): try to recover and draw it any way?
        SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kMissingBT_SkPdfIssue,
                    "\" without BT", NULL, pdfContext);
        return kIgnoreError_SkPdfResult;
    }

    EXPECT_OPERANDS("\"", pdfContext, 3);
    POP_OBJ(pdfContext, str);
    POP_OBJ(pdfContext, ac);
    POP_OBJ(pdfContext, aw);
    CHECK_PARAMETERS();

    pdfContext->fObjectStack.push(aw);
    PdfOp_Tw(pdfContext, canvas, parentLooper);

    pdfContext->fObjectStack.push(ac);
    PdfOp_Tc(pdfContext, canvas, parentLooper);

    pdfContext->fObjectStack.push(str);
    PdfOp_quote(pdfContext, canvas, parentLooper);

    return kPartial_SkPdfResult;
}

static SkPdfResult PdfOp_TJ(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    EXPECT_OPERANDS("Tf", pdfContext, 1);
    POP_ARRAY(pdfContext, array);
    CHECK_PARAMETERS();

    if (!pdfContext->fGraphicsState.fTextBlock) {
        // TODO(edisonn): try to recover and draw it any way?
        SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kMissingBT_SkPdfIssue, "TJ without BT", NULL,
                    pdfContext);
        return kIgnoreError_SkPdfResult;
    }

    if (!array->isArray()) {
        SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, array,
                                  SkPdfNativeObject::kArray_PdfObjectType, pdfContext);
        return kIgnoreError_SkPdfResult;
    }

    for( int i=0; i<static_cast<int>(array->size()); i++ )
    {
        if (!(*array)[i]) {
            SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity,
                                      "element [i] is null, no element should be null",
                                      array,
                                      SkPdfNativeObject::_kAnyString_PdfObjectType |
                                              SkPdfNativeObject::_kNumber_PdfObjectType,
                                      pdfContext);
        } else if( (*array)[i]->isAnyString()) {
            SkPdfNativeObject* obj = (*array)[i];
            DrawText(pdfContext, obj, canvas);
        } else if ((*array)[i]->isNumber()) {
            double dx = (*array)[i]->numberValue();
            SkMatrix matrix;
            matrix.setAll(SkDoubleToScalar(1),
                          SkDoubleToScalar(0),
                          // TODO(edisonn): use writing mode, vertical/horizontal.
                          SkDoubleToScalar(-dx),  // amount is substracted!!!
                          SkDoubleToScalar(0),
                          SkDoubleToScalar(1),
                          SkDoubleToScalar(0),
                          SkDoubleToScalar(0),
                          SkDoubleToScalar(0),
                          SkDoubleToScalar(1));

            pdfContext->fGraphicsState.fMatrixTm.preConcat(matrix);
        } else {
            SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, "wrong type", (*array)[i],
                                      SkPdfNativeObject::kArray_PdfObjectType |
                                              SkPdfNativeObject::_kNumber_PdfObjectType,
                                      pdfContext);
        }
    }
    return kPartial_SkPdfResult;  // TODO(edisonn): Implement fully DrawText before returing OK.
}

static SkPdfResult PdfOp_CS_cs(SkPdfContext* pdfContext, SkCanvas* canvas,
                               SkPdfColorOperator* colorOperator) {
    EXPECT_OPERANDS("CS/cs", pdfContext, 1);
    POP_NAME(pdfContext, name);
    CHECK_PARAMETERS();

    //Next, get the ColorSpace Dictionary from the Resource Dictionary:
    SkPdfDictionary* colorSpaceResource
            = pdfContext->fGraphicsState.fResources->ColorSpace(pdfContext->fPdfDoc);

    SkPdfNativeObject* colorSpace
            = colorSpaceResource ? pdfContext->fPdfDoc
                                             ->resolveReference(colorSpaceResource->get(name)) :
                                   name;

    if (colorSpace == NULL) {
        colorOperator->fColorSpace = name->strRef();
    } else {
#ifdef PDF_TRACE
        printf("CS = %s\n", colorSpace->toString(0, 0).c_str());
#endif   // PDF_TRACE
        if (colorSpace->isName()) {
            colorOperator->fColorSpace = colorSpace->strRef();
        } else if (colorSpace->isArray()) {
            size_t cnt = colorSpace->size();
            if (cnt == 0) {
                SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kIncostistentSizes_SkPdfIssue,
                            "color space has length 0", colorSpace, pdfContext);
                return kIgnoreError_SkPdfResult;
            }
            SkPdfNativeObject* type = colorSpace->objAtAIndex(0);
            type = pdfContext->fPdfDoc->resolveReference(type);

            if (type->isName("ICCBased")) {
                if (cnt != 2) {
                    SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kIncostistentSizes_SkPdfIssue,
                                "ICCBased color space must have an array with 2 elements",
                                colorSpace, pdfContext);
                    return kIgnoreError_SkPdfResult;
                }
                SkPdfNativeObject* prop = colorSpace->objAtAIndex(1);
                prop = pdfContext->fPdfDoc->resolveReference(prop);
#ifdef PDF_TRACE
                printf("ICCBased prop = %s\n", prop->toString(0, 0).c_str());
#endif   // PDF_TRACE
                // TODO(edisonn): hack
                if (prop && prop->isDictionary() && prop->get("N") &&
                        prop->get("N")->isInteger() && prop->get("N")->intValue() == 3) {
                    colorOperator->setColorSpace(&strings_DeviceRGB);
                    return kPartial_SkPdfResult;
                }
                return kNYI_SkPdfResult;
            }
        }
    }

    return kPartial_SkPdfResult;
}

static SkPdfResult PdfOp_CS(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    return PdfOp_CS_cs(pdfContext, canvas, &pdfContext->fGraphicsState.fStroking);
}

static SkPdfResult PdfOp_cs(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    return PdfOp_CS_cs(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStroking);
}

static SkPdfResult PdfOp_SC_sc(SkPdfContext* pdfContext, SkCanvas* canvas,
                               SkPdfColorOperator* colorOperator) {
    double c[4];
//    int64_t v[4];

    int n = GetColorSpaceComponents(colorOperator->fColorSpace);

    bool doubles = true;
    if (colorOperator->fColorSpace.equals("Indexed")) {
        doubles = false;
    }

#ifdef PDF_TRACE
    printf("color space = %s, N = %i\n", colorOperator->fColorSpace.fBuffer, n);
#endif

    EXPECT_OPERANDS("SC/sc", pdfContext, n);

    for (int i = n - 1; i >= 0 ; i--) {
        if (doubles) {
            POP_NUMBER_INTO(pdfContext, c[i]);
//        } else {
//            v[i] = pdfContext->fObjectStack.top()->intValue();        pdfContext->fObjectStack.pop();
        }
    }
    CHECK_PARAMETERS();

    // TODO(edisonn): Now, set that color. Only DeviceRGB supported.
    // TODO(edisonn): do possible field values to enum at parsing time!
    // TODO(edisonn): support also abbreviations /DeviceRGB == /RGB
    if (colorOperator->fColorSpace.equals("DeviceRGB") ||
            colorOperator->fColorSpace.equals("RGB")) {
        colorOperator->setRGBColor(SkColorSetRGB((U8CPU)(255*c[0]),
                                                 (U8CPU)(255*c[1]),
                                                 (U8CPU)(255*c[2])));
    }
    return kPartial_SkPdfResult;
}

static SkPdfResult PdfOp_SC(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    return PdfOp_SC_sc(pdfContext, canvas, &pdfContext->fGraphicsState.fStroking);
}

static SkPdfResult PdfOp_sc(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    return PdfOp_SC_sc(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStroking);
}

static SkPdfResult PdfOp_SCN_scn(SkPdfContext* pdfContext, SkCanvas* canvas,
                                 SkPdfColorOperator* colorOperator) {
    if (pdfContext->fObjectStack.count() > 0 && pdfContext->fObjectStack.top()->isName()) {
        SkPdfNativeObject* name = pdfContext->fObjectStack.top();    pdfContext->fObjectStack.pop();

        SkPdfDictionary* patternResources
                = pdfContext->fGraphicsState.fResources->Pattern(pdfContext->fPdfDoc);

        if (patternResources == NULL) {
#ifdef PDF_TRACE
            printf("ExtGState is NULL!\n");
#endif
            return kIgnoreError_SkPdfResult;
        }

        colorOperator->setPatternColorSpace(
                pdfContext->fPdfDoc->resolveReference(patternResources->get(name)));
    }

    // TODO(edisonn): SCN supports more color spaces than SCN. Read and implement spec.
    PdfOp_SC_sc(pdfContext, canvas, colorOperator);

    return kPartial_SkPdfResult;
}

static SkPdfResult PdfOp_SCN(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    return PdfOp_SCN_scn(pdfContext, canvas, &pdfContext->fGraphicsState.fStroking);
}

static SkPdfResult PdfOp_scn(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    return PdfOp_SCN_scn(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStroking);
}

static SkPdfResult PdfOp_G_g(SkPdfContext* pdfContext, SkCanvas* canvas,
                             SkPdfColorOperator* colorOperator) {
    EXPECT_OPERANDS("G/g", pdfContext, 1);
    POP_NUMBER(pdfContext, gray);
    CHECK_PARAMETERS();

    // TODO(edisonn): limit gray in [0, 1]

    // TODO(edisonn): HACK - it should be device gray, but not suported right now
    colorOperator->fColorSpace = strings_DeviceRGB;
    colorOperator->setRGBColor(SkColorSetRGB((U8CPU)(255 * gray),
                                             (U8CPU)(255 * gray),
                                             (U8CPU)(255 * gray)));

    return kPartial_SkPdfResult;
}

static SkPdfResult PdfOp_G(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    return PdfOp_G_g(pdfContext, canvas, &pdfContext->fGraphicsState.fStroking);
}

static SkPdfResult PdfOp_g(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    return PdfOp_G_g(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStroking);
}

static SkPdfResult PdfOp_RG_rg(SkPdfContext* pdfContext, SkCanvas* canvas,
                               SkPdfColorOperator* colorOperator) {
    EXPECT_OPERANDS("RG/rg", pdfContext, 3);
    POP_NUMBER(pdfContext, b);
    POP_NUMBER(pdfContext, g);
    POP_NUMBER(pdfContext, r);
    CHECK_PARAMETERS();

    colorOperator->fColorSpace = strings_DeviceRGB;
    colorOperator->setRGBColor(SkColorSetRGB((U8CPU)(255*r), (U8CPU)(255*g), (U8CPU)(255*b)));
    return kOK_SkPdfResult;
}

static SkPdfResult PdfOp_RG(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    return PdfOp_RG_rg(pdfContext, canvas, &pdfContext->fGraphicsState.fStroking);
}

static SkPdfResult PdfOp_rg(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    return PdfOp_RG_rg(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStroking);
}

static SkPdfResult PdfOp_K_k(SkPdfContext* pdfContext, SkCanvas* canvas,
                             SkPdfColorOperator* colorOperator) {
    // TODO(edisonn): spec has some rules about overprint, implement them.
    EXPECT_OPERANDS("K/k", pdfContext, 4);
    POP_NUMBER(pdfContext, k);
    POP_NUMBER(pdfContext, y);
    POP_NUMBER(pdfContext, m);
    POP_NUMBER(pdfContext, c);
    CHECK_PARAMETERS();

    // TODO(edisonn): really silly quick way to remove compiler warning
    if (k + y + m + c == 0) {
        return kNYI_SkPdfResult;
    }

    //colorOperator->fColorSpace = strings_DeviceCMYK;
    // TODO(edisonn): Set color.
    return kNYI_SkPdfResult;
}

static SkPdfResult PdfOp_K(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    return PdfOp_K_k(pdfContext, canvas, &pdfContext->fGraphicsState.fStroking);
}

static SkPdfResult PdfOp_k(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    return PdfOp_K_k(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStroking);
}

static SkPdfResult PdfOp_W(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    pdfContext->fGraphicsState.fClipPath = pdfContext->fGraphicsState.fPath;
    pdfContext->fGraphicsState.fHasClipPathToApply = true;

    return kOK_SkPdfResult;
}

static SkPdfResult PdfOp_W_star(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    pdfContext->fGraphicsState.fClipPath = pdfContext->fGraphicsState.fPath;

    pdfContext->fGraphicsState.fClipPath.setFillType(SkPath::kEvenOdd_FillType);
    pdfContext->fGraphicsState.fHasClipPathToApply = true;

    return kOK_SkPdfResult;
}

static SkPdfResult PdfOp_BX(SkPdfContext* pdfContext, SkCanvas* canvas,
                            SkPdfTokenLooper* parentLooper) {
    PdfCompatibilitySectionLooper looper(parentLooper);
    looper.loop();
    return kOK_SkPdfResult;
}

static SkPdfResult PdfOp_EX(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kNullObject_SkPdfIssue,
                "EX operator should not be called, it is handled in a looper, "
                        "unless the file is corrupted, we should assert",
                NULL, pdfContext);

    return kIgnoreError_SkPdfResult;
}

static SkPdfResult PdfOp_BI(SkPdfContext* pdfContext, SkCanvas* canvas,
                            SkPdfTokenLooper* parentLooper) {
    PdfInlineImageLooper looper(parentLooper);
    looper.loop();
    return kOK_SkPdfResult;
}

static SkPdfResult PdfOp_ID(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kNullObject_SkPdfIssue,
                "ID operator should not be called, it is habdled in a looper, "
                        "unless the file is corrupted, we should assert",
                NULL, pdfContext);
    return kIgnoreError_SkPdfResult;
}

static SkPdfResult PdfOp_EI(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kNullObject_SkPdfIssue,
                "EI operator should not be called, it is habdled in a looper, "
                        "unless the file is corrupted, we should assert",
                NULL, pdfContext);
    return kIgnoreError_SkPdfResult;
}

static SkPdfResult skpdfGraphicsStateApply_ca(SkPdfContext* pdfContext, double ca) {
    pdfContext->fGraphicsState.fNonStroking.fOpacity = ca;
    return kOK_SkPdfResult;
}

static SkPdfResult skpdfGraphicsStateApply_CA(SkPdfContext* pdfContext, double CA) {
    pdfContext->fGraphicsState.fStroking.fOpacity = CA;
    return kOK_SkPdfResult;
}

static SkPdfResult skpdfGraphicsStateApplyLW(SkPdfContext* pdfContext, double lineWidth) {
    pdfContext->fGraphicsState.fLineWidth = lineWidth;
    return kOK_SkPdfResult;
}

static SkPdfResult skpdfGraphicsStateApplyLC(SkPdfContext* pdfContext, int64_t lineCap) {
    pdfContext->fGraphicsState.fLineCap = (int)lineCap;
    return kOK_SkPdfResult;
}

static SkPdfResult skpdfGraphicsStateApplyLJ(SkPdfContext* pdfContext, int64_t lineJoin) {
    pdfContext->fGraphicsState.fLineJoin = (int)lineJoin;
    return kOK_SkPdfResult;
}

static SkPdfResult skpdfGraphicsStateApplyML(SkPdfContext* pdfContext, double miterLimit) {
    pdfContext->fGraphicsState.fMiterLimit = miterLimit;
    return kOK_SkPdfResult;
}

// TODO(edisonn): test all dashing rules, not sure if they work as in skia.
/*
1) [ ] 0 No dash; solid, unbroken lines
2) [3] 0 3 units on, 3 units off, …
3) [2] 1 1 on, 2 off, 2 on, 2 off, …
4) [2 1] 0 2 on, 1 off, 2 on, 1 off, …
5) [3 5] 6 2 off, 3 on, 5 off, 3 on, 5 off, …
6) [2 3] 11 1 on, 3 off, 2 on, 3 off, 2 on, …
 */

static SkPdfResult skpdfGraphicsStateApplyD(SkPdfContext* pdfContext, SkPdfArray* intervals,
                                            SkPdfNativeObject* phase) {
    if (intervals == NULL) {
        SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, intervals,
                                  SkPdfNativeObject::_kNumber_PdfObjectType, pdfContext);
        return kIgnoreError_SkPdfResult;
    }

    if (phase == NULL) {
        SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, phase,
                                  SkPdfNativeObject::_kNumber_PdfObjectType, pdfContext);
        return kIgnoreError_SkPdfResult;
    }

    int cnt = (int) intervals->size();
    if (cnt >= 256) {
        // TODO(edisonn): alloc memory
        SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue,
                    "dash array size unssuported, cnt > 256", intervals, pdfContext);
        return kIgnoreError_SkPdfResult;
    }
    for (int i = 0; i < cnt; i++) {
        if (!intervals->objAtAIndex(i) || !intervals->objAtAIndex(i)->isNumber()) {
            SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL,
                                      intervals->objAtAIndex(i),
                                      SkPdfNativeObject::_kNumber_PdfObjectType, NULL);
            return kIgnoreError_SkPdfResult;
        }
    }

    double total = 0;
    for (int i = 0 ; i < cnt; i++) {
        pdfContext->fGraphicsState.fDashArray[i] = intervals->objAtAIndex(i)->scalarValue();
        total += pdfContext->fGraphicsState.fDashArray[i];
    }
    if (cnt & 1) {
        if (cnt == 1) {
            pdfContext->fGraphicsState.fDashArray[1] = pdfContext->fGraphicsState.fDashArray[0];
            cnt++;
        } else {
            // TODO(edisonn): report error/warning
            return kNYI_SkPdfResult;
        }
    }
    pdfContext->fGraphicsState.fDashArrayLength = cnt;
    pdfContext->fGraphicsState.fDashPhase = phase->scalarValue();
    if (pdfContext->fGraphicsState.fDashPhase == 0) {
        // other rules, changes?
        pdfContext->fGraphicsState.fDashPhase = SkDoubleToScalar(total);
    }

    return kOK_SkPdfResult;
}

static SkPdfResult skpdfGraphicsStateApplyD(SkPdfContext* pdfContext, SkPdfArray* dash) {
    if (!dash || dash->isArray()) {
        SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, dash,
                                  SkPdfNativeObject::kArray_PdfObjectType, pdfContext);
        return kIgnoreError_SkPdfResult;
    }

    if (dash->size() != 2) {
        SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kIncostistentSizes_SkPdfIssue,
                    "hash array must have 2 elements", dash, pdfContext);
        return kIgnoreError_SkPdfResult;
    }

    if (!dash->objAtAIndex(0) || !dash->objAtAIndex(0)->isArray()) {
        SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, dash->objAtAIndex(0),
                                  SkPdfNativeObject::kArray_PdfObjectType, pdfContext);
        return kIgnoreError_SkPdfResult;
    }

    if (!dash->objAtAIndex(1) || !dash->objAtAIndex(1)->isNumber()) {
        SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, dash->objAtAIndex(1),
                                  SkPdfNativeObject::_kNumber_PdfObjectType, pdfContext);
        return kIgnoreError_SkPdfResult;
    }

    return skpdfGraphicsStateApplyD(pdfContext, (SkPdfArray*)dash->objAtAIndex(0),
                                    dash->objAtAIndex(1));
}

static void skpdfGraphicsStateApplyFont(SkPdfContext* pdfContext, SkPdfArray* fontAndSize) {
    if (!fontAndSize || !fontAndSize->isArray()) {
        SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, fontAndSize,
                                  SkPdfNativeObject::kArray_PdfObjectType, pdfContext);
        return;
    }

    if (fontAndSize->size() != 2) {
        SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kIncostistentSizes_SkPdfIssue,
                    "font array must have 2 elements", fontAndSize, pdfContext);
        return;
    }

    if (!fontAndSize->objAtAIndex(0) || !fontAndSize->objAtAIndex(0)->isName()) {
        SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL,
                                  fontAndSize->objAtAIndex(0),
                                  SkPdfNativeObject::kName_PdfObjectType, pdfContext);
        return;
    }


    if (!fontAndSize->objAtAIndex(1) || !fontAndSize->objAtAIndex(1)->isNumber()) {
        SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL,
                                  fontAndSize->objAtAIndex(0),
                                  SkPdfNativeObject::_kNumber_PdfObjectType, pdfContext);
        return;
    }

    skpdfGraphicsStateApplyFontCore(pdfContext, fontAndSize->objAtAIndex(0),
                                    fontAndSize->objAtAIndex(1)->numberValue());
}


//lineWidth w Set the line width in the graphics state (see “Line Width” on page 152).
static SkPdfResult PdfOp_w(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    EXPECT_OPERANDS("w", pdfContext, 1);
    POP_NUMBER(pdfContext, lw);
    CHECK_PARAMETERS();

    return skpdfGraphicsStateApplyLW(pdfContext, lw);
}

//lineCap J Set the line cap style in the graphics state (see “Line Cap Style” on page 153).
static SkPdfResult PdfOp_J(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    // TODO(edisonn): round/ceil to int?
    EXPECT_OPERANDS("J", pdfContext, 1);
    POP_NUMBER(pdfContext, lc);
    CHECK_PARAMETERS();

    return skpdfGraphicsStateApplyLC(pdfContext, (int)lc);
}

//lineJoin j Set the line join style in the graphics state (see “Line Join Style” on page 153).
static SkPdfResult PdfOp_j(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    // TODO(edisonn): round/ceil to int?
    EXPECT_OPERANDS("j", pdfContext, 1);
    POP_NUMBER(pdfContext, lj);
    CHECK_PARAMETERS();

    return skpdfGraphicsStateApplyLJ(pdfContext, (int)lj);
}

//miterLimit M Set the miter limit in the graphics state (see “Miter Limit” on page 153).
static SkPdfResult PdfOp_M(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    EXPECT_OPERANDS("M", pdfContext, 1);
    POP_NUMBER(pdfContext, ml);
    CHECK_PARAMETERS();
    return skpdfGraphicsStateApplyML(pdfContext, ml);
}

//dashArray dashPhase d Set the line dash pattern in the graphics state (see “Line Dash Pattern” on
//page 155).
static SkPdfResult PdfOp_d(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    EXPECT_OPERANDS("d", pdfContext, 2);
    POP_OBJ(pdfContext, phase);
    POP_ARRAY(pdfContext, array);
    CHECK_PARAMETERS();

    return skpdfGraphicsStateApplyD(pdfContext, array, phase);
}

//intent ri (PDF 1.1) Set the color rendering intent in the graphics state (see “Rendering Intents”
// on page 197).
static SkPdfResult PdfOp_ri(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    pdfContext->fObjectStack.pop();

    SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, "render intent NYI", NULL,
                pdfContext);

    return kNYI_SkPdfResult;
}

//ﬂatness i Set the ﬂatness tolerance in the graphics state (see Section 6.5.1, “Flatness
//Tolerance”). ﬂatness is a number in the range 0 to 100; a value of 0 speci-
//ﬁes the output device’s default ﬂatness tolerance.
static SkPdfResult PdfOp_i(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    EXPECT_OPERANDS("i", pdfContext, 1);
    POP_NUMBER(pdfContext, flatness);
    CHECK_PARAMETERS();

    if (flatness < 0 || flatness > 100) {
        SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kOutOfRange_SkPdfIssue,
                    "flatness must be a real in [0, 100] range", flatness_obj, pdfContext);
        return kIgnoreError_SkPdfResult;
    }

    return kNYI_SkPdfResult;
}

SkTDict<SkXfermode::Mode> gPdfBlendModes(20);

class InitBlendModes {
public:
    InitBlendModes() {
        // TODO(edisonn): use the python code generator?
        // TABLE 7.2 Standard separable blend modes
        gPdfBlendModes.set("Normal", SkXfermode::kSrc_Mode);
        gPdfBlendModes.set("Multiply", SkXfermode::kMultiply_Mode);
        gPdfBlendModes.set("Screen", SkXfermode::kScreen_Mode);
        gPdfBlendModes.set("Overlay", SkXfermode::kOverlay_Mode);
        gPdfBlendModes.set("Darken", SkXfermode::kDarken_Mode);
        gPdfBlendModes.set("Lighten", SkXfermode::kLighten_Mode);
        gPdfBlendModes.set("ColorDodge", SkXfermode::kColorDodge_Mode);
        gPdfBlendModes.set("ColorBurn", SkXfermode::kColorBurn_Mode);
        gPdfBlendModes.set("HardLight", SkXfermode::kHardLight_Mode);
        gPdfBlendModes.set("SoftLight", SkXfermode::kSoftLight_Mode);
        gPdfBlendModes.set("Difference", SkXfermode::kDifference_Mode);
        gPdfBlendModes.set("Exclusion", SkXfermode::kExclusion_Mode);

        // TABLE 7.3 Standard nonseparable blend modes
        gPdfBlendModes.set("Hue", SkXfermode::kHue_Mode);
        gPdfBlendModes.set("Saturation", SkXfermode::kSaturation_Mode);
        gPdfBlendModes.set("Color", SkXfermode::kColor_Mode);
        gPdfBlendModes.set("Luminosity", SkXfermode::kLuminosity_Mode);
    }
};

InitBlendModes _gDummyInniter;

static SkXfermode::Mode xferModeFromBlendMode(const char* blendMode, size_t len) {
    SkXfermode::Mode mode = (SkXfermode::Mode)(SkXfermode::kLastMode + 1);
    if (gPdfBlendModes.find(blendMode, len, &mode)) {
        return mode;
    }

    return (SkXfermode::Mode)(SkXfermode::kLastMode + 1);
}

static void skpdfGraphicsStateApplyBM_name(SkPdfContext* pdfContext, const SkString& blendMode) {
    SkXfermode::Mode mode = xferModeFromBlendMode(blendMode.c_str(), blendMode.size());
    if (mode <= SkXfermode::kLastMode) {
        pdfContext->fGraphicsState.fBlendModesLength = 1;
        pdfContext->fGraphicsState.fBlendModes[0] = mode;
    } else {
        SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kUnknownBlendMode_SkPdfIssue,
                    blendMode.c_str(), NULL, pdfContext);
    }
}

static void skpdfGraphicsStateApplyBM_array(SkPdfContext* pdfContext, SkPdfArray* blendModes) {
    if (!blendModes || !blendModes->isArray()) {
        SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, blendModes,
                                  SkPdfNativeObject::kArray_PdfObjectType, pdfContext);
        return;
    }

    if (blendModes->size() == 0 || blendModes->size() > 256) {
        SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kIncostistentSizes_SkPdfIssue,
                    "length of blendmodes, 0, is an erro, 256+, is NYI", blendModes, pdfContext);
        return;
    }

    SkXfermode::Mode modes[256];
    int cnt = (int) blendModes->size();
    for (int i = 0; i < cnt; i++) {
        SkPdfNativeObject* name = blendModes->objAtAIndex(i);
        if (!name || !name->isName()) {
            SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, name,
                                      SkPdfNativeObject::kName_PdfObjectType, pdfContext);
            return;
        }
        SkXfermode::Mode mode = xferModeFromBlendMode(name->c_str(), name->lenstr());
        if (mode > SkXfermode::kLastMode) {
            SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kUnknownBlendMode_SkPdfIssue, NULL, name,
                        pdfContext);
            return;
        }
    }

    pdfContext->fGraphicsState.fBlendModesLength = cnt;
    for (int i = 0; i < cnt; i++) {
        pdfContext->fGraphicsState.fBlendModes[i] = modes[i];
    }
}

static void skpdfGraphicsStateApplySMask_dict(SkPdfContext* pdfContext, SkPdfDictionary* sMask) {
    if (!sMask || !sMask->isName()) {
        SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, sMask,
                                  SkPdfNativeObject::kArray_PdfObjectType, pdfContext);
        return;
    }

    if (pdfContext->fPdfDoc->mapper()->mapSoftMaskDictionary(sMask)) {
        pdfContext->fGraphicsState.fSoftMaskDictionary = (SkPdfSoftMaskDictionary*)sMask;
    } else if (pdfContext->fPdfDoc->mapper()->mapSoftMaskImageDictionary(sMask)) {
        SkPdfSoftMaskImageDictionary* smid = (SkPdfSoftMaskImageDictionary*)sMask;
        pdfContext->fGraphicsState.fSMask = getImageFromObject(pdfContext, smid, true);
    } else {
        SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity,
                                  "Dictionary must be SoftMask, or SoftMaskImage",
                                  sMask, SkPdfNativeObject::kDictionary_PdfObjectType, pdfContext);
    }
}

static void skpdfGraphicsStateApplySMask_name(SkPdfContext* pdfContext, const SkString& sMask) {
    if (sMask.equals("None")) {
        pdfContext->fGraphicsState.fSoftMaskDictionary = NULL;
        pdfContext->fGraphicsState.fSMask = NULL;
        return;
    }

    SkPdfDictionary* extGStateDictionary
            = pdfContext->fGraphicsState.fResources->ExtGState(pdfContext->fPdfDoc);

    if (extGStateDictionary == NULL) {
        SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kMissingExtGState_SkPdfIssue, NULL,
                    pdfContext->fGraphicsState.fResources, pdfContext);
        return;
    }

    SkPdfNativeObject* obj
            = pdfContext->fPdfDoc->resolveReference(extGStateDictionary->get(sMask.c_str()));
    if (!obj || !obj->isDictionary()) {
        SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, obj,
                                  SkPdfNativeObject::kDictionary_PdfObjectType, pdfContext);
        return;
    }

    pdfContext->fGraphicsState.fSoftMaskDictionary = NULL;
    pdfContext->fGraphicsState.fSMask = NULL;

    skpdfGraphicsStateApplySMask_dict(pdfContext, obj->asDictionary());
}

static void skpdfGraphicsStateApplyAIS(SkPdfContext* pdfContext, bool alphaSource) {
    pdfContext->fGraphicsState.fAlphaSource = alphaSource;
}


//dictName gs (PDF 1.2) Set the speciﬁed parameters in the graphics state. dictName is
//the name of a graphics state parameter dictionary in the ExtGState subdictionary of the current
//resource dictionary (see the next section).
static SkPdfResult PdfOp_gs(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    EXPECT_OPERANDS("gs", pdfContext, 1);
    POP_NAME(pdfContext, name);
    CHECK_PARAMETERS();

    SkPdfDictionary* extGStateDictionary
            = pdfContext->fGraphicsState.fResources->ExtGState(pdfContext->fPdfDoc);

    if (extGStateDictionary == NULL) {
        SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kMissingExtGState_SkPdfIssue, NULL,
                    pdfContext->fGraphicsState.fResources, pdfContext);
        return kIgnoreError_SkPdfResult;
    }

    SkPdfNativeObject* value
            = pdfContext->fPdfDoc->resolveReference(extGStateDictionary->get(name));

    if (kNone_SkPdfNativeObjectType ==
                pdfContext->fPdfDoc->mapper()->mapGraphicsStateDictionary(value)) {
        return kIgnoreError_SkPdfResult;
    }
    SkPdfGraphicsStateDictionary* gs = (SkPdfGraphicsStateDictionary*)value;

    if (gs == NULL) {
        SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL,
                                  gs, SkPdfNativeObject::kDictionary_PdfObjectType, pdfContext);
        return kIgnoreError_SkPdfResult;
    }

    if (gs->has_LW()) {
        skpdfGraphicsStateApplyLW(pdfContext, gs->LW(pdfContext->fPdfDoc));
    }

    if (gs->has_LC()) {
        skpdfGraphicsStateApplyLC(pdfContext, gs->LC(pdfContext->fPdfDoc));
    }

    if (gs->has_LJ()) {
        skpdfGraphicsStateApplyLJ(pdfContext, gs->LJ(pdfContext->fPdfDoc));
    }

    if (gs->has_ML()) {
        skpdfGraphicsStateApplyML(pdfContext, gs->ML(pdfContext->fPdfDoc));
    }

    if (gs->has_D()) {
        skpdfGraphicsStateApplyD(pdfContext, gs->D(pdfContext->fPdfDoc));
    }

    if (gs->has_Font()) {
        skpdfGraphicsStateApplyFont(pdfContext, gs->Font(pdfContext->fPdfDoc));
    }

    if (gs->has_BM()) {
        if (gs->isBMAName(pdfContext->fPdfDoc)) {
            skpdfGraphicsStateApplyBM_name(pdfContext, gs->getBMAsName(pdfContext->fPdfDoc));
        } else if (gs->isBMAArray(pdfContext->fPdfDoc)) {
            skpdfGraphicsStateApplyBM_array(pdfContext, gs->getBMAsArray(pdfContext->fPdfDoc));
        } else {
            SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, "wrong type", gs->get("BM"),
                                      SkPdfNativeObject::kArray_PdfObjectType |
                                              SkPdfNativeObject::kName_PdfObjectType, pdfContext);
        }
    }

    if (gs->has_SMask()) {
        if (gs->isSMaskAName(pdfContext->fPdfDoc)) {
            skpdfGraphicsStateApplySMask_name(pdfContext, gs->getSMaskAsName(pdfContext->fPdfDoc));
        } else if (gs->isSMaskADictionary(pdfContext->fPdfDoc)) {
            skpdfGraphicsStateApplySMask_dict(pdfContext,
                                              gs->getSMaskAsDictionary(pdfContext->fPdfDoc));
        } else {
            SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity,
                                      "wrong type",
                                      gs->get("BM"),
                                      SkPdfNativeObject::kDictionary_PdfObjectType |
                                              SkPdfNativeObject::kName_PdfObjectType,
                                              pdfContext);
        }
    }

    if (gs->has_ca()) {
        skpdfGraphicsStateApply_ca(pdfContext, gs->ca(pdfContext->fPdfDoc));
    }

    if (gs->has_CA()) {
        skpdfGraphicsStateApply_CA(pdfContext, gs->CA(pdfContext->fPdfDoc));
    }

    if (gs->has_AIS()) {
        skpdfGraphicsStateApplyAIS(pdfContext, gs->AIS(pdfContext->fPdfDoc));
    }

    // TODO(edisonn): make sure we loaded all those properties in graphic state.

    return kOK_SkPdfResult;
}

//charSpace Tc Set the character spacing, Tc
//, to charSpace, which is a number expressed in unscaled text space units.
//  Character spacing is used by the Tj, TJ, and ' operators.
//Initial value: 0.
SkPdfResult PdfOp_Tc(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    EXPECT_OPERANDS("Tc", pdfContext, 1);
    POP_NUMBER(pdfContext, charSpace);
    CHECK_PARAMETERS();

    pdfContext->fGraphicsState.fCharSpace = charSpace;

    return kOK_SkPdfResult;
}

//wordSpace Tw Set the word spacing, T
//w
//, to wordSpace, which is a number expressed in unscaled
//text space units. Word spacing is used by the Tj, TJ, and ' operators. Initial
//value: 0.
SkPdfResult PdfOp_Tw(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    EXPECT_OPERANDS("Tw", pdfContext, 1);
    POP_NUMBER(pdfContext, wordSpace);
    CHECK_PARAMETERS();

    pdfContext->fGraphicsState.fWordSpace = wordSpace;

    return kOK_SkPdfResult;
}

//scale Tz Set the horizontal scaling, Th
//, to (scale ˜ 100). scale is a number specifying the
//percentage of the normal width. Initial value: 100 (normal width).
static SkPdfResult PdfOp_Tz(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    EXPECT_OPERANDS("Tz", pdfContext, 1);
    POP_NUMBER(pdfContext, scale);
    CHECK_PARAMETERS();

    if (scale < 0) {
        SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kOutOfRange_SkPdfIssue,
                    "scale must a positive real number", scale_obj, pdfContext);
        return kError_SkPdfResult;
    }

    return kNYI_SkPdfResult;
}

//render Tr Set the text rendering mode, T
//mode, to render, which is an integer. Initial value: 0.
static SkPdfResult PdfOp_Tr(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    EXPECT_OPERANDS("Tr", pdfContext, 1);
    POP_INTEGER(pdfContext, mode);
    CHECK_PARAMETERS();

    if (mode < 0) {  // TODO(edisonn): function/enums with supported modes
        SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kOutOfRange_SkPdfIssue,
                    "mode must a positive integer or 0", mode_obj, pdfContext);
        return kError_SkPdfResult;
    }

    return kNYI_SkPdfResult;
}
//rise Ts Set the text rise, Trise, to rise, which is a number expressed in unscaled text space
//units. Initial value: 0.
static SkPdfResult PdfOp_Ts(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    EXPECT_OPERANDS("Ts", pdfContext, 1);
    POP_NUMBER(pdfContext, rise);
    CHECK_PARAMETERS();

    if (rise < 0) {
        SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kOutOfRange_SkPdfIssue,
                    "rise must a positive real number", rise_obj, pdfContext);
        return kNYI_SkPdfResult;
    }

    return kNYI_SkPdfResult;
}

//wx wy d0
static SkPdfResult PdfOp_d0(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    EXPECT_OPERANDS("d0", pdfContext, 2);
    POP_NUMBER(pdfContext, wy);
    POP_NUMBER(pdfContext, wx);
    CHECK_PARAMETERS();

    if (wx < 0) {
        SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kOutOfRange_SkPdfIssue,
                    "wx must a positive real number", wx_obj, pdfContext);
        return kError_SkPdfResult;
    }

    if (wy < 0) {
        SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kOutOfRange_SkPdfIssue,
                    "wy must a positive real number", wy_obj, pdfContext);
        return kError_SkPdfResult;
    }

    return kNYI_SkPdfResult;
}

//wx wy llx lly urx ury d1
static SkPdfResult PdfOp_d1(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    EXPECT_OPERANDS("d1", pdfContext, 6);
    POP_NUMBER(pdfContext, ury);
    POP_NUMBER(pdfContext, urx);
    POP_NUMBER(pdfContext, lly);
    POP_NUMBER(pdfContext, llx);
    POP_NUMBER(pdfContext, wy);
    POP_NUMBER(pdfContext, wx);
    CHECK_PARAMETERS();

    // TODO(edisonn): really silly quick way to remove warning
    if (wx + wy + llx + lly + urx + ury) {
        return kNYI_SkPdfResult;
    }

    return kNYI_SkPdfResult;
}

//name sh
static SkPdfResult PdfOp_sh(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    EXPECT_OPERANDS("sh", pdfContext, 1);
    POP_NAME(pdfContext, name);
    CHECK_PARAMETERS();

    if (name == NULL) {
        SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, name,
                                  SkPdfNativeObject::kName_PdfObjectType, pdfContext);
        return kError_SkPdfResult;
    }

    return kNYI_SkPdfResult;
}

//name Do
static SkPdfResult PdfOp_Do(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    EXPECT_OPERANDS("Do", pdfContext, 1);
    POP_NAME(pdfContext, name);
    CHECK_PARAMETERS();

    SkPdfDictionary* xObject =  pdfContext->fGraphicsState.fResources->XObject(pdfContext->fPdfDoc);

    if (xObject == NULL) {
        SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kMissingXObject_SkPdfIssue, NULL,
                    pdfContext->fGraphicsState.fResources, pdfContext);
        return kIgnoreError_SkPdfResult;
    }

    SkPdfNativeObject* value = xObject->get(name);
    value = pdfContext->fPdfDoc->resolveReference(value);

    return doXObject(pdfContext, canvas, value);
}

//tag MP Designate a marked-content point. tag is a name object indicating the role or
//signiﬁcance of the point.
static SkPdfResult PdfOp_MP(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    EXPECT_OPERANDS("MP", pdfContext, 1);
    POP_OBJ(pdfContext, tag);
    CHECK_PARAMETERS();

    if (tag == NULL) {
        SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, tag,
                                  SkPdfNativeObject::_kObject_PdfObjectType, pdfContext);
        return kNYI_SkPdfResult;
    }

    SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, "MP NYI", NULL, NULL);
    return kNYI_SkPdfResult;
}

//tag properties DP Designate a marked-content point with an associated property list. tag is a
//name object indicating the role or signiﬁcance of the point; properties is
//either an inline dictionary containing the property list or a name object
//associated with it in the Properties subdictionary of the current resource
//dictionary (see Section 9.5.1, “Property Lists”).
static SkPdfResult PdfOp_DP(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    EXPECT_OPERANDS("DP", pdfContext, 2);
    POP_OBJ(pdfContext, properties);
    POP_OBJ(pdfContext, tag);
    CHECK_PARAMETERS();

    if (tag == NULL) {
        SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, tag,
                                  SkPdfNativeObject::_kObject_PdfObjectType, pdfContext);
        return kNYI_SkPdfResult;
    }

    if (properties == NULL) {
        SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, properties,
                                  SkPdfNativeObject::_kObject_PdfObjectType, pdfContext);
        return kNYI_SkPdfResult;
    }

    SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, "DP NYI", NULL, NULL);
    return kNYI_SkPdfResult;
}

//tag BMC Begin a marked-content sequence terminated by a balancing EMC operator.
//tag is a name object indicating the role or signiﬁcance of the sequence.
static SkPdfResult PdfOp_BMC(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    EXPECT_OPERANDS("BMC", pdfContext, 1);
    POP_OBJ(pdfContext, tag);
    CHECK_PARAMETERS();

    if (tag == NULL) {
        SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, tag,
                                  SkPdfNativeObject::_kObject_PdfObjectType, pdfContext);
        return kNYI_SkPdfResult;
    }

    SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, "BMC NYI", NULL, NULL);
    return kNYI_SkPdfResult;
}

//tag properties BDC Begin a marked-content sequence with an associated property list, terminated
//by a balancing EMCoperator. tag is a name object indicating the role or significance of the
// sequence; propertiesis either an inline dictionary containing the
//property list or a name object associated with it in the Properties subdictionary of the current
//resource dictionary (see Section 9.5.1, “Property Lists”).
static SkPdfResult PdfOp_BDC(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    EXPECT_OPERANDS("BDC", pdfContext, 2);
    POP_OBJ(pdfContext, properties);
    POP_OBJ(pdfContext, tag);
    CHECK_PARAMETERS();

    if (tag == NULL) {
        SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, tag,
                                  SkPdfNativeObject::_kObject_PdfObjectType, pdfContext);
        return kNYI_SkPdfResult;
    }

    if (properties == NULL) {
        SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, properties,
                                  SkPdfNativeObject::_kObject_PdfObjectType, pdfContext);
        return kNYI_SkPdfResult;
    }

    SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, "BDC NYI", NULL, NULL);
    return kNYI_SkPdfResult;
}

//— EMC End a marked-content sequence begun by a BMC or BDC operator.
static SkPdfResult PdfOp_EMC(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) {
    SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, "EMC NYI", NULL, NULL);
    return kNYI_SkPdfResult;
}

#include "SkPdfOps.h"

SkTDict<PdfOperatorRenderer> gPdfOps(100);

static void initPdfOperatorRenderes() {
    static bool gInitialized = false;
    if (gInitialized) {
        return;
    }

    gPdfOps.set("q", PdfOp_q);
    gPdfOps.set("Q", PdfOp_Q);
    gPdfOps.set("cm", PdfOp_cm);

    gPdfOps.set("TD", PdfOp_TD);
    gPdfOps.set("Td", PdfOp_Td);
    gPdfOps.set("Tm", PdfOp_Tm);
    gPdfOps.set("T*", PdfOp_T_star);

    gPdfOps.set("m", PdfOp_m);
    gPdfOps.set("l", PdfOp_l);
    gPdfOps.set("c", PdfOp_c);
    gPdfOps.set("v", PdfOp_v);
    gPdfOps.set("y", PdfOp_y);
    gPdfOps.set("h", PdfOp_h);
    gPdfOps.set("re", PdfOp_re);

    gPdfOps.set("S", PdfOp_S);
    gPdfOps.set("s", PdfOp_s);
    gPdfOps.set("f", PdfOp_f);
    gPdfOps.set("F", PdfOp_F);
    gPdfOps.set("f*", PdfOp_f_star);
    gPdfOps.set("B", PdfOp_B);
    gPdfOps.set("B*", PdfOp_B_star);
    gPdfOps.set("b", PdfOp_b);
    gPdfOps.set("b*", PdfOp_b_star);
    gPdfOps.set("n", PdfOp_n);

    gPdfOps.set("BT", PdfOp_BT);
    gPdfOps.set("ET", PdfOp_ET);

    gPdfOps.set("Tj", PdfOp_Tj);
    gPdfOps.set("'", PdfOp_quote);
    gPdfOps.set("\"", PdfOp_doublequote);
    gPdfOps.set("TJ", PdfOp_TJ);

    gPdfOps.set("CS", PdfOp_CS);
    gPdfOps.set("cs", PdfOp_cs);
    gPdfOps.set("SC", PdfOp_SC);
    gPdfOps.set("SCN", PdfOp_SCN);
    gPdfOps.set("sc", PdfOp_sc);
    gPdfOps.set("scn", PdfOp_scn);
    gPdfOps.set("G", PdfOp_G);
    gPdfOps.set("g", PdfOp_g);
    gPdfOps.set("RG", PdfOp_RG);
    gPdfOps.set("rg", PdfOp_rg);
    gPdfOps.set("K", PdfOp_K);
    gPdfOps.set("k", PdfOp_k);

    gPdfOps.set("W", PdfOp_W);
    gPdfOps.set("W*", PdfOp_W_star);

    gPdfOps.set("BX", PdfOp_BX);
    gPdfOps.set("EX", PdfOp_EX);

    gPdfOps.set("BI", PdfOp_BI);
    gPdfOps.set("ID", PdfOp_ID);
    gPdfOps.set("EI", PdfOp_EI);

    gPdfOps.set("w", PdfOp_w);
    gPdfOps.set("J", PdfOp_J);
    gPdfOps.set("j", PdfOp_j);
    gPdfOps.set("M", PdfOp_M);
    gPdfOps.set("d", PdfOp_d);
    gPdfOps.set("ri", PdfOp_ri);
    gPdfOps.set("i", PdfOp_i);
    gPdfOps.set("gs", PdfOp_gs);

    gPdfOps.set("Tc", PdfOp_Tc);
    gPdfOps.set("Tw", PdfOp_Tw);
    gPdfOps.set("Tz", PdfOp_Tz);
    gPdfOps.set("TL", PdfOp_TL);
    gPdfOps.set("Tf", PdfOp_Tf);
    gPdfOps.set("Tr", PdfOp_Tr);
    gPdfOps.set("Ts", PdfOp_Ts);

    gPdfOps.set("d0", PdfOp_d0);
    gPdfOps.set("d1", PdfOp_d1);

    gPdfOps.set("sh", PdfOp_sh);

    gPdfOps.set("Do", PdfOp_Do);

    gPdfOps.set("MP", PdfOp_MP);
    gPdfOps.set("DP", PdfOp_DP);
    gPdfOps.set("BMC", PdfOp_BMC);
    gPdfOps.set("BDC", PdfOp_BDC);
    gPdfOps.set("EMC", PdfOp_EMC);

    gInitialized = true;
}

class InitPdfOps {
public:
    InitPdfOps() {
        initPdfOperatorRenderes();
    }
};

InitPdfOps gInitPdfOps;

SkPdfResult PdfInlineImageLooper::consumeToken(PdfToken& token) {
    SkASSERT(false);
    return kIgnoreError_SkPdfResult;
}

void PdfInlineImageLooper::loop() {
    // FIXME (scroggo): Does this need to be looper? It does not consumeTokens,
    // nor does it loop. The one thing it does is provide access to the
    // protected members of SkPdfTokenLooper.
    doXObject_Image(fPdfContext, fCanvas, fTokenizer->readInlineImage());
}

SkPdfResult PdfCompatibilitySectionLooper::consumeToken(PdfToken& token) {
    return fParent->consumeToken(token);
}

void PdfCompatibilitySectionLooper::loop() {
    PdfOp_q(fPdfContext, fCanvas, NULL);

    PdfToken token;
    while (fTokenizer->readToken(&token)) {
        if (token.fType == kKeyword_TokenType && strcmp(token.fKeyword, "BX") == 0) {
            PdfCompatibilitySectionLooper looper(this);
            looper.loop();
        } else {
            if (token.fType == kKeyword_TokenType && strcmp(token.fKeyword, "EX") == 0) {
                break;
            }
            fParent->consumeToken(token);
        }
    }

    PdfOp_Q(fPdfContext, fCanvas, NULL);
}

// TODO(edisonn): for debugging - remove or put it in a #ifdef
SkPdfContext* gPdfContext = NULL;

bool SkPdfRenderer::renderPage(int page, SkCanvas* canvas, const SkRect& dst) const {
    if (!fPdfDoc) {
        return false;
    }

    if (page < 0 || page >= pages()) {
        return false;
    }

    SkPdfContext pdfContext(fPdfDoc);

    // FIXME (scroggo): Is this matrix needed?
    pdfContext.fOriginalMatrix = SkMatrix::I();
    pdfContext.fGraphicsState.fResources = fPdfDoc->pageResources(page);

    gPdfContext = &pdfContext;

    SkScalar z = SkIntToScalar(0);
    SkScalar w = dst.width();
    SkScalar h = dst.height();

    if (SkScalarTruncToInt(w) <= 0 || SkScalarTruncToInt(h) <= 0) {
        return true;
    }

    // FIXME (scroggo): The media box may not be anchored at 0,0. Is this okay?
    SkScalar wp = fPdfDoc->MediaBox(page).width();
    SkScalar hp = fPdfDoc->MediaBox(page).height();

    SkPoint pdfSpace[4] = {SkPoint::Make(z, z),
                           SkPoint::Make(wp, z),
                           SkPoint::Make(wp, hp),
                           SkPoint::Make(z, hp)};

#ifdef PDF_DEBUG_3X
    // Use larger image to make sure we do not draw anything outside of page
    // could be used in tests.
    SkPoint skiaSpace[4] = {SkPoint::Make(w+z, h+h),
                            SkPoint::Make(w+w, h+h),
                            SkPoint::Make(w+w, h+z),
                            SkPoint::Make(w+z, h+z)};
#else
    SkPoint skiaSpace[4] = {SkPoint::Make(z, h),
                            SkPoint::Make(w, h),
                            SkPoint::Make(w, z),
                            SkPoint::Make(z, z)};
#endif

    SkAssertResult(pdfContext.fOriginalMatrix.setPolyToPoly(pdfSpace, skiaSpace, 4));
    SkTraceMatrix(pdfContext.fOriginalMatrix, "Original matrix");

    // FIXME (scroggo): Do we need to translate to account for the fact that
    // the media box (or the destination rect) may not be anchored at 0,0?
    pdfContext.fOriginalMatrix.postConcat(canvas->getTotalMatrix());

    pdfContext.fGraphicsState.fCTM = pdfContext.fOriginalMatrix;
    pdfContext.fGraphicsState.fContentStreamMatrix = pdfContext.fOriginalMatrix;
    pdfContext.fGraphicsState.fMatrixTm = pdfContext.fGraphicsState.fCTM;
    pdfContext.fGraphicsState.fMatrixTlm = pdfContext.fGraphicsState.fCTM;

#ifndef PDF_DEBUG_NO_PAGE_CLIPING
    canvas->clipRect(dst, SkRegion::kIntersect_Op, true);
#endif

    // FIXME (scroggo): This concat may not be necessary, since we generally
    // call SkCanvas::setMatrix() before using the canvas.
    canvas->concat(pdfContext.fOriginalMatrix);

    doPage(&pdfContext, canvas, fPdfDoc->page(page));

          // TODO(edisonn:) erase with white before draw? Right now the caller is responsible.
//        SkPaint paint;
//        paint.setColor(SK_ColorWHITE);
//        canvas->drawRect(rect, paint);


    canvas->flush();
    return true;
}

SkPdfRenderer* SkPdfRenderer::CreateFromFile(const char* inputFileName) {
    // FIXME: SkPdfNativeDoc should have a similar Create function.
    SkPdfNativeDoc* pdfDoc = SkNEW_ARGS(SkPdfNativeDoc, (inputFileName));
    if (pdfDoc->pages() == 0) {
        SkDELETE(pdfDoc);
        return NULL;
    }

    return SkNEW_ARGS(SkPdfRenderer, (pdfDoc));
}

SkPdfRenderer* SkPdfRenderer::CreateFromStream(SkStream* stream) {
    // TODO(edisonn): create static function that could return NULL if there are errors
    SkPdfNativeDoc* pdfDoc = SkNEW_ARGS(SkPdfNativeDoc, (stream));
    if (pdfDoc->pages() == 0) {
        SkDELETE(pdfDoc);
        return NULL;
    }

    return SkNEW_ARGS(SkPdfRenderer, (pdfDoc));
}

SkPdfRenderer::SkPdfRenderer(SkPdfNativeDoc* doc)
    :fPdfDoc(doc) {
}

SkPdfRenderer::~SkPdfRenderer() {
    SkDELETE(fPdfDoc);
}

int SkPdfRenderer::pages() const {
    SkASSERT(fPdfDoc != NULL);
    return fPdfDoc->pages();
}

SkRect SkPdfRenderer::MediaBox(int page) const {
    SkASSERT(fPdfDoc != NULL);
    return fPdfDoc->MediaBox(page);
}

size_t SkPdfRenderer::bytesUsed() const {
    SkASSERT(fPdfDoc != NULL);
    return fPdfDoc->bytesUsed();
}

bool SkPDFNativeRenderToBitmap(SkStream* stream,
                               SkBitmap* output,
                               int page,
                               SkPdfContent unused,
                               double dpi) {
    SkASSERT(page >= 0);
    SkPdfRenderer* renderer = SkPdfRenderer::CreateFromStream(stream);
    if (NULL == renderer) {
        return false;
    }

    SkRect rect = renderer->MediaBox(page < 0 ? 0 :page);

    SkScalar width = SkScalarMul(rect.width(),  SkDoubleToScalar(dpi / 72.0));
    SkScalar height = SkScalarMul(rect.height(),  SkDoubleToScalar(dpi / 72.0));

    rect = SkRect::MakeWH(width, height);

    setup_bitmap(output, SkScalarCeilToInt(width), SkScalarCeilToInt(height));

    SkAutoTUnref<SkBaseDevice> device(SkNEW_ARGS(SkBitmapDevice, (*output)));
    SkCanvas canvas(device);

    return renderer->renderPage(page, &canvas, rect);
}
