1131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com/* 2131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com * Copyright 2013 Google Inc. 3131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com * 4131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com * Use of this source code is governed by a BSD-style license that can be 5131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com * found in the LICENSE file. 6131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com */ 7131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 8af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com#include "SkPdfRenderer.h" 9af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com 10e91260c3e75d9d26e391be6823ea37373b27d1ffedisonn@google.com#include "SkBitmapDevice.h" 11131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com#include "SkCanvas.h" 1285a5750ffa71bf595d5e70e14b233d708be24ee9halcanary#include "SkColorPriv.h" 13131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com#include "SkDevice.h" 14131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com#include "SkForceLinking.h" 15131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com#include "SkGraphics.h" 16131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com#include "SkImageDecoder.h" 17131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com#include "SkImageEncoder.h" 18131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com#include "SkOSFile.h" 19131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com#include "SkPicture.h" 20e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com#include "SkPdfFont.h" 21e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com#include "SkPdfGraphicsState.h" 22e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com#include "SkPdfHeaders_autogen.h" 23e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com#include "SkPdfMapper_autogen.h" 24e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com#include "SkPdfNativeTokenizer.h" 25e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com#include "SkPdfRenderer.h" 26e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com#include "SkPdfReporter.h" 27bf6426120a8a9a034f37d37feaf942b1386b7a84scroggo@google.com#include "SkPdfTokenLooper.h" 28e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com#include "SkPdfUtils.h" 29131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com#include "SkStream.h" 30131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com#include "SkTypeface.h" 31131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com#include "SkTArray.h" 322ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com#include "SkTDict.h" 33131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 34e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com// TODO(edisonn): #ifdef these ones, as they are used only for debugging. 353aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.comextern "C" SkPdfContext* gPdfContext; 3615b11182036ba32a732a68982f5eca0b325e0ebeedisonn@google.com 37131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com__SK_FORCE_IMAGE_DECODER_LINKING; 38131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 39e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com// TODO(edisonn): tool, show what objects were read during rendering - will help to identify 40e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com// features with incomplete implementation 41131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com// TODO(edisonn): security - validate all the user input, all pdf! 42e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com// TODO(edisonn): testability -add option to render without text, or only render text 43131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 44e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com// Helper macros to load variables from stack, and automatically check their type. 45af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com#define EXPECT_OPERANDS(name,pdfContext,n) \ 46bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com bool __failed = pdfContext->fObjectStack.count() < n; \ 47af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com SkPdfREPORTCODE(const char* __operator_name = name); \ 48af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com SkPdfREPORTCODE((void)__operator_name); \ 49e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReportIf(pdfContext->fObjectStack.count() < n, \ 50e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com kIgnoreError_SkPdfIssueSeverity, \ 51e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com kStackOverflow_SkPdfIssue, \ 52e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com "Not enought parameters.", NULL, pdfContext); \ 53bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com SkDEBUGCODE(int __cnt = n); 54bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com 55bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com#define POP_OBJ(pdfContext,name) \ 56bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com SkDEBUGCODE(__cnt--); \ 57bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com SkASSERT(__cnt >= 0); \ 58bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com SkPdfNativeObject* name = NULL; \ 59bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com __failed = __failed || pdfContext->fObjectStack.count() == 0; \ 60bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com if (pdfContext->fObjectStack.count() > 0) { \ 61bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com name = pdfContext->fObjectStack.top(); \ 62bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com pdfContext->fObjectStack.pop(); \ 63bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com } 64bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com 65af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com// TODO(edisonn): make all pop function to use name##_obj 66bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com#define POP_NUMBER(pdfContext,name) \ 67bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com SkDEBUGCODE(__cnt--); \ 68bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com SkASSERT(__cnt >= 0); \ 69bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com double name = 0; \ 70af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com SkPdfNativeObject* name##_obj = NULL; \ 71bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com __failed = __failed || pdfContext->fObjectStack.count() == 0; \ 72bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com if (pdfContext->fObjectStack.count() > 0) { \ 73af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com name##_obj = pdfContext->fObjectStack.top(); \ 74bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com pdfContext->fObjectStack.pop(); \ 75af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com if (!name##_obj || !name##_obj->isNumber()) { \ 76e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, \ 77e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com __operator_name, \ 78e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com name##_obj, \ 79e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfNativeObject::_kNumber_PdfObjectType, \ 80e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com NULL);\ 81bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com __failed = true;\ 82bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com } else { \ 83af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com name = name##_obj->numberValue(); \ 84bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com } \ 85bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com } 86bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com 87bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com#define POP_INTEGER(pdfContext,name) \ 88bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com SkDEBUGCODE(__cnt--); \ 89bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com SkASSERT(__cnt >= 0); \ 90bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com int64_t name = 0; \ 91bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com __failed = __failed || pdfContext->fObjectStack.count() == 0; \ 92af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com SkPdfNativeObject* name##_obj = NULL; \ 93bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com if (pdfContext->fObjectStack.count() > 0) { \ 94af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com name##_obj = pdfContext->fObjectStack.top(); \ 95bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com pdfContext->fObjectStack.pop(); \ 96af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com if (!name##_obj || !name##_obj->isInteger()) { \ 97e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, \ 98e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com __operator_name, \ 99e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com name##_obj, \ 100e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfNativeObject::kInteger_PdfObjectType, \ 101e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com NULL);\ 102bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com __failed = true;\ 103bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com } else { \ 104af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com name = name##_obj->intValue(); \ 105bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com } \ 106bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com } 107bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com 108bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com#define POP_NUMBER_INTO(pdfContext,var) \ 109bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com SkDEBUGCODE(__cnt--); \ 110bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com SkASSERT(__cnt >= 0); \ 111bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com __failed = __failed || pdfContext->fObjectStack.count() == 0; \ 112bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com if (pdfContext->fObjectStack.count() > 0) { \ 113bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com SkPdfNativeObject* tmp = pdfContext->fObjectStack.top(); \ 114bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com pdfContext->fObjectStack.pop(); \ 115bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com if (!tmp || !tmp->isNumber()) { \ 116e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, \ 117e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com __operator_name, \ 118e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com tmp, \ 119e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfNativeObject::kInteger_PdfObjectType | \ 120e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfNativeObject::kReal_PdfObjectType, \ 121e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com NULL);\ 122bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com __failed = true;\ 123bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com } else { \ 124bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com var = tmp->numberValue(); \ 125bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com } \ 126bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com } 127bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com 128bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com 129bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com#define POP_NAME(pdfContext,name) \ 130bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com SkDEBUGCODE(__cnt--); \ 131bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com SkASSERT(__cnt >= 0); \ 132bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com SkPdfNativeObject* name = NULL; \ 133bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com __failed = __failed || pdfContext->fObjectStack.count() == 0; \ 134bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com if (pdfContext->fObjectStack.count() > 0) { \ 135bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com SkPdfNativeObject* tmp = pdfContext->fObjectStack.top(); \ 136bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com pdfContext->fObjectStack.pop(); \ 137bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com if (!tmp || !tmp->isName()) { \ 138e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, \ 139e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com __operator_name, \ 140e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com tmp, \ 141e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfNativeObject::kName_PdfObjectType, \ 142e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com NULL);\ 143bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com __failed = true;\ 144bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com } else { \ 145bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com name = tmp; \ 146bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com } \ 147bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com } 148bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com 149bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com#define POP_STRING(pdfContext,name) \ 150bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com SkDEBUGCODE(__cnt--); \ 151bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com SkASSERT(__cnt >= 0); \ 152bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com SkPdfNativeObject* name = NULL; \ 153bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com __failed = __failed || pdfContext->fObjectStack.count() == 0; \ 154bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com if (pdfContext->fObjectStack.count() > 0) { \ 155bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com SkPdfNativeObject* tmp = pdfContext->fObjectStack.top(); \ 156bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com pdfContext->fObjectStack.pop(); \ 157bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com if (!tmp || !tmp->isAnyString()) { \ 158e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, \ 159e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com __operator_name, \ 160e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com tmp, \ 161e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfNativeObject::kString_PdfObjectType | \ 162e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfNativeObject::kHexString_PdfObjectType, \ 163e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com NULL);\ 164bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com __failed = true;\ 165bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com } else { \ 166bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com name = tmp; \ 167bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com } \ 168bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com } 169bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com 170bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com#define POP_ARRAY(pdfContext,name) \ 171bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com SkDEBUGCODE(__cnt--); \ 172bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com SkASSERT(__cnt >= 0); \ 173bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com SkPdfArray* name = NULL; \ 174bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com __failed = __failed || pdfContext->fObjectStack.count() == 0; \ 175bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com if (pdfContext->fObjectStack.count() > 0) { \ 176bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com SkPdfNativeObject* tmp = pdfContext->fObjectStack.top(); \ 177bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com pdfContext->fObjectStack.pop(); \ 178bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com if (!tmp || !tmp->isArray()) { \ 179e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, \ 180e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com __operator_name, \ 181e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com tmp, \ 182e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfNativeObject::kArray_PdfObjectType, \ 183e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com NULL);\ 184bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com __failed = true;\ 185bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com } else { \ 186bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com name = (SkPdfArray*)tmp; \ 187bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com } \ 188bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com } 189bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com 190bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com#define CHECK_PARAMETERS() \ 191bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com SkASSERT(__cnt == 0); \ 192bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com if (__failed) return kIgnoreError_SkPdfResult; 193bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com 194e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com 1952ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.comNotOwnedString strings_DeviceRGB; 1962ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.comNotOwnedString strings_DeviceCMYK; 197222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com 1982ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.comclass StringsInit { 1992ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.compublic: 2002ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com StringsInit() { 2012ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com NotOwnedString::init(&strings_DeviceRGB, "DeviceRGB"); 2022ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com NotOwnedString::init(&strings_DeviceCMYK, "DeviceCMYK"); 2032ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com } 2042ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com}; 2052ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com 206e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com// TODO(edisonn): this will not work in chrome! Find another solution! 2072ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.comStringsInit gStringsInit; 208222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com 209248647cebb3724fd2ce1d41745afb786516af4f8scroggo@google.com// TODO(edisonn): Document SkPdfTokenLooper and subclasses. 210248647cebb3724fd2ce1d41745afb786516af4f8scroggo@google.comclass PdfInlineImageLooper : public SkPdfTokenLooper { 211222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.compublic: 21236026de64400cbe91552c549cf9a906a0926fef3scroggo@google.com explicit PdfInlineImageLooper(SkPdfTokenLooper* parent) 21336026de64400cbe91552c549cf9a906a0926fef3scroggo@google.com : INHERITED(parent) {} 214222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com 21536352bf5e38f45a70ee4f4fc132a38048d38206dmtklein SkPdfResult consumeToken(PdfToken& token) override; 21636352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void loop() override; 21736026de64400cbe91552c549cf9a906a0926fef3scroggo@google.com 21836026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comprivate: 21936026de64400cbe91552c549cf9a906a0926fef3scroggo@google.com typedef SkPdfTokenLooper INHERITED; 220222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com}; 221222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com 222248647cebb3724fd2ce1d41745afb786516af4f8scroggo@google.comclass PdfCompatibilitySectionLooper : public SkPdfTokenLooper { 223222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.compublic: 22436026de64400cbe91552c549cf9a906a0926fef3scroggo@google.com explicit PdfCompatibilitySectionLooper(SkPdfTokenLooper* parent) 22536026de64400cbe91552c549cf9a906a0926fef3scroggo@google.com : INHERITED (parent) {} 22636026de64400cbe91552c549cf9a906a0926fef3scroggo@google.com 22736352bf5e38f45a70ee4f4fc132a38048d38206dmtklein SkPdfResult consumeToken(PdfToken& token) override; 22836352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void loop() override; 229222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com 23036026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comprivate: 23136026de64400cbe91552c549cf9a906a0926fef3scroggo@google.com typedef SkPdfTokenLooper INHERITED; 232222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com}; 233222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com 234131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com// Utilities 235131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.comstatic void setup_bitmap(SkBitmap* bitmap, int width, int height, SkColor color = SK_ColorWHITE) { 2366c22573edb234ad14df947278cfed010669a39a7reed bitmap->allocN32Pixels(width, height); 237131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com bitmap->eraseColor(color); 238131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 239131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 240e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com// TODO(edisonn): synonyms? /DeviceRGB and /RGB mean the same thing. Context dependent. 2412ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.comstatic int GetColorSpaceComponents(NotOwnedString& colorSpace) { 2422ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com if (colorSpace.equals("DeviceCMYK")) { 243131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com return 4; 2442ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com } else if (colorSpace.equals("DeviceGray") || 2452ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com colorSpace.equals("CalGray") || 2462ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com colorSpace.equals("Indexed")) { 247131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com return 1; 2482ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com } else if (colorSpace.equals("DeviceRGB") || 2492ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com colorSpace.equals("CalRGB") || 2502ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com colorSpace.equals("Lab")) { 251131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com return 3; 252131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } else { 253131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com return 0; 254131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 255131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 256131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 2573aac1f9f308192f3787265830fe86ce8874e7382edisonn@google.comSkMatrix SkMatrixFromPdfMatrix(double array[6]) { 258131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com SkMatrix matrix; 259131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com matrix.setAll(SkDoubleToScalar(array[0]), 260131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com SkDoubleToScalar(array[2]), 261131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com SkDoubleToScalar(array[4]), 262131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com SkDoubleToScalar(array[1]), 263131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com SkDoubleToScalar(array[3]), 264131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com SkDoubleToScalar(array[5]), 265131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com SkDoubleToScalar(0), 266131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com SkDoubleToScalar(0), 267131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com SkDoubleToScalar(1)); 268131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 269131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com return matrix; 270131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 271131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 272131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.comSkMatrix SkMatrixFromPdfArray(SkPdfArray* pdfArray) { 273131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com double array[6]; 274131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 275131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com // TODO(edisonn): security issue, ret if size() != 6 276af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com if (pdfArray == NULL) { 277e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kNullObject_SkPdfIssue, 278e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com "null array passed to build matrix", NULL, NULL); 279af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com return SkMatrix::I(); 280af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com } 281af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com 282af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com if (pdfArray->size() != 6) { 283e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kUnexpectedArraySize_SkPdfIssue, 284e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com "null array passed to build matrix", pdfArray, NULL); 285af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com return SkMatrix::I(); 286af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com } 287af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com 288131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com for (int i = 0; i < 6; i++) { 2893aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com const SkPdfNativeObject* elem = pdfArray->operator [](i); 290571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com if (elem == NULL || !elem->isNumber()) { 291e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, elem, 292e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfNativeObject::_kNumber_PdfObjectType, NULL); 293af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com return SkMatrix::I(); 294131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 295571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com array[i] = elem->numberValue(); 296131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 297131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 298131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com return SkMatrixFromPdfMatrix(array); 299131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 300131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 301e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com// TODO(edisonn): debug code, used to analyze rendering when we find bugs. 3023aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.comextern "C" SkPdfNativeDoc* gDoc; 303131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 3043aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.comstatic SkPdfResult DrawText(SkPdfContext* pdfContext, 3053aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com const SkPdfNativeObject* _str, 306131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com SkCanvas* canvas) 307131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com{ 308131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com SkPdfFont* skfont = pdfContext->fGraphicsState.fSkFont; 309131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com if (skfont == NULL) { 310131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com skfont = SkPdfFont::Default(); 311131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 312131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 313571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com if (_str == NULL || !_str->isAnyString()) { 314e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, 315e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com "DrawText", 316e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com _str, 317e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfNativeObject::_kAnyString_PdfObjectType, 318e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com pdfContext); 3193aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kIgnoreError_SkPdfResult; 3203aac1f9f308192f3787265830fe86ce8874e7382edisonn@google.com } 321571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com const SkPdfString* str = (const SkPdfString*)_str; 3223aac1f9f308192f3787265830fe86ce8874e7382edisonn@google.com 323131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com SkUnencodedText binary(str); 324131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 325131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com SkDecodedText decoded; 326131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 327131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com if (skfont->encoding() == NULL) { 328e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kMissingEncoding_SkPdfIssue, 329e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com "draw text", _str, pdfContext); 3303aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kNYI_SkPdfResult; 331131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 332131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 333131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com skfont->encoding()->decodeText(binary, &decoded); 334131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 335131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com SkPaint paint; 336e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com // TODO(edisonn): does size 0 mean anything special? 337131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com if (pdfContext->fGraphicsState.fCurFontSize != 0) { 338131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com paint.setTextSize(SkDoubleToScalar(pdfContext->fGraphicsState.fCurFontSize)); 339131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 340131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 341e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com // TODO(edisonn): implement font scaler 342131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com// if (fCurFont && fCurFont->GetFontScale() != 0) { 3434b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org// paint.setTextScaleX(fCurFont->GetFontScale() / 100.0); 344131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com// } 345131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 346131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com pdfContext->fGraphicsState.applyGraphicsState(&paint, false); 347131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 3486e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com skfont->drawText(decoded, &paint, pdfContext, canvas); 349131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 3503aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kOK_SkPdfResult; 351131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 352131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 353131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com// TODO(edisonn): create header files with declarations! 35436026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comSkPdfResult PdfOp_q(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper* parentLooper); 35536026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comSkPdfResult PdfOp_Q(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper* parentLooper); 35636026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comSkPdfResult PdfOp_Tw(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper* parentLooper); 35736026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comSkPdfResult PdfOp_Tc(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper* parentLooper); 358131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 359131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com// TODO(edisonn): perf!!! 360131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.comstatic SkColorTable* getGrayColortable() { 361131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com static SkColorTable* grayColortable = NULL; 362131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com if (grayColortable == NULL) { 363131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com SkPMColor* colors = new SkPMColor[256]; 364131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com for (int i = 0 ; i < 256; i++) { 365131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com colors[i] = SkPreMultiplyARGB(255, i, i, i); 366131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 367131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com grayColortable = new SkColorTable(colors, 256); 368131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 369131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com return grayColortable; 370131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 371131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 372af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.comstatic SkBitmap* transferImageStreamToBitmap(const unsigned char* uncompressedStream, 373af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com size_t uncompressedStreamLength, 374af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com int width, int height, int bytesPerLine, 375af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com int bpc, const SkString& colorSpace, 376af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com bool transparencyMask) { 377b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com SkBitmap* bitmap = new SkBitmap(); 378131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 379571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com //int components = GetColorSpaceComponents(colorSpace); 380131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com//#define MAX_COMPONENTS 10 381131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 382131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com // TODO(edisonn): assume start of lines are aligned at 32 bits? 383131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com // Is there a faster way to load the uncompressed stream into a bitmap? 384131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 385131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com // minimal support for now 386063d7072ef45971c17045721626b3f0cd052b3b9edisonn@google.com if ((colorSpace.equals("DeviceRGB") || colorSpace.equals("RGB")) && bpc == 8) { 38785a5750ffa71bf595d5e70e14b233d708be24ee9halcanary uint32_t* uncompressedStreamArgb = (SkColor*)malloc(width * height * sizeof(uint32_t)); 388131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 389131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com for (int h = 0 ; h < height; h++) { 390571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com long i = width * (h); 391131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com for (int w = 0 ; w < width; w++) { 39285a5750ffa71bf595d5e70e14b233d708be24ee9halcanary uncompressedStreamArgb[i] = SkPackARGB32(0xFF, 39385a5750ffa71bf595d5e70e14b233d708be24ee9halcanary uncompressedStream[3 * w], 39485a5750ffa71bf595d5e70e14b233d708be24ee9halcanary uncompressedStream[3 * w + 1], 39585a5750ffa71bf595d5e70e14b233d708be24ee9halcanary uncompressedStream[3 * w + 2]); 396131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com i++; 397131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 398131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com uncompressedStream += bytesPerLine; 399131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 400131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 4016c22573edb234ad14df947278cfed010669a39a7reed const SkImageInfo info = SkImageInfo::MakeN32Premul(width, height); 4026c22573edb234ad14df947278cfed010669a39a7reed bitmap->installPixels(info, uncompressedStreamArgb, info.minRowBytes()); 403131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 404063d7072ef45971c17045721626b3f0cd052b3b9edisonn@google.com else if ((colorSpace.equals("DeviceGray") || colorSpace.equals("Gray")) && bpc == 8) { 405131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com unsigned char* uncompressedStreamA8 = (unsigned char*)malloc(width * height); 406131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 407131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com for (int h = 0 ; h < height; h++) { 408571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com long i = width * (h); 409131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com for (int w = 0 ; w < width; w++) { 410131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com uncompressedStreamA8[i] = transparencyMask ? 255 - uncompressedStream[w] : 411131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com uncompressedStream[w]; 412131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com i++; 413131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 414131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com uncompressedStream += bytesPerLine; 415131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 416131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 4176c22573edb234ad14df947278cfed010669a39a7reed const SkColorType ct = transparencyMask ? kAlpha_8_SkColorType : kIndex_8_SkColorType; 4186c22573edb234ad14df947278cfed010669a39a7reed const SkImageInfo info = SkImageInfo::Make(width, height, ct, kPremul_SkAlphaType); 4196c22573edb234ad14df947278cfed010669a39a7reed bitmap->installPixels(info, uncompressedStreamA8, info.minRowBytes(), 4206c22573edb234ad14df947278cfed010669a39a7reed transparencyMask ? NULL : getGrayColortable(), NULL, NULL); 421131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 422131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 423af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com // TODO(edisonn): pass color space and context here? 424af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, "Color space NYI", NULL, NULL); 425131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com return bitmap; 426131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 427131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com// TODO(edisonn): preserve A1 format that skia knows, + fast convert from 111, 222, 444 to closest 428e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com// skia format. 429131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 430e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com// This functions returns the image, it does not look at the smask. 431e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.comstatic SkBitmap* getImageFromObjectCore(SkPdfContext* pdfContext, 432e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfImageDictionary* image, bool transparencyMask) { 433571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com if (image == NULL || !image->hasStream()) { 434e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, "Missing stream", image, 435e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfNativeObject::_kStream_PdfObjectType, pdfContext); 436b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com return NULL; 437131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 438131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 43933f11b6fcdb7dfce27f953803be40fbacedc7450edisonn@google.com int bpc = (int)image->BitsPerComponent(pdfContext->fPdfDoc); 44033f11b6fcdb7dfce27f953803be40fbacedc7450edisonn@google.com int width = (int)image->Width(pdfContext->fPdfDoc); 44133f11b6fcdb7dfce27f953803be40fbacedc7450edisonn@google.com int height = (int)image->Height(pdfContext->fPdfDoc); 442063d7072ef45971c17045721626b3f0cd052b3b9edisonn@google.com SkString colorSpace("DeviceRGB"); 443131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 444b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com bool indexed = false; 445b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com SkPMColor colors[256]; 446b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com int cnt = 0; 447b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com 448571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com if (image->isColorSpaceAName(pdfContext->fPdfDoc)) { 449571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com colorSpace = image->getColorSpaceAsName(pdfContext->fPdfDoc); 450b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com } else if (image->isColorSpaceAArray(pdfContext->fPdfDoc)) { 451b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com SkPdfArray* array = image->getColorSpaceAsArray(pdfContext->fPdfDoc); 452b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com if (array && array->size() == 4 && array->objAtAIndex(0)->isName("Indexed") && 453e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com (array->objAtAIndex(1)->isName("DeviceRGB") || 454e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com array->objAtAIndex(1)->isName("RGB")) && 455b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com array->objAtAIndex(2)->isInteger() && 456b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com array->objAtAIndex(3)->isHexString() 457b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com ) { 458e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, "Color space NYI", 459e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com image, pdfContext); 460b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com indexed = true; 46133f11b6fcdb7dfce27f953803be40fbacedc7450edisonn@google.com cnt = (int)array->objAtAIndex(2)->intValue() + 1; 462b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com if (cnt > 256) { 463e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, 464e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com "Color space feature NYI, cnt > 256", image, pdfContext); 465b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com return NULL; 466b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com } 467b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com NotOwnedString data = array->objAtAIndex(3)->strRef(); 468b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com if (data.fBytes != (unsigned int)cnt * 3) { 469e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kIncostistentSizes_SkPdfIssue, 470e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com "Image color table mismatch color space specs", array, pdfContext); 471b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com return NULL; 472b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com } 473b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com for (int i = 0 ; i < cnt; i++) { 474e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com colors[i] = SkPreMultiplyARGB(0xff, 475e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com data.fBuffer[3 * i], 476e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com data.fBuffer[3 * i + 1], 477e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com data.fBuffer[3 * i + 2]); 478b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com } 479b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com } 480131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 481131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 482e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com // TODO(edisonn): implement image masks. 483e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com/* bool imageMask = image->imageMask(); 484131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com if (imageMask) { 485131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com if (bpc != 0 && bpc != 1) { 486131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com // TODO(edisonn): report warning to be used in testing. 487131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com return SkBitmap(); 488131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 489131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com bpc = 1; 490131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 491131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com*/ 492131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 4932ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com const unsigned char* uncompressedStream = NULL; 494571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com size_t uncompressedStreamLength = 0; 495131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 496571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com SkPdfStream* stream = (SkPdfStream*)image; 4973aac1f9f308192f3787265830fe86ce8874e7382edisonn@google.com 4982ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com if (!stream || !stream->GetFilteredStreamRef(&uncompressedStream, &uncompressedStreamLength) || 4993aac1f9f308192f3787265830fe86ce8874e7382edisonn@google.com uncompressedStream == NULL || uncompressedStreamLength == 0) { 500e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, "Missing stream", stream, 501e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfNativeObject::_kStream_PdfObjectType, pdfContext); 502b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com return NULL; 503131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 504131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 505571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com SkPdfStreamCommonDictionary* streamDict = (SkPdfStreamCommonDictionary*)stream; 506571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 507e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com if (streamDict->has_Filter() && 508e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com ((streamDict->isFilterAName(NULL) && 509e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com streamDict->getFilterAsName(NULL).equals("DCTDecode")) || 510e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com (streamDict->isFilterAArray(NULL) && 511e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com streamDict->getFilterAsArray(NULL)->size() > 0 && 512e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com streamDict->getFilterAsArray(NULL)->objAtAIndex(0)->isName() && 513e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com streamDict->getFilterAsArray(NULL)->objAtAIndex(0)->nameValue2() 514e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com .equals("DCTDecode")))) { 515b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com SkBitmap* bitmap = new SkBitmap(); 516b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com SkImageDecoder::DecodeMemory(uncompressedStream, uncompressedStreamLength, bitmap); 517571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com return bitmap; 518571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 519571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 520e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com // TODO(edisonn): assumes RGB for now, since it is the only one implemented 521b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com if (indexed) { 522b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com SkBitmap* bitmap = new SkBitmap(); 5236c22573edb234ad14df947278cfed010669a39a7reed const SkImageInfo info = SkImageInfo::Make(width, height, kIndex_8_SkColorType, 5246c22573edb234ad14df947278cfed010669a39a7reed kPremul_SkAlphaType); 5256c22573edb234ad14df947278cfed010669a39a7reed SkAutoTUnref<SkColorTable> colorTable(new SkColorTable(colors, cnt)); 5266c22573edb234ad14df947278cfed010669a39a7reed bitmap->installPixels(info, (void*)uncompressedStream, info.minRowBytes(), colorTable, 5276c22573edb234ad14df947278cfed010669a39a7reed NULL, NULL); 528b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com return bitmap; 529b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com } 530b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com 53196ba3aa2faafc609ac275092aa0a4fad4afd749cedisonn@google.com int bytesPerLine = (int)(uncompressedStreamLength / height); 532131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com#ifdef PDF_TRACE 533131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com if (uncompressedStreamLength % height != 0) { 534571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com printf("Warning uncompressedStreamLength modulo height != 0 !!!\n"); 535131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 536131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com#endif 537131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 538b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com SkBitmap* bitmap = transferImageStreamToBitmap( 539131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com (unsigned char*)uncompressedStream, uncompressedStreamLength, 540a3356fce903ff75dc332b53dd3a860ba810b9519edisonn@google.com (int)width, (int)height, bytesPerLine, 541a3356fce903ff75dc332b53dd3a860ba810b9519edisonn@google.com (int)bpc, colorSpace, 542131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com transparencyMask); 543131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 544131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com return bitmap; 545131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 546131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 547e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.comstatic SkBitmap* getImageFromObject(SkPdfContext* pdfContext, SkPdfImageDictionary* image, 548e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com bool transparencyMask) { 549b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com if (!transparencyMask) { 5503aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com if (!image->hasData(SkPdfNativeObject::kBitmap_Data)) { 551b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com SkBitmap* bitmap = getImageFromObjectCore(pdfContext, image, transparencyMask); 5523aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com image->setData(bitmap, SkPdfNativeObject::kBitmap_Data); 553b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com } 5543aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return (SkBitmap*) image->data(SkPdfNativeObject::kBitmap_Data); 555b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com } else { 556b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com return getImageFromObjectCore(pdfContext, image, transparencyMask); 557b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com } 558b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com} 559b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com 5603aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.comstatic SkBitmap* getSmaskFromObject(SkPdfContext* pdfContext, SkPdfImageDictionary* obj) { 561571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com SkPdfImageDictionary* sMask = obj->SMask(pdfContext->fPdfDoc); 562131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 563131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com if (sMask) { 5643aac1f9f308192f3787265830fe86ce8874e7382edisonn@google.com return getImageFromObject(pdfContext, sMask, true); 565131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 566131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 567131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com // TODO(edisonn): implement GS SMask. Default to empty right now. 568e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, 569e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com "implement GS SMask. Default to empty right now.", obj, pdfContext); 570af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com 571131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com return pdfContext->fGraphicsState.fSMask; 572131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 573131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 574e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.comstatic SkPdfResult doXObject_Image(SkPdfContext* pdfContext, SkCanvas* canvas, 575e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfImageDictionary* skpdfimage) { 5763aac1f9f308192f3787265830fe86ce8874e7382edisonn@google.com if (skpdfimage == NULL) { 5773aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kIgnoreError_SkPdfResult; 578131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 579131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 580b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com SkBitmap* image = getImageFromObject(pdfContext, skpdfimage, false); 581b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com SkBitmap* sMask = getSmaskFromObject(pdfContext, skpdfimage); 582131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 583131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com canvas->save(); 584a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com canvas->setMatrix(pdfContext->fGraphicsState.fCTM); 585571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 586571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com SkScalar z = SkIntToScalar(0); 587571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com SkScalar one = SkIntToScalar(1); 588571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 589e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPoint from[4] = {SkPoint::Make(z, z), SkPoint::Make(one, z), 590e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPoint::Make(one, one), SkPoint::Make(z, one)}; 591e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPoint to[4] = {SkPoint::Make(z, one), SkPoint::Make(one, one), 592e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPoint::Make(one, z), SkPoint::Make(z, z)}; 593571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com SkMatrix flip; 594571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com SkAssertResult(flip.setPolyToPoly(from, to, 4)); 595a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com SkMatrix solveImageFlip = pdfContext->fGraphicsState.fCTM; 596571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com solveImageFlip.preConcat(flip); 597571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com canvas->setMatrix(solveImageFlip); 5980f9019008405ad48d73878db9b2d2ee82f90c6bdedisonn@google.com 5990f9019008405ad48d73878db9b2d2ee82f90c6bdedisonn@google.com#ifdef PDF_TRACE 600e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPoint final[4] = {SkPoint::Make(z, z), SkPoint::Make(one, z), 601e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPoint::Make(one, one), SkPoint::Make(z, one)}; 6020f9019008405ad48d73878db9b2d2ee82f90c6bdedisonn@google.com solveImageFlip.mapPoints(final, 4); 6030f9019008405ad48d73878db9b2d2ee82f90c6bdedisonn@google.com printf("IMAGE rect = "); 6040f9019008405ad48d73878db9b2d2ee82f90c6bdedisonn@google.com for (int i = 0; i < 4; i++) { 6050f9019008405ad48d73878db9b2d2ee82f90c6bdedisonn@google.com printf("(%f %f) ", SkScalarToDouble(final[i].x()), SkScalarToDouble(final[i].y())); 6060f9019008405ad48d73878db9b2d2ee82f90c6bdedisonn@google.com } 6070f9019008405ad48d73878db9b2d2ee82f90c6bdedisonn@google.com printf("\n"); 6080f9019008405ad48d73878db9b2d2ee82f90c6bdedisonn@google.com#endif // PDF_TRACE 609571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 610e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkRect dst = SkRect::MakeXYWH(SkDoubleToScalar(0.0), SkDoubleToScalar(0.0), 611e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkDoubleToScalar(1.0), SkDoubleToScalar(1.0)); 612131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 6134ef4bed00efd247a0ea005b95b7239a9d4c14c68edisonn@google.com // TODO(edisonn): soft mask type? alpha/luminosity. 614e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, 615e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com "implement soft mask type", skpdfimage, pdfContext); 616af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com 6172273f9b45fb78b0cc7df81f96f74b0c3c0e6cc37edisonn@google.com SkPaint paint; 6182273f9b45fb78b0cc7df81f96f74b0c3c0e6cc37edisonn@google.com pdfContext->fGraphicsState.applyGraphicsState(&paint, false); 6192273f9b45fb78b0cc7df81f96f74b0c3c0e6cc37edisonn@google.com 620b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com if (!sMask || sMask->empty()) { 6212273f9b45fb78b0cc7df81f96f74b0c3c0e6cc37edisonn@google.com canvas->drawBitmapRect(*image, dst, &paint); 622131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } else { 6232273f9b45fb78b0cc7df81f96f74b0c3c0e6cc37edisonn@google.com canvas->saveLayer(&dst, &paint); 624b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com canvas->drawBitmapRect(*image, dst, NULL); 625131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com SkPaint xfer; 626e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com xfer.setXfermodeMode(SkXfermode::kSrcOut_Mode); 627b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com canvas->drawBitmapRect(*sMask, dst, &xfer); 628131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com canvas->restore(); 629131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 630131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 631131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com canvas->restore(); 632131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 6333aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kPartial_SkPdfResult; 634131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 635131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 636f111a4b6855277bba8dac84cce7ccfa1b3f25d7cedisonn@google.com//TODO(edisonn): options for implementing isolation and knockout 637f111a4b6855277bba8dac84cce7ccfa1b3f25d7cedisonn@google.com// 1) emulate them (current solution) 638f111a4b6855277bba8dac84cce7ccfa1b3f25d7cedisonn@google.com// PRO: simple 639f111a4b6855277bba8dac84cce7ccfa1b3f25d7cedisonn@google.com// CON: will need to use readPixels, which means serious perf issues 640f111a4b6855277bba8dac84cce7ccfa1b3f25d7cedisonn@google.com// 2) Compile a plan for an array of matrixes, compose the result at the end 641f111a4b6855277bba8dac84cce7ccfa1b3f25d7cedisonn@google.com// PRO: might be faster then 1, no need to readPixels 642e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com// CON: multiple drawings (but on smaller areas), pay a price at loading pdf to 643e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com// compute a pdf draw plan 644f111a4b6855277bba8dac84cce7ccfa1b3f25d7cedisonn@google.com// on average, a load with empty draw is 100ms on all the skps we have, for complete sites 645f111a4b6855277bba8dac84cce7ccfa1b3f25d7cedisonn@google.com// 3) support them natively in SkCanvas 646f111a4b6855277bba8dac84cce7ccfa1b3f25d7cedisonn@google.com// PRO: simple 647f111a4b6855277bba8dac84cce7ccfa1b3f25d7cedisonn@google.com// CON: we would still need to use a form of readPixels anyway, so perf might be the same as 1) 648f111a4b6855277bba8dac84cce7ccfa1b3f25d7cedisonn@google.com// 4) compile a plan using pathops, and render once without any fancy rules with backdrop 649f111a4b6855277bba8dac84cce7ccfa1b3f25d7cedisonn@google.com// PRO: simple, fast 650f111a4b6855277bba8dac84cce7ccfa1b3f25d7cedisonn@google.com// CON: pathops must be bug free first + time to compute new paths 651f111a4b6855277bba8dac84cce7ccfa1b3f25d7cedisonn@google.com// pay a price at loading pdf to compute a pdf draw plan 652f111a4b6855277bba8dac84cce7ccfa1b3f25d7cedisonn@google.com// on average, a load with empty draw is 100ms on all the skps we have, for complete sites 653e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com// 5) for knockout, render the objects in reverse order, and add every object to the clip, and any 654e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com// new draw will be cliped 655f111a4b6855277bba8dac84cce7ccfa1b3f25d7cedisonn@google.com 656e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.comstatic void doGroup_before(SkPdfContext* pdfContext, SkCanvas* canvas, SkRect bbox, 657e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfTransparencyGroupDictionary* tgroup, bool page) { 658f111a4b6855277bba8dac84cce7ccfa1b3f25d7cedisonn@google.com SkRect bboxOrig = bbox; 659f111a4b6855277bba8dac84cce7ccfa1b3f25d7cedisonn@google.com SkBitmap backdrop; 660f111a4b6855277bba8dac84cce7ccfa1b3f25d7cedisonn@google.com bool isolatedGroup = tgroup->I(pdfContext->fPdfDoc); 661f111a4b6855277bba8dac84cce7ccfa1b3f25d7cedisonn@google.com// bool knockoutGroup = tgroup->K(pdfContext->fPdfDoc); 662f111a4b6855277bba8dac84cce7ccfa1b3f25d7cedisonn@google.com SkPaint paint; 663f111a4b6855277bba8dac84cce7ccfa1b3f25d7cedisonn@google.com pdfContext->fGraphicsState.applyGraphicsState(&paint, false); 664f111a4b6855277bba8dac84cce7ccfa1b3f25d7cedisonn@google.com canvas->saveLayer(&bboxOrig, isolatedGroup ? &paint : NULL); 665f111a4b6855277bba8dac84cce7ccfa1b3f25d7cedisonn@google.com} 666f111a4b6855277bba8dac84cce7ccfa1b3f25d7cedisonn@google.com 667e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com// TODO(edisonn): non isolation should probably be implemented in skia 668e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com//static void doGroup_after(SkPdfContext* pdfContext, SkCanvas* canvas, SkRect bbox, 669e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com// SkPdfTransparencyGroupDictionary* tgroup) { 670251176ebe92417e956ed696e608939156a68585cedisonn@google.com// if not isolated 671251176ebe92417e956ed696e608939156a68585cedisonn@google.com// canvas->drawBitmapRect(backdrop, bboxOrig, NULL); 672f111a4b6855277bba8dac84cce7ccfa1b3f25d7cedisonn@google.com//} 673f111a4b6855277bba8dac84cce7ccfa1b3f25d7cedisonn@google.com 674e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.comstatic SkPdfResult doXObject_Form(SkPdfContext* pdfContext, SkCanvas* canvas, 675e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfType1FormDictionary* skobj) { 676571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com if (!skobj || !skobj->hasStream()) { 677e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, "Missing stream", skobj, 678e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfNativeObject::_kStream_PdfObjectType, pdfContext); 6793aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kIgnoreError_SkPdfResult; 680131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 681131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 682f111a4b6855277bba8dac84cce7ccfa1b3f25d7cedisonn@google.com if (!skobj->has_BBox()) { 683e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kMissingRequiredKey_SkPdfIssue, "BBox", 684e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com skobj, pdfContext); 6853aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kIgnoreError_SkPdfResult; 686f111a4b6855277bba8dac84cce7ccfa1b3f25d7cedisonn@google.com } 687f111a4b6855277bba8dac84cce7ccfa1b3f25d7cedisonn@google.com 688131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com PdfOp_q(pdfContext, canvas, NULL); 6894ef4bed00efd247a0ea005b95b7239a9d4c14c68edisonn@google.com 690131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 691571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com if (skobj->Resources(pdfContext->fPdfDoc)) { 692571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com pdfContext->fGraphicsState.fResources = skobj->Resources(pdfContext->fPdfDoc); 693131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 694131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 695a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com SkTraceMatrix(pdfContext->fGraphicsState.fCTM, "Current matrix"); 696131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 697571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com if (skobj->has_Matrix()) { 698a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com pdfContext->fGraphicsState.fCTM.preConcat(skobj->Matrix(pdfContext->fPdfDoc)); 699e57c62d039cbd67a4e52776b3e95c5d002b818d2edisonn@google.com SkMatrix matrix = pdfContext->fGraphicsState.fCTM; 700e57c62d039cbd67a4e52776b3e95c5d002b818d2edisonn@google.com matrix.preScale(SkDoubleToScalar(1), SkDoubleToScalar(-1)); 701e57c62d039cbd67a4e52776b3e95c5d002b818d2edisonn@google.com pdfContext->fGraphicsState.fMatrixTm = matrix; 702e57c62d039cbd67a4e52776b3e95c5d002b818d2edisonn@google.com pdfContext->fGraphicsState.fMatrixTlm = matrix; 703e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com // TODO(edisonn): text matrixes mosltly NYI 704131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 705131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 706a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com SkTraceMatrix(pdfContext->fGraphicsState.fCTM, "Total matrix"); 7070f9019008405ad48d73878db9b2d2ee82f90c6bdedisonn@google.com pdfContext->fGraphicsState.fContentStreamMatrix = pdfContext->fGraphicsState.fCTM; 708131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 709a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com canvas->setMatrix(pdfContext->fGraphicsState.fCTM); 710131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 711f111a4b6855277bba8dac84cce7ccfa1b3f25d7cedisonn@google.com SkRect bbox = skobj->BBox(pdfContext->fPdfDoc); 712e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com // TODO(edisonn): constants (AA) from settings. 713e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com canvas->clipRect(bbox, SkRegion::kIntersect_Op, false); 714131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 715e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com // This is a group? 716e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com if (skobj->has_Group()) { 717f111a4b6855277bba8dac84cce7ccfa1b3f25d7cedisonn@google.com SkPdfTransparencyGroupDictionary* tgroup = skobj->Group(pdfContext->fPdfDoc); 718f111a4b6855277bba8dac84cce7ccfa1b3f25d7cedisonn@google.com doGroup_before(pdfContext, canvas, bbox, tgroup, false); 719e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com } 720e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com 721571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com SkPdfStream* stream = (SkPdfStream*)skobj; 7223aac1f9f308192f3787265830fe86ce8874e7382edisonn@google.com 723248647cebb3724fd2ce1d41745afb786516af4f8scroggo@google.com pdfContext->parseStream(stream, canvas); 724131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 725f111a4b6855277bba8dac84cce7ccfa1b3f25d7cedisonn@google.com if (skobj->has_Group()) { 726f111a4b6855277bba8dac84cce7ccfa1b3f25d7cedisonn@google.com canvas->restore(); 727f111a4b6855277bba8dac84cce7ccfa1b3f25d7cedisonn@google.com } 728f111a4b6855277bba8dac84cce7ccfa1b3f25d7cedisonn@google.com 729131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com PdfOp_Q(pdfContext, canvas, NULL); 7303aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kPartial_SkPdfResult; 731131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 732131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 733e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.comstatic SkPdfResult doXObject_Pattern(SkPdfContext* pdfContext, SkCanvas* canvas, 734e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfType1PatternDictionary* skobj) { 735e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com if (!skobj || !skobj->hasStream()) { 736e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, "Missing stream", 737e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com skobj, SkPdfNativeObject::_kStream_PdfObjectType, pdfContext); 7383aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kIgnoreError_SkPdfResult; 739e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com } 740e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com 741e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com if (!skobj->has_BBox()) { 742e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kMissingRequiredKey_SkPdfIssue, "BBox", 743e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com skobj, pdfContext); 7443aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kIgnoreError_SkPdfResult; 745e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com } 746e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com 747e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com PdfOp_q(pdfContext, canvas, NULL); 748e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com 749e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com 750e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com if (skobj->Resources(pdfContext->fPdfDoc)) { 751e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com pdfContext->fGraphicsState.fResources = skobj->Resources(pdfContext->fPdfDoc); 752e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com } 753e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com 7540f9019008405ad48d73878db9b2d2ee82f90c6bdedisonn@google.com SkTraceMatrix(pdfContext->fGraphicsState.fContentStreamMatrix, "Current Content stream matrix"); 755e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com 756e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com if (skobj->has_Matrix()) { 757e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com pdfContext->fGraphicsState.fContentStreamMatrix.preConcat( 758e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com skobj->Matrix(pdfContext->fPdfDoc)); 759e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com } 760e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com 7610f9019008405ad48d73878db9b2d2ee82f90c6bdedisonn@google.com SkTraceMatrix(pdfContext->fGraphicsState.fContentStreamMatrix, "Total Content stream matrix"); 762e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com 7630f9019008405ad48d73878db9b2d2ee82f90c6bdedisonn@google.com canvas->setMatrix(pdfContext->fGraphicsState.fContentStreamMatrix); 7640f9019008405ad48d73878db9b2d2ee82f90c6bdedisonn@google.com pdfContext->fGraphicsState.fCTM = pdfContext->fGraphicsState.fContentStreamMatrix; 765e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com 766e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com SkRect bbox = skobj->BBox(pdfContext->fPdfDoc); 767e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com // TODO(edisonn): constants (AA) from settings. 768e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com canvas->clipRect(bbox, SkRegion::kIntersect_Op, false); 769e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com 770e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com SkPdfStream* stream = (SkPdfStream*)skobj; 771e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com 772248647cebb3724fd2ce1d41745afb786516af4f8scroggo@google.com pdfContext->parseStream(stream, canvas); 773e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com 774e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com PdfOp_Q(pdfContext, canvas, NULL); 7753aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kPartial_SkPdfResult; 776e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com} 777e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com 778e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com// TODO(edisonn): PS NYI 779e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com//static SkPdfResult doXObject_PS(SkPdfContext* pdfContext, SkCanvas* canvas, 780e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com// const SkPdfNativeObject* obj) { 7813aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com// return kNYI_SkPdfResult; 782a3356fce903ff75dc332b53dd3a860ba810b9519edisonn@google.com//} 783131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 784e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.comSkPdfResult doType3Char(SkPdfContext* pdfContext, SkCanvas* canvas, const SkPdfNativeObject* skobj, 785e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkRect bBox, SkMatrix matrix, double textSize) { 786571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com if (!skobj || !skobj->hasStream()) { 787e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, "Missing stream", skobj, 788e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfNativeObject::_kStream_PdfObjectType, pdfContext); 7893aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kIgnoreError_SkPdfResult; 790131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 791131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 792131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com PdfOp_q(pdfContext, canvas, NULL); 793131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 794131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com pdfContext->fGraphicsState.fMatrixTm.preConcat(matrix); 795e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com pdfContext->fGraphicsState.fMatrixTm.preScale(SkDoubleToScalar(textSize), 796e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkDoubleToScalar(textSize)); 797e57c62d039cbd67a4e52776b3e95c5d002b818d2edisonn@google.com pdfContext->fGraphicsState.fMatrixTlm = pdfContext->fGraphicsState.fMatrixTm; 798131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 799a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com pdfContext->fGraphicsState.fCTM = pdfContext->fGraphicsState.fMatrixTm; 800e57c62d039cbd67a4e52776b3e95c5d002b818d2edisonn@google.com pdfContext->fGraphicsState.fCTM.preScale(SkDoubleToScalar(1), SkDoubleToScalar(-1)); 801131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 802a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com SkTraceMatrix(pdfContext->fGraphicsState.fCTM, "Total matrix"); 803131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 804a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com canvas->setMatrix(pdfContext->fGraphicsState.fCTM); 805131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 806131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com SkRect rm = bBox; 807a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com pdfContext->fGraphicsState.fCTM.mapRect(&rm); 808131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 809131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com SkTraceRect(rm, "bbox mapped"); 810131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 811e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com // TODO(edisonn): constants (AA) from settings. 812e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com canvas->clipRect(bBox, SkRegion::kIntersect_Op, false); 813131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 814571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com SkPdfStream* stream = (SkPdfStream*)skobj; 8153aac1f9f308192f3787265830fe86ce8874e7382edisonn@google.com 816248647cebb3724fd2ce1d41745afb786516af4f8scroggo@google.com pdfContext->parseStream(stream, canvas); 817131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 818131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com PdfOp_Q(pdfContext, canvas, NULL); 8193aac1f9f308192f3787265830fe86ce8874e7382edisonn@google.com 8203aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kPartial_SkPdfResult; 821131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 822131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 823e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com// The PDF could be corrupted so a dict refers recursively to the same dict, if this happens 824e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com// we end up with a stack overflow and crash. 825131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.comclass CheckRecursiveRendering { 826063d7072ef45971c17045721626b3f0cd052b3b9edisonn@google.com SkPdfNativeObject* fObj; 827131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.compublic: 828063d7072ef45971c17045721626b3f0cd052b3b9edisonn@google.com CheckRecursiveRendering(SkPdfNativeObject* obj) : fObj(obj) { 829063d7072ef45971c17045721626b3f0cd052b3b9edisonn@google.com SkASSERT(!obj->inRendering()); 830063d7072ef45971c17045721626b3f0cd052b3b9edisonn@google.com obj->startRendering(); 831131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 832131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 833131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com ~CheckRecursiveRendering() { 834063d7072ef45971c17045721626b3f0cd052b3b9edisonn@google.com SkASSERT(fObj->inRendering()); 835063d7072ef45971c17045721626b3f0cd052b3b9edisonn@google.com fObj->doneRendering(); 836131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 837131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 8383aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com static bool IsInRendering(const SkPdfNativeObject* obj) { 839063d7072ef45971c17045721626b3f0cd052b3b9edisonn@google.com return obj->inRendering(); 840131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 841131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com}; 842131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 843063d7072ef45971c17045721626b3f0cd052b3b9edisonn@google.comstatic SkPdfResult doXObject(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfNativeObject* obj) { 844571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com if (CheckRecursiveRendering::IsInRendering(obj)) { 845e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kRecursiveReferencing_SkPdfIssue, 846e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com "Recursive reverencing is invalid in draw objects", obj, pdfContext); 8473aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kIgnoreError_SkPdfResult; 848131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 849131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 850571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com CheckRecursiveRendering checkRecursion(obj); 851131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 852571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com switch (pdfContext->fPdfDoc->mapper()->mapXObjectDictionary(obj)) 853131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com { 8543aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com case kImageDictionary_SkPdfNativeObjectType: 855571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com return doXObject_Image(pdfContext, canvas, (SkPdfImageDictionary*)obj); 8563aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com case kType1FormDictionary_SkPdfNativeObjectType: 857571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com return doXObject_Form(pdfContext, canvas, (SkPdfType1FormDictionary*)obj); 8583aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com //case kObjectDictionaryXObjectPS_SkPdfNativeObjectType: 859131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com //return doXObject_PS(skxobj.asPS()); 860e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com default: { 861e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com if (pdfContext->fPdfDoc->mapper()->mapType1PatternDictionary(obj) != 862e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com kNone_SkPdfNativeObjectType) { 863e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com SkPdfType1PatternDictionary* pattern = (SkPdfType1PatternDictionary*)obj; 864e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com return doXObject_Pattern(pdfContext, canvas, pattern); 865e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com } 866e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, "doXObject", 867e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com obj, pdfContext); 868e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com } 869131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 8703aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kIgnoreError_SkPdfResult; 871131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 872131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 873e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.comstatic SkPdfResult doPage(SkPdfContext* pdfContext, SkCanvas* canvas, 874e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfPageObjectDictionary* skobj) { 875af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com if (!skobj || !skobj->isContentsAStream(pdfContext->fPdfDoc)) { 876e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, "Missing stream", skobj, 877e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfNativeObject::_kStream_PdfObjectType, pdfContext); 8783aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kNYI_SkPdfResult; 87988fc03dd1f47ad33b08d60c47013de860f8fa69fedisonn@google.com } 88088fc03dd1f47ad33b08d60c47013de860f8fa69fedisonn@google.com 88188fc03dd1f47ad33b08d60c47013de860f8fa69fedisonn@google.com SkPdfStream* stream = skobj->getContentsAsStream(pdfContext->fPdfDoc); 88288fc03dd1f47ad33b08d60c47013de860f8fa69fedisonn@google.com 88388fc03dd1f47ad33b08d60c47013de860f8fa69fedisonn@google.com if (!stream) { 884e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, "Missing stream", 885e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com skobj, SkPdfNativeObject::_kStream_PdfObjectType, pdfContext); 8863aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kIgnoreError_SkPdfResult; 88788fc03dd1f47ad33b08d60c47013de860f8fa69fedisonn@google.com } 88888fc03dd1f47ad33b08d60c47013de860f8fa69fedisonn@google.com 889b1de123336246ad970e8a593267c37cc3be8105cscroggo@google.com // FIXME (scroggo): renderPage also sets fResources. Are these redundant? 89073613c16e154f08d01de98f03a3b10c474d5c9fbedisonn@google.com pdfContext->fGraphicsState.fResources = skobj->Resources(pdfContext->fPdfDoc); 89173613c16e154f08d01de98f03a3b10c474d5c9fbedisonn@google.com 89273613c16e154f08d01de98f03a3b10c474d5c9fbedisonn@google.com if (!pdfContext->fGraphicsState.fResources) { 893e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com // It might be null because we have not implemented yet inheritance. 894e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com return kIgnoreError_SkPdfResult; 89573613c16e154f08d01de98f03a3b10c474d5c9fbedisonn@google.com } 89673613c16e154f08d01de98f03a3b10c474d5c9fbedisonn@google.com 89788fc03dd1f47ad33b08d60c47013de860f8fa69fedisonn@google.com if (CheckRecursiveRendering::IsInRendering(skobj)) { 898e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kRecursiveReferencing_SkPdfIssue, 899e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com "Recursive reverencing is invalid in draw objects", skobj, pdfContext); 9003aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kIgnoreError_SkPdfResult; 90188fc03dd1f47ad33b08d60c47013de860f8fa69fedisonn@google.com } 90288fc03dd1f47ad33b08d60c47013de860f8fa69fedisonn@google.com CheckRecursiveRendering checkRecursion(skobj); 90388fc03dd1f47ad33b08d60c47013de860f8fa69fedisonn@google.com 90488fc03dd1f47ad33b08d60c47013de860f8fa69fedisonn@google.com 905b1de123336246ad970e8a593267c37cc3be8105cscroggo@google.com // FIXME (scroggo): Is this save necessary? May be needed for rendering a nested PDF. 90688fc03dd1f47ad33b08d60c47013de860f8fa69fedisonn@google.com PdfOp_q(pdfContext, canvas, NULL); 90788fc03dd1f47ad33b08d60c47013de860f8fa69fedisonn@google.com 908f111a4b6855277bba8dac84cce7ccfa1b3f25d7cedisonn@google.com // TODO(edisonn): MediaBox can be inherited!!!! 909e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, "MediaBox inheritance NYI", 910e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com NULL, pdfContext); 911f111a4b6855277bba8dac84cce7ccfa1b3f25d7cedisonn@google.com SkRect bbox = skobj->MediaBox(pdfContext->fPdfDoc); 91288fc03dd1f47ad33b08d60c47013de860f8fa69fedisonn@google.com if (skobj->has_Group()) { 913f111a4b6855277bba8dac84cce7ccfa1b3f25d7cedisonn@google.com SkPdfTransparencyGroupDictionary* tgroup = skobj->Group(pdfContext->fPdfDoc); 914f111a4b6855277bba8dac84cce7ccfa1b3f25d7cedisonn@google.com doGroup_before(pdfContext, canvas, bbox, tgroup, true); 915f111a4b6855277bba8dac84cce7ccfa1b3f25d7cedisonn@google.com } else { 916f111a4b6855277bba8dac84cce7ccfa1b3f25d7cedisonn@google.com canvas->save(); 91788fc03dd1f47ad33b08d60c47013de860f8fa69fedisonn@google.com } 91888fc03dd1f47ad33b08d60c47013de860f8fa69fedisonn@google.com 919248647cebb3724fd2ce1d41745afb786516af4f8scroggo@google.com pdfContext->parseStream(stream, canvas); 92088fc03dd1f47ad33b08d60c47013de860f8fa69fedisonn@google.com 92188fc03dd1f47ad33b08d60c47013de860f8fa69fedisonn@google.com canvas->restore(); 92288fc03dd1f47ad33b08d60c47013de860f8fa69fedisonn@google.com PdfOp_Q(pdfContext, canvas, NULL); 9233aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kPartial_SkPdfResult; 92488fc03dd1f47ad33b08d60c47013de860f8fa69fedisonn@google.com} 92588fc03dd1f47ad33b08d60c47013de860f8fa69fedisonn@google.com 92636026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comSkPdfResult PdfOp_q(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 927131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com pdfContext->fStateStack.push(pdfContext->fGraphicsState); 928131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com canvas->save(); 929f68aed33819cbc98a95edeadde1da9303eca7fb2edisonn@google.com pdfContext->fObjectStack.nest(); 9303aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kOK_SkPdfResult; 931131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 932131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 93336026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comSkPdfResult PdfOp_Q(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 934f68aed33819cbc98a95edeadde1da9303eca7fb2edisonn@google.com if (pdfContext->fStateStack.count() > 0) { 935f68aed33819cbc98a95edeadde1da9303eca7fb2edisonn@google.com pdfContext->fGraphicsState = pdfContext->fStateStack.top(); 936f68aed33819cbc98a95edeadde1da9303eca7fb2edisonn@google.com pdfContext->fStateStack.pop(); 937f68aed33819cbc98a95edeadde1da9303eca7fb2edisonn@google.com canvas->restore(); 938f68aed33819cbc98a95edeadde1da9303eca7fb2edisonn@google.com 9397d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com if (pdfContext->fObjectStack.nestingLevel() == 0) { 940e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kStackNestingOverflow_SkPdfIssue, 941e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com "stack nesting overflow (q/Q)", NULL, pdfContext); 942f68aed33819cbc98a95edeadde1da9303eca7fb2edisonn@google.com return kIgnoreError_SkPdfResult; 943f68aed33819cbc98a95edeadde1da9303eca7fb2edisonn@google.com } else { 944f68aed33819cbc98a95edeadde1da9303eca7fb2edisonn@google.com pdfContext->fObjectStack.unnest(); 945f68aed33819cbc98a95edeadde1da9303eca7fb2edisonn@google.com } 946f68aed33819cbc98a95edeadde1da9303eca7fb2edisonn@google.com } else { 947e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kStackOverflow_SkPdfIssue, 948e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com "stack overflow (q/Q)", NULL, pdfContext); 949f68aed33819cbc98a95edeadde1da9303eca7fb2edisonn@google.com return kIgnoreError_SkPdfResult; 950f68aed33819cbc98a95edeadde1da9303eca7fb2edisonn@google.com } 951f68aed33819cbc98a95edeadde1da9303eca7fb2edisonn@google.com 9523aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kOK_SkPdfResult; 953131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 954131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 95536026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_cm(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 956af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com EXPECT_OPERANDS("cm", pdfContext, 6); 957bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, f); 958bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, e); 959bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, d); 960bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, c); 961bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, b); 962bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, a); 963bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com CHECK_PARAMETERS(); 964bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com double array[6] = {a, b, c, d, e, f}; 965131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 966131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com // a b 967131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com // c d 968131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com // e f 969131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 970131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com // 0 1 971131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com // 2 3 972131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com // 4 5 973131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 974131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com // sx ky 975131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com // kx sy 976131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com // tx ty 977131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com SkMatrix matrix = SkMatrixFromPdfMatrix(array); 978131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 979a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com pdfContext->fGraphicsState.fCTM.preConcat(matrix); 980131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 981131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com#ifdef PDF_TRACE 982131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com printf("cm "); 983131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com for (int i = 0 ; i < 6 ; i++) { 984131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com printf("%f ", array[i]); 985131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 986131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com printf("\n"); 987a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com SkTraceMatrix(pdfContext->fGraphicsState.fCTM, "cm"); 988131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com#endif 989131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 9903aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kOK_SkPdfResult; 991131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 992131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 993131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com//leading TL Set the text leading, Tl 994131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com//, to leading, which is a number expressed in unscaled text 995131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com//space units. Text leading is used only by the T*, ', and " operators. Initial value: 0. 99636026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_TL(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 997af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com EXPECT_OPERANDS("TL", pdfContext, 1); 998bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, ty); 999bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com CHECK_PARAMETERS(); 1000131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1001131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com pdfContext->fGraphicsState.fTextLeading = ty; 1002131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 10033aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kOK_SkPdfResult; 1004131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 1005131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 100636026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_Td(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 1007af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com EXPECT_OPERANDS("Td", pdfContext, 2); 1008bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, ty); 1009bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, tx); 1010bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com CHECK_PARAMETERS(); 1011131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1012e57c62d039cbd67a4e52776b3e95c5d002b818d2edisonn@google.com double array[6] = {1, 0, 0, 1, tx, -ty}; 1013131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com SkMatrix matrix = SkMatrixFromPdfMatrix(array); 1014131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1015131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com pdfContext->fGraphicsState.fMatrixTm.preConcat(matrix); 1016131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com pdfContext->fGraphicsState.fMatrixTlm.preConcat(matrix); 1017131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 10183aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kPartial_SkPdfResult; 1019131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 1020131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 102136026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_TD(SkPdfContext* pdfContext, SkCanvas* canvas, 102236026de64400cbe91552c549cf9a906a0926fef3scroggo@google.com SkPdfTokenLooper* parentLooper) { 1023af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com EXPECT_OPERANDS("TD", pdfContext, 2) 1024bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, ty); 1025bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, tx); 1026bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com CHECK_PARAMETERS(); 1027131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1028571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com // TODO(edisonn): Create factory methods or constructors so native is hidden 1029571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com SkPdfReal* _ty = pdfContext->fPdfDoc->createReal(-ty); 10303aac1f9f308192f3787265830fe86ce8874e7382edisonn@google.com pdfContext->fObjectStack.push(_ty); 1031131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 103236026de64400cbe91552c549cf9a906a0926fef3scroggo@google.com PdfOp_TL(pdfContext, canvas, parentLooper); 1033131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1034571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com SkPdfReal* vtx = pdfContext->fPdfDoc->createReal(tx); 10353aac1f9f308192f3787265830fe86ce8874e7382edisonn@google.com pdfContext->fObjectStack.push(vtx); 10363aac1f9f308192f3787265830fe86ce8874e7382edisonn@google.com 1037571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com SkPdfReal* vty = pdfContext->fPdfDoc->createReal(ty); 10383aac1f9f308192f3787265830fe86ce8874e7382edisonn@google.com pdfContext->fObjectStack.push(vty); 10393aac1f9f308192f3787265830fe86ce8874e7382edisonn@google.com 104036026de64400cbe91552c549cf9a906a0926fef3scroggo@google.com SkPdfResult ret = PdfOp_Td(pdfContext, canvas, parentLooper); 1041131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 10423aac1f9f308192f3787265830fe86ce8874e7382edisonn@google.com return ret; 1043131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 1044131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 104536026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_Tm(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 1046af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com EXPECT_OPERANDS("Tm", pdfContext, 6); 1047bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, f); 1048bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, e); 1049bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, d); 1050bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, c); 1051bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, b); 1052bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, a); 1053bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com CHECK_PARAMETERS(); 1054131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1055131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com double array[6]; 1056131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com array[0] = a; 1057131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com array[1] = b; 1058131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com array[2] = c; 1059131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com array[3] = d; 1060131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com array[4] = e; 1061131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com array[5] = f; 1062131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1063131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com SkMatrix matrix = SkMatrixFromPdfMatrix(array); 1064a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com matrix.postConcat(pdfContext->fGraphicsState.fCTM); 1065e57c62d039cbd67a4e52776b3e95c5d002b818d2edisonn@google.com matrix.preScale(SkDoubleToScalar(1), SkDoubleToScalar(-1)); 1066131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1067e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com // TODO(edisonn): NYI - Text positioning. 1068e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, 1069e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com "Text positioning not implemented for 2+ chars", NULL, pdfContext); 1070af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com 1071131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com pdfContext->fGraphicsState.fMatrixTm = matrix; 1072567ff2f6143ecb993dbedede402a43feb71c420atfarina pdfContext->fGraphicsState.fMatrixTlm = matrix; 1073131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 10743aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kPartial_SkPdfResult; 1075131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 1076131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1077131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com//— T* Move to the start of the next line. This operator has the same effect as the code 1078131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com//0 Tl Td 1079131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com//where Tl is the current leading parameter in the text state 1080e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.comstatic SkPdfResult PdfOp_T_star(SkPdfContext* pdfContext, SkCanvas* canvas, 108136026de64400cbe91552c549cf9a906a0926fef3scroggo@google.com SkPdfTokenLooper* parentLooper) { 1082571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com SkPdfReal* zero = pdfContext->fPdfDoc->createReal(0.0); 1083571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com SkPdfReal* tl = pdfContext->fPdfDoc->createReal(pdfContext->fGraphicsState.fTextLeading); 10843aac1f9f308192f3787265830fe86ce8874e7382edisonn@google.com 10853aac1f9f308192f3787265830fe86ce8874e7382edisonn@google.com pdfContext->fObjectStack.push(zero); 10863aac1f9f308192f3787265830fe86ce8874e7382edisonn@google.com pdfContext->fObjectStack.push(tl); 10873aac1f9f308192f3787265830fe86ce8874e7382edisonn@google.com 108836026de64400cbe91552c549cf9a906a0926fef3scroggo@google.com SkPdfResult ret = PdfOp_Td(pdfContext, canvas, parentLooper); 1089131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 10903aac1f9f308192f3787265830fe86ce8874e7382edisonn@google.com return ret; 1091131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 1092131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 109336026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_m(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 1094131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com if (pdfContext->fGraphicsState.fPathClosed) { 1095131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com pdfContext->fGraphicsState.fPath.reset(); 1096131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com pdfContext->fGraphicsState.fPathClosed = false; 1097131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 1098131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1099af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com EXPECT_OPERANDS("m", pdfContext, 2); 1100bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, y); 1101bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, x); 1102bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com CHECK_PARAMETERS(); 1103bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com 1104bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com pdfContext->fGraphicsState.fCurPosY = y; 1105bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com pdfContext->fGraphicsState.fCurPosX = x; 1106131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1107131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com pdfContext->fGraphicsState.fPath.moveTo(SkDoubleToScalar(pdfContext->fGraphicsState.fCurPosX), 1108bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com SkDoubleToScalar(pdfContext->fGraphicsState.fCurPosY)); 1109131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 11103aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kOK_SkPdfResult; 1111131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 1112131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 111336026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_l(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 1114131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com if (pdfContext->fGraphicsState.fPathClosed) { 1115131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com pdfContext->fGraphicsState.fPath.reset(); 1116131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com pdfContext->fGraphicsState.fPathClosed = false; 1117131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 1118131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1119af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com EXPECT_OPERANDS("l", pdfContext, 2); 1120bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, y); 1121bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, x); 1122bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com CHECK_PARAMETERS(); 1123bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com 1124bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com pdfContext->fGraphicsState.fCurPosY = y; 1125bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com pdfContext->fGraphicsState.fCurPosX = x; 1126131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1127131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com pdfContext->fGraphicsState.fPath.lineTo(SkDoubleToScalar(pdfContext->fGraphicsState.fCurPosX), 1128bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com SkDoubleToScalar(pdfContext->fGraphicsState.fCurPosY)); 1129131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 11303aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kOK_SkPdfResult; 1131131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 1132131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 113336026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_c(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 1134131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com if (pdfContext->fGraphicsState.fPathClosed) { 1135131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com pdfContext->fGraphicsState.fPath.reset(); 1136131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com pdfContext->fGraphicsState.fPathClosed = false; 1137131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 1138131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1139af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com EXPECT_OPERANDS("c", pdfContext, 6); 1140bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, y3); 1141bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, x3); 1142bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, y2); 1143bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, x2); 1144bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, y1); 1145bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, x1); 1146bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com CHECK_PARAMETERS(); 1147131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1148131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com pdfContext->fGraphicsState.fPath.cubicTo(SkDoubleToScalar(x1), SkDoubleToScalar(y1), 1149bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com SkDoubleToScalar(x2), SkDoubleToScalar(y2), 1150bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com SkDoubleToScalar(x3), SkDoubleToScalar(y3)); 1151131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1152131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com pdfContext->fGraphicsState.fCurPosX = x3; 1153131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com pdfContext->fGraphicsState.fCurPosY = y3; 1154131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 11553aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kOK_SkPdfResult; 1156131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 1157131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 115836026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_v(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 1159131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com if (pdfContext->fGraphicsState.fPathClosed) { 1160131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com pdfContext->fGraphicsState.fPath.reset(); 1161131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com pdfContext->fGraphicsState.fPathClosed = false; 1162131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 1163131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1164af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com EXPECT_OPERANDS("v", pdfContext, 4); 1165bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, y3); 1166bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, x3); 1167bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, y2); 1168bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, x2); 1169bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com CHECK_PARAMETERS(); 1170bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com 1171131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com double y1 = pdfContext->fGraphicsState.fCurPosY; 1172131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com double x1 = pdfContext->fGraphicsState.fCurPosX; 1173131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1174131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com pdfContext->fGraphicsState.fPath.cubicTo(SkDoubleToScalar(x1), SkDoubleToScalar(y1), 1175bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com SkDoubleToScalar(x2), SkDoubleToScalar(y2), 1176bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com SkDoubleToScalar(x3), SkDoubleToScalar(y3)); 1177131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1178131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com pdfContext->fGraphicsState.fCurPosX = x3; 1179131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com pdfContext->fGraphicsState.fCurPosY = y3; 1180131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 11813aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kOK_SkPdfResult; 1182131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 1183131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 118436026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_y(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 1185131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com if (pdfContext->fGraphicsState.fPathClosed) { 1186131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com pdfContext->fGraphicsState.fPath.reset(); 1187131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com pdfContext->fGraphicsState.fPathClosed = false; 1188131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 1189131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1190af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com EXPECT_OPERANDS("y", pdfContext, 4); 1191bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, y3); 1192bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, x3); 1193bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, y1); 1194bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, x1); 1195bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com CHECK_PARAMETERS(); 1196bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com 1197131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com double y2 = pdfContext->fGraphicsState.fCurPosY; 1198131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com double x2 = pdfContext->fGraphicsState.fCurPosX; 1199131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1200131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com pdfContext->fGraphicsState.fPath.cubicTo(SkDoubleToScalar(x1), SkDoubleToScalar(y1), 1201bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com SkDoubleToScalar(x2), SkDoubleToScalar(y2), 1202bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com SkDoubleToScalar(x3), SkDoubleToScalar(y3)); 1203131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1204131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com pdfContext->fGraphicsState.fCurPosX = x3; 1205131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com pdfContext->fGraphicsState.fCurPosY = y3; 1206131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 12073aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kOK_SkPdfResult; 1208131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 1209131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 121036026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_re(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 1211131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com if (pdfContext->fGraphicsState.fPathClosed) { 1212131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com pdfContext->fGraphicsState.fPath.reset(); 1213131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com pdfContext->fGraphicsState.fPathClosed = false; 1214131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 1215131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1216af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com EXPECT_OPERANDS("re", pdfContext, 4); 1217bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, height); 1218bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, width); 1219bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, y); 1220bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, x); 1221bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com CHECK_PARAMETERS(); 1222131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1223e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com pdfContext->fGraphicsState.fPath.addRect(SkDoubleToScalar(x), 1224e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkDoubleToScalar(y), 1225e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkDoubleToScalar(x + width), 1226e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkDoubleToScalar(y + height)); 1227131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1228131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com pdfContext->fGraphicsState.fCurPosX = x; 1229131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com pdfContext->fGraphicsState.fCurPosY = y + height; 1230131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 12313aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kOK_SkPdfResult; 1232131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 1233131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 123436026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_h(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 1235131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com pdfContext->fGraphicsState.fPath.close(); 12363aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kOK_SkPdfResult; 1237131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 1238131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1239e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.comstatic SkPdfResult PdfOp_fillAndStroke(SkPdfContext* pdfContext, SkCanvas* canvas, 1240e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com bool fill, bool stroke, bool close, bool evenOdd) { 1241131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com SkPath path = pdfContext->fGraphicsState.fPath; 1242131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1243131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com if (close) { 1244131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com path.close(); 1245131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 1246131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1247a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com canvas->setMatrix(pdfContext->fGraphicsState.fCTM); 1248131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1249131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com SkPaint paint; 1250131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1251131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com SkPoint line[2]; 1252131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com if (fill && !stroke && path.isLine(line)) { 1253131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com paint.setStyle(SkPaint::kStroke_Style); 1254131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1255e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com // TODO(edisonn): implement this with patterns 1256131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com pdfContext->fGraphicsState.applyGraphicsState(&paint, false); 1257131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com paint.setStrokeWidth(SkDoubleToScalar(0)); 1258131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1259131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com canvas->drawPath(path, paint); 1260131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } else { 1261131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com if (fill) { 1262e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com if (strncmp((char*)pdfContext->fGraphicsState.fNonStroking.fColorSpace.fBuffer, 1263e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com "Pattern", strlen("Pattern")) == 0 && 1264e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com pdfContext->fGraphicsState.fNonStroking.fPattern != NULL) { 1265e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com 1266e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com // TODO(edisonn): we can use a shader here, like imageshader to draw fast. 1267131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1268e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com PdfOp_q(pdfContext, canvas, NULL); 1269131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1270e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com if (evenOdd) { 1271e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com path.setFillType(SkPath::kEvenOdd_FillType); 1272e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com } 1273e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com canvas->clipPath(path); 1274e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com 1275e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com if (pdfContext->fPdfDoc 1276e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com ->mapper() 1277e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com ->mapType1PatternDictionary(pdfContext->fGraphicsState 1278e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com .fNonStroking 1279e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com .fPattern) 1280e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com != kNone_SkPdfNativeObjectType) { 1281e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfType1PatternDictionary* pattern 1282e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com = (SkPdfType1PatternDictionary*)pdfContext->fGraphicsState 1283e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com .fNonStroking 1284e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com .fPattern; 1285e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com 1286e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com // TODO(edisonn): make PaintType constants 1287e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com if (pattern->PaintType(pdfContext->fPdfDoc) == 1) { 1288b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com // TODO(edisonn): don't use abs, iterate as asked, if the cells intersect 1289b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com // it will change the result iterating in reverse 1290e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com // remove then the following bounds.sort(); 1291b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com int xStep = abs((int)pattern->XStep(pdfContext->fPdfDoc)); 1292b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com int yStep = abs((int)pattern->YStep(pdfContext->fPdfDoc)); 1293e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com 1294e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, 1295e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com "paterns x/y step is forced to positive number", 1296e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com pattern, pdfContext); 1297af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com 1298e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com SkRect bounds = path.getBounds(); 1299b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com bounds.sort(); 1300b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com 1301b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com SkScalar x; 1302b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com SkScalar y; 1303e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com 1304e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com y = bounds.top(); 1305e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com int totalx = 0; 1306e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com int totaly = 0; 1307e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com while (y < bounds.bottom()) { 1308e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com x = bounds.left(); 1309e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com totalx = 0; 1310e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com 1311e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com while (x < bounds.right()) { 1312e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com doXObject(pdfContext, canvas, pattern); 1313e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com 1314e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com pdfContext->fGraphicsState.fContentStreamMatrix.preTranslate( 1315e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkIntToScalar(xStep), SkIntToScalar(0)); 1316e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com totalx += xStep; 1317e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com x += SkIntToScalar(xStep); 1318e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com } 1319e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com pdfContext->fGraphicsState.fContentStreamMatrix.preTranslate( 1320e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkIntToScalar(-totalx), SkIntToScalar(0)); 1321e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com 1322e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com pdfContext->fGraphicsState.fContentStreamMatrix.preTranslate( 1323e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkIntToScalar(0), SkIntToScalar(-yStep)); 1324e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com totaly += yStep; 1325e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com y += SkIntToScalar(yStep); 1326e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com } 1327e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com pdfContext->fGraphicsState.fContentStreamMatrix.preTranslate( 1328e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkIntToScalar(0), SkIntToScalar(totaly)); 1329e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com } 1330e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com } 1331e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com 1332e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com PdfOp_Q(pdfContext, canvas, NULL); 1333e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com } else { 1334e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com paint.setStyle(SkPaint::kFill_Style); 1335e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com if (evenOdd) { 1336e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com path.setFillType(SkPath::kEvenOdd_FillType); 1337e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com } 1338e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com 1339e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com pdfContext->fGraphicsState.applyGraphicsState(&paint, false); 1340e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com 1341e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com canvas->drawPath(path, paint); 1342e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com } 1343131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 1344131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1345131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com if (stroke) { 1346e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com if (false && strncmp((char*)pdfContext->fGraphicsState.fNonStroking.fColorSpace.fBuffer, 1347e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com "Pattern", strlen("Pattern")) == 0) { 1348e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com // TODO(edisonn): implement Pattern for strokes 1349e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com paint.setStyle(SkPaint::kStroke_Style); 1350e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com 1351e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com paint.setColor(SK_ColorGREEN); 1352e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com 1353e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com // reset it, just in case it messes up the stroke 1354e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com path.setFillType(SkPath::kWinding_FillType); 1355e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com canvas->drawPath(path, paint); 1356e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com } else { 1357e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com paint.setStyle(SkPaint::kStroke_Style); 1358131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1359e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com pdfContext->fGraphicsState.applyGraphicsState(&paint, true); 1360131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1361e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com // reset it, just in case it messes up the stroke 1362e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com path.setFillType(SkPath::kWinding_FillType); 1363e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com canvas->drawPath(path, paint); 1364e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com } 1365131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 1366131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 1367131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1368131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com pdfContext->fGraphicsState.fPath.reset(); 1369e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com // TODO(edisonn): implement scale/zoom 1370131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1371131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com if (pdfContext->fGraphicsState.fHasClipPathToApply) { 1372131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com#ifndef PDF_DEBUG_NO_CLIPING 1373131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com canvas->clipPath(pdfContext->fGraphicsState.fClipPath, SkRegion::kIntersect_Op, true); 1374131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com#endif 1375131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 1376131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1377131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com //pdfContext->fGraphicsState.fClipPath.reset(); 1378131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com pdfContext->fGraphicsState.fHasClipPathToApply = false; 1379131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 13803aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kOK_SkPdfResult; 1381131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1382131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 1383131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 138436026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_S(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 1385131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com return PdfOp_fillAndStroke(pdfContext, canvas, false, true, false, false); 1386131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 1387131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 138836026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_s(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 1389131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com return PdfOp_fillAndStroke(pdfContext, canvas, false, true, true, false); 1390131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 1391131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 139236026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_F(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 1393131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com return PdfOp_fillAndStroke(pdfContext, canvas, true, false, false, false); 1394131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 1395131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 139636026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_f(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 1397131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com return PdfOp_fillAndStroke(pdfContext, canvas, true, false, false, false); 1398131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 1399131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1400e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.comstatic SkPdfResult PdfOp_f_star(SkPdfContext* pdfContext, SkCanvas* canvas, 140136026de64400cbe91552c549cf9a906a0926fef3scroggo@google.com SkPdfTokenLooper*) { 1402131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com return PdfOp_fillAndStroke(pdfContext, canvas, true, false, false, true); 1403131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 1404131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 140536026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_B(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 1406131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com return PdfOp_fillAndStroke(pdfContext, canvas, true, true, false, false); 1407131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 1408131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1409e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.comstatic SkPdfResult PdfOp_B_star(SkPdfContext* pdfContext, SkCanvas* canvas, 141036026de64400cbe91552c549cf9a906a0926fef3scroggo@google.com SkPdfTokenLooper*) { 1411131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com return PdfOp_fillAndStroke(pdfContext, canvas, true, true, false, true); 1412131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 1413131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 141436026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_b(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 1415131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com return PdfOp_fillAndStroke(pdfContext, canvas, true, true, true, false); 1416131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 1417131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1418e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.comstatic SkPdfResult PdfOp_b_star(SkPdfContext* pdfContext, SkCanvas* canvas, 141936026de64400cbe91552c549cf9a906a0926fef3scroggo@google.com SkPdfTokenLooper*) { 1420131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com return PdfOp_fillAndStroke(pdfContext, canvas, true, true, true, true); 1421131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 1422131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 142336026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_n(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 1424a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com canvas->setMatrix(pdfContext->fGraphicsState.fCTM); 1425131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com if (pdfContext->fGraphicsState.fHasClipPathToApply) { 1426131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com#ifndef PDF_DEBUG_NO_CLIPING 1427131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com canvas->clipPath(pdfContext->fGraphicsState.fClipPath, SkRegion::kIntersect_Op, true); 1428131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com#endif 1429131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 1430131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1431131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com pdfContext->fGraphicsState.fHasClipPathToApply = false; 1432131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1433131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com pdfContext->fGraphicsState.fPathClosed = true; 1434131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 14353aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kOK_SkPdfResult; 1436131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 1437131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 143836026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_BT(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 1439131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com pdfContext->fGraphicsState.fTextBlock = true; 1440e57c62d039cbd67a4e52776b3e95c5d002b818d2edisonn@google.com SkMatrix matrix = pdfContext->fGraphicsState.fCTM; 1441e57c62d039cbd67a4e52776b3e95c5d002b818d2edisonn@google.com matrix.preScale(SkDoubleToScalar(1), SkDoubleToScalar(-1)); 1442e57c62d039cbd67a4e52776b3e95c5d002b818d2edisonn@google.com pdfContext->fGraphicsState.fMatrixTm = matrix; 1443e57c62d039cbd67a4e52776b3e95c5d002b818d2edisonn@google.com pdfContext->fGraphicsState.fMatrixTlm = matrix; 1444131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 14453aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kPartial_SkPdfResult; 1446131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 1447131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 144836026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_ET(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 1449131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com if (!pdfContext->fGraphicsState.fTextBlock) { 1450e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kMissingBT_SkPdfIssue, "ET without BT", NULL, 1451e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com pdfContext); 1452af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com 14533aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kIgnoreError_SkPdfResult; 1454131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 1455b1de123336246ad970e8a593267c37cc3be8105cscroggo@google.com 1456b1de123336246ad970e8a593267c37cc3be8105cscroggo@google.com pdfContext->fGraphicsState.fTextBlock = false; 1457b1de123336246ad970e8a593267c37cc3be8105cscroggo@google.com 1458131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com // TODO(edisonn): anything else to be done once we are done with draw text? Like restore stack? 14593aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kOK_SkPdfResult; 1460131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 1461131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1462e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.comstatic SkPdfResult skpdfGraphicsStateApplyFontCore(SkPdfContext* pdfContext, 1463e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com const SkPdfNativeObject* fontName, double fontSize) { 1464131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com#ifdef PDF_TRACE 14652ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com printf("font name: %s\n", fontName->nameValue2().c_str()); 1466131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com#endif 1467131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 146896ba3aa2faafc609ac275092aa0a4fad4afd749cedisonn@google.com if (!pdfContext->fGraphicsState.fResources->Font(pdfContext->fPdfDoc)) { 146996ba3aa2faafc609ac275092aa0a4fad4afd749cedisonn@google.com // TODO(edisonn): try to recover and draw it any way? 1470e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kMissingFont_SkPdfIssue, 1471e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com "No font", fontName, pdfContext); 14723aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kIgnoreError_SkPdfResult; 147396ba3aa2faafc609ac275092aa0a4fad4afd749cedisonn@google.com } 1474131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1475e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfNativeObject* objFont 1476e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com = pdfContext->fGraphicsState.fResources->Font(pdfContext->fPdfDoc)->get(fontName); 147796ba3aa2faafc609ac275092aa0a4fad4afd749cedisonn@google.com objFont = pdfContext->fPdfDoc->resolveReference(objFont); 14783aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com if (kNone_SkPdfNativeObjectType == pdfContext->fPdfDoc->mapper()->mapFontDictionary(objFont)) { 147996ba3aa2faafc609ac275092aa0a4fad4afd749cedisonn@google.com // TODO(edisonn): try to recover and draw it any way? 1480e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kInvalidFont_SkPdfIssue, 1481e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com "Invalid font", objFont, pdfContext); 14823aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kIgnoreError_SkPdfResult; 148396ba3aa2faafc609ac275092aa0a4fad4afd749cedisonn@google.com } 1484131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 148596ba3aa2faafc609ac275092aa0a4fad4afd749cedisonn@google.com SkPdfFontDictionary* fd = (SkPdfFontDictionary*)objFont; 148696ba3aa2faafc609ac275092aa0a4fad4afd749cedisonn@google.com 148796ba3aa2faafc609ac275092aa0a4fad4afd749cedisonn@google.com SkPdfFont* skfont = SkPdfFont::fontFromPdfDictionary(pdfContext->fPdfDoc, fd); 148896ba3aa2faafc609ac275092aa0a4fad4afd749cedisonn@google.com 148996ba3aa2faafc609ac275092aa0a4fad4afd749cedisonn@google.com if (skfont) { 149096ba3aa2faafc609ac275092aa0a4fad4afd749cedisonn@google.com pdfContext->fGraphicsState.fSkFont = skfont; 1491131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 1492a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com pdfContext->fGraphicsState.fCurFontSize = fontSize; 14933aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kOK_SkPdfResult; 1494131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 1495131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1496a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com//font size Tf Set the text font, Tf 1497a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com//, to font and the text font size, Tfs, to size. font is the name of a 1498a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com//font resource in the Fontsubdictionary of the current resource dictionary; size is 1499a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com//a number representing a scale factor. There is no initial value for either font or 1500a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com//size; they must be specified explicitly using Tf before any text is shown. 150136026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_Tf(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 1502af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com EXPECT_OPERANDS("Tf", pdfContext, 2); 1503bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, fontSize); 1504bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NAME(pdfContext, fontName); 1505bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com CHECK_PARAMETERS(); 1506bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com 1507a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com return skpdfGraphicsStateApplyFontCore(pdfContext, fontName, fontSize); 1508a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com} 1509a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com 151036026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_Tj(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 1511af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com EXPECT_OPERANDS("Tj", pdfContext, 1); 1512bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_STRING(pdfContext, str); 1513bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com CHECK_PARAMETERS(); 1514bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com 1515131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com if (!pdfContext->fGraphicsState.fTextBlock) { 1516131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com // TODO(edisonn): try to recover and draw it any way? 1517e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kMissingBT_SkPdfIssue, "Tj without BT", NULL, 1518e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com pdfContext); 15193aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kIgnoreError_SkPdfResult; 1520131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 1521131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1522bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com SkPdfResult ret = DrawText(pdfContext, str, canvas); 1523131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1524131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com return ret; 1525131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 1526131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1527e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.comstatic SkPdfResult PdfOp_quote(SkPdfContext* pdfContext, SkCanvas* canvas, 152836026de64400cbe91552c549cf9a906a0926fef3scroggo@google.com SkPdfTokenLooper* parentLooper) { 1529131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com if (!pdfContext->fGraphicsState.fTextBlock) { 1530131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com // TODO(edisonn): try to recover and draw it any way? 1531e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kMissingBT_SkPdfIssue, 1532e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com "' without BT", NULL, pdfContext); 15333aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kIgnoreError_SkPdfResult; 1534131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 1535131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 153636026de64400cbe91552c549cf9a906a0926fef3scroggo@google.com PdfOp_T_star(pdfContext, canvas, parentLooper); 1537131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com // Do not pop, and push, just transfer the param to Tj 153836026de64400cbe91552c549cf9a906a0926fef3scroggo@google.com return PdfOp_Tj(pdfContext, canvas, parentLooper); 1539131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 1540131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1541e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.comstatic SkPdfResult PdfOp_doublequote(SkPdfContext* pdfContext, SkCanvas* canvas, 154236026de64400cbe91552c549cf9a906a0926fef3scroggo@google.com SkPdfTokenLooper* parentLooper) { 1543131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com if (!pdfContext->fGraphicsState.fTextBlock) { 1544131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com // TODO(edisonn): try to recover and draw it any way? 1545e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kMissingBT_SkPdfIssue, 1546e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com "\" without BT", NULL, pdfContext); 15473aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kIgnoreError_SkPdfResult; 1548131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 1549131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1550af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com EXPECT_OPERANDS("\"", pdfContext, 3); 1551bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_OBJ(pdfContext, str); 1552bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_OBJ(pdfContext, ac); 1553bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_OBJ(pdfContext, aw); 1554bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com CHECK_PARAMETERS(); 1555131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1556131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com pdfContext->fObjectStack.push(aw); 155736026de64400cbe91552c549cf9a906a0926fef3scroggo@google.com PdfOp_Tw(pdfContext, canvas, parentLooper); 1558131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1559131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com pdfContext->fObjectStack.push(ac); 156036026de64400cbe91552c549cf9a906a0926fef3scroggo@google.com PdfOp_Tc(pdfContext, canvas, parentLooper); 1561131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1562131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com pdfContext->fObjectStack.push(str); 156336026de64400cbe91552c549cf9a906a0926fef3scroggo@google.com PdfOp_quote(pdfContext, canvas, parentLooper); 1564131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 15653aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kPartial_SkPdfResult; 1566131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 1567131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 156836026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_TJ(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 1569af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com EXPECT_OPERANDS("Tf", pdfContext, 1); 1570bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_ARRAY(pdfContext, array); 1571bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com CHECK_PARAMETERS(); 1572bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com 1573131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com if (!pdfContext->fGraphicsState.fTextBlock) { 1574131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com // TODO(edisonn): try to recover and draw it any way? 1575e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kMissingBT_SkPdfIssue, "TJ without BT", NULL, 1576e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com pdfContext); 15773aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kIgnoreError_SkPdfResult; 1578131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 1579131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1580571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com if (!array->isArray()) { 1581e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, array, 1582e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfNativeObject::kArray_PdfObjectType, pdfContext); 15833aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kIgnoreError_SkPdfResult; 1584571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 1585571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 1586131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com for( int i=0; i<static_cast<int>(array->size()); i++ ) 1587131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com { 1588af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com if (!(*array)[i]) { 1589e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, 1590e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com "element [i] is null, no element should be null", 1591e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com array, 15925e4d9819dbcbfbbdbd2ad2840b9c1b2b01c98db1edisonn@google.com SkPdfNativeObject::_kAnyString_PdfObjectType | 1593e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfNativeObject::_kNumber_PdfObjectType, 1594e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com pdfContext); 1595af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com } else if( (*array)[i]->isAnyString()) { 15963aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com SkPdfNativeObject* obj = (*array)[i]; 1597bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com DrawText(pdfContext, obj, canvas); 1598571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } else if ((*array)[i]->isNumber()) { 1599571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com double dx = (*array)[i]->numberValue(); 1600131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com SkMatrix matrix; 1601131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com matrix.setAll(SkDoubleToScalar(1), 1602131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com SkDoubleToScalar(0), 1603131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com // TODO(edisonn): use writing mode, vertical/horizontal. 1604131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com SkDoubleToScalar(-dx), // amount is substracted!!! 1605131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com SkDoubleToScalar(0), 1606131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com SkDoubleToScalar(1), 1607131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com SkDoubleToScalar(0), 1608131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com SkDoubleToScalar(0), 1609131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com SkDoubleToScalar(0), 1610131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com SkDoubleToScalar(1)); 1611131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1612131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com pdfContext->fGraphicsState.fMatrixTm.preConcat(matrix); 1613af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com } else { 1614e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, "wrong type", (*array)[i], 16155e4d9819dbcbfbbdbd2ad2840b9c1b2b01c98db1edisonn@google.com SkPdfNativeObject::kArray_PdfObjectType | 1616e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfNativeObject::_kNumber_PdfObjectType, 1617e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com pdfContext); 1618131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 1619131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 16203aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kPartial_SkPdfResult; // TODO(edisonn): Implement fully DrawText before returing OK. 1621131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 1622131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1623e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.comstatic SkPdfResult PdfOp_CS_cs(SkPdfContext* pdfContext, SkCanvas* canvas, 1624e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfColorOperator* colorOperator) { 1625af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com EXPECT_OPERANDS("CS/cs", pdfContext, 1); 1626bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NAME(pdfContext, name); 1627bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com CHECK_PARAMETERS(); 16284f898b78bb1c04e4763eca59a6e1defef555e696edisonn@google.com 16294f898b78bb1c04e4763eca59a6e1defef555e696edisonn@google.com //Next, get the ColorSpace Dictionary from the Resource Dictionary: 1630e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfDictionary* colorSpaceResource 1631e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com = pdfContext->fGraphicsState.fResources->ColorSpace(pdfContext->fPdfDoc); 16324f898b78bb1c04e4763eca59a6e1defef555e696edisonn@google.com 1633e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfNativeObject* colorSpace 1634e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com = colorSpaceResource ? pdfContext->fPdfDoc 1635e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com ->resolveReference(colorSpaceResource->get(name)) : 1636e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com name; 16374f898b78bb1c04e4763eca59a6e1defef555e696edisonn@google.com 16384f898b78bb1c04e4763eca59a6e1defef555e696edisonn@google.com if (colorSpace == NULL) { 16394f898b78bb1c04e4763eca59a6e1defef555e696edisonn@google.com colorOperator->fColorSpace = name->strRef(); 16404f898b78bb1c04e4763eca59a6e1defef555e696edisonn@google.com } else { 16414f898b78bb1c04e4763eca59a6e1defef555e696edisonn@google.com#ifdef PDF_TRACE 16424f898b78bb1c04e4763eca59a6e1defef555e696edisonn@google.com printf("CS = %s\n", colorSpace->toString(0, 0).c_str()); 16434f898b78bb1c04e4763eca59a6e1defef555e696edisonn@google.com#endif // PDF_TRACE 16444f898b78bb1c04e4763eca59a6e1defef555e696edisonn@google.com if (colorSpace->isName()) { 16454f898b78bb1c04e4763eca59a6e1defef555e696edisonn@google.com colorOperator->fColorSpace = colorSpace->strRef(); 16464f898b78bb1c04e4763eca59a6e1defef555e696edisonn@google.com } else if (colorSpace->isArray()) { 16475f008652f69ce7809b920b9fa573bc72216acd51scroggo@google.com size_t cnt = colorSpace->size(); 16484f898b78bb1c04e4763eca59a6e1defef555e696edisonn@google.com if (cnt == 0) { 1649e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kIncostistentSizes_SkPdfIssue, 1650e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com "color space has length 0", colorSpace, pdfContext); 16513aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kIgnoreError_SkPdfResult; 16524f898b78bb1c04e4763eca59a6e1defef555e696edisonn@google.com } 16533aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com SkPdfNativeObject* type = colorSpace->objAtAIndex(0); 16544f898b78bb1c04e4763eca59a6e1defef555e696edisonn@google.com type = pdfContext->fPdfDoc->resolveReference(type); 16554f898b78bb1c04e4763eca59a6e1defef555e696edisonn@google.com 16564f898b78bb1c04e4763eca59a6e1defef555e696edisonn@google.com if (type->isName("ICCBased")) { 16574f898b78bb1c04e4763eca59a6e1defef555e696edisonn@google.com if (cnt != 2) { 1658e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kIncostistentSizes_SkPdfIssue, 1659e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com "ICCBased color space must have an array with 2 elements", 1660e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com colorSpace, pdfContext); 16613aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kIgnoreError_SkPdfResult; 16624f898b78bb1c04e4763eca59a6e1defef555e696edisonn@google.com } 16633aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com SkPdfNativeObject* prop = colorSpace->objAtAIndex(1); 16644f898b78bb1c04e4763eca59a6e1defef555e696edisonn@google.com prop = pdfContext->fPdfDoc->resolveReference(prop); 16654f898b78bb1c04e4763eca59a6e1defef555e696edisonn@google.com#ifdef PDF_TRACE 16664f898b78bb1c04e4763eca59a6e1defef555e696edisonn@google.com printf("ICCBased prop = %s\n", prop->toString(0, 0).c_str()); 16674f898b78bb1c04e4763eca59a6e1defef555e696edisonn@google.com#endif // PDF_TRACE 16684f898b78bb1c04e4763eca59a6e1defef555e696edisonn@google.com // TODO(edisonn): hack 1669e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com if (prop && prop->isDictionary() && prop->get("N") && 1670e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com prop->get("N")->isInteger() && prop->get("N")->intValue() == 3) { 16714f898b78bb1c04e4763eca59a6e1defef555e696edisonn@google.com colorOperator->setColorSpace(&strings_DeviceRGB); 16723aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kPartial_SkPdfResult; 16734f898b78bb1c04e4763eca59a6e1defef555e696edisonn@google.com } 16743aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kNYI_SkPdfResult; 16754f898b78bb1c04e4763eca59a6e1defef555e696edisonn@google.com } 16764f898b78bb1c04e4763eca59a6e1defef555e696edisonn@google.com } 16774f898b78bb1c04e4763eca59a6e1defef555e696edisonn@google.com } 16784f898b78bb1c04e4763eca59a6e1defef555e696edisonn@google.com 16793aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kPartial_SkPdfResult; 1680131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 1681131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 168236026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_CS(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 1683131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com return PdfOp_CS_cs(pdfContext, canvas, &pdfContext->fGraphicsState.fStroking); 1684131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 1685131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 168636026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_cs(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 1687131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com return PdfOp_CS_cs(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStroking); 1688131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 1689131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1690e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.comstatic SkPdfResult PdfOp_SC_sc(SkPdfContext* pdfContext, SkCanvas* canvas, 1691e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfColorOperator* colorOperator) { 1692131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com double c[4]; 1693571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com// int64_t v[4]; 1694131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1695131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com int n = GetColorSpaceComponents(colorOperator->fColorSpace); 1696131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1697131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com bool doubles = true; 16982ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com if (colorOperator->fColorSpace.equals("Indexed")) { 1699131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com doubles = false; 1700131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 1701131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1702131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com#ifdef PDF_TRACE 17032ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com printf("color space = %s, N = %i\n", colorOperator->fColorSpace.fBuffer, n); 1704131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com#endif 1705131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1706af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com EXPECT_OPERANDS("SC/sc", pdfContext, n); 1707bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com 1708131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com for (int i = n - 1; i >= 0 ; i--) { 1709131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com if (doubles) { 1710bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER_INTO(pdfContext, c[i]); 1711571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com// } else { 1712571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com// v[i] = pdfContext->fObjectStack.top()->intValue(); pdfContext->fObjectStack.pop(); 1713131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 1714131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 1715bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com CHECK_PARAMETERS(); 1716131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1717131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com // TODO(edisonn): Now, set that color. Only DeviceRGB supported. 1718571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com // TODO(edisonn): do possible field values to enum at parsing time! 1719e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com // TODO(edisonn): support also abbreviations /DeviceRGB == /RGB 1720e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com if (colorOperator->fColorSpace.equals("DeviceRGB") || 1721e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com colorOperator->fColorSpace.equals("RGB")) { 1722e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com colorOperator->setRGBColor(SkColorSetRGB((U8CPU)(255*c[0]), 1723e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com (U8CPU)(255*c[1]), 1724e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com (U8CPU)(255*c[2]))); 1725131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 17263aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kPartial_SkPdfResult; 1727131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 1728131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 172936026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_SC(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 1730131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com return PdfOp_SC_sc(pdfContext, canvas, &pdfContext->fGraphicsState.fStroking); 1731131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 1732131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 173336026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_sc(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 1734131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com return PdfOp_SC_sc(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStroking); 1735131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 1736131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1737e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.comstatic SkPdfResult PdfOp_SCN_scn(SkPdfContext* pdfContext, SkCanvas* canvas, 1738e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfColorOperator* colorOperator) { 1739bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com if (pdfContext->fObjectStack.count() > 0 && pdfContext->fObjectStack.top()->isName()) { 17403aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com SkPdfNativeObject* name = pdfContext->fObjectStack.top(); pdfContext->fObjectStack.pop(); 1741276fed9e0ae2e4457efd61eeb14738040feb65f1edisonn@google.com 1742e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfDictionary* patternResources 1743e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com = pdfContext->fGraphicsState.fResources->Pattern(pdfContext->fPdfDoc); 1744276fed9e0ae2e4457efd61eeb14738040feb65f1edisonn@google.com 1745e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com if (patternResources == NULL) { 1746276fed9e0ae2e4457efd61eeb14738040feb65f1edisonn@google.com#ifdef PDF_TRACE 1747276fed9e0ae2e4457efd61eeb14738040feb65f1edisonn@google.com printf("ExtGState is NULL!\n"); 1748276fed9e0ae2e4457efd61eeb14738040feb65f1edisonn@google.com#endif 17493aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kIgnoreError_SkPdfResult; 1750276fed9e0ae2e4457efd61eeb14738040feb65f1edisonn@google.com } 1751276fed9e0ae2e4457efd61eeb14738040feb65f1edisonn@google.com 1752e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com colorOperator->setPatternColorSpace( 1753e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com pdfContext->fPdfDoc->resolveReference(patternResources->get(name))); 1754131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 1755131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1756131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com // TODO(edisonn): SCN supports more color spaces than SCN. Read and implement spec. 1757131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com PdfOp_SC_sc(pdfContext, canvas, colorOperator); 1758131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 17593aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kPartial_SkPdfResult; 1760131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 1761131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 176236026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_SCN(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 1763131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com return PdfOp_SCN_scn(pdfContext, canvas, &pdfContext->fGraphicsState.fStroking); 1764131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 1765131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 176636026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_scn(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 1767131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com return PdfOp_SCN_scn(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStroking); 1768131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 1769131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1770e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.comstatic SkPdfResult PdfOp_G_g(SkPdfContext* pdfContext, SkCanvas* canvas, 1771e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfColorOperator* colorOperator) { 1772af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com EXPECT_OPERANDS("G/g", pdfContext, 1); 1773bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, gray); 1774bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com CHECK_PARAMETERS(); 1775bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com 1776e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com // TODO(edisonn): limit gray in [0, 1] 1777e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com 1778e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com // TODO(edisonn): HACK - it should be device gray, but not suported right now 1779e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com colorOperator->fColorSpace = strings_DeviceRGB; 1780e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com colorOperator->setRGBColor(SkColorSetRGB((U8CPU)(255 * gray), 1781e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com (U8CPU)(255 * gray), 1782e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com (U8CPU)(255 * gray))); 1783bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com 1784bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com return kPartial_SkPdfResult; 1785131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 1786131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 178736026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_G(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 1788131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com return PdfOp_G_g(pdfContext, canvas, &pdfContext->fGraphicsState.fStroking); 1789131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 1790131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 179136026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_g(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 1792131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com return PdfOp_G_g(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStroking); 1793131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 1794131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1795e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.comstatic SkPdfResult PdfOp_RG_rg(SkPdfContext* pdfContext, SkCanvas* canvas, 1796e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfColorOperator* colorOperator) { 1797af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com EXPECT_OPERANDS("RG/rg", pdfContext, 3); 1798bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, b); 1799bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, g); 1800bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, r); 1801bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com CHECK_PARAMETERS(); 1802131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 18032ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com colorOperator->fColorSpace = strings_DeviceRGB; 180496ba3aa2faafc609ac275092aa0a4fad4afd749cedisonn@google.com colorOperator->setRGBColor(SkColorSetRGB((U8CPU)(255*r), (U8CPU)(255*g), (U8CPU)(255*b))); 18053aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kOK_SkPdfResult; 1806131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 1807131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 180836026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_RG(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 1809131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com return PdfOp_RG_rg(pdfContext, canvas, &pdfContext->fGraphicsState.fStroking); 1810131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 1811131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 181236026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_rg(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 1813131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com return PdfOp_RG_rg(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStroking); 1814131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 1815131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1816e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.comstatic SkPdfResult PdfOp_K_k(SkPdfContext* pdfContext, SkCanvas* canvas, 1817e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfColorOperator* colorOperator) { 1818131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com // TODO(edisonn): spec has some rules about overprint, implement them. 1819af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com EXPECT_OPERANDS("K/k", pdfContext, 4); 1820bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, k); 1821bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, y); 1822bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, m); 1823bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, c); 1824bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com CHECK_PARAMETERS(); 1825bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com 1826e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com // TODO(edisonn): really silly quick way to remove compiler warning 1827bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com if (k + y + m + c == 0) { 1828bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com return kNYI_SkPdfResult; 1829bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com } 1830131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1831bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com //colorOperator->fColorSpace = strings_DeviceCMYK; 1832131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com // TODO(edisonn): Set color. 18333aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kNYI_SkPdfResult; 1834131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 1835131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 183636026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_K(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 1837131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com return PdfOp_K_k(pdfContext, canvas, &pdfContext->fGraphicsState.fStroking); 1838131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 1839131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 184036026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_k(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 1841131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com return PdfOp_K_k(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStroking); 1842131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 1843131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 184436026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_W(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 1845131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com pdfContext->fGraphicsState.fClipPath = pdfContext->fGraphicsState.fPath; 1846131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com pdfContext->fGraphicsState.fHasClipPathToApply = true; 1847131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 18483aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kOK_SkPdfResult; 1849131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 1850131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 185136026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_W_star(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 1852131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com pdfContext->fGraphicsState.fClipPath = pdfContext->fGraphicsState.fPath; 1853131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 1854131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com pdfContext->fGraphicsState.fClipPath.setFillType(SkPath::kEvenOdd_FillType); 1855131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com pdfContext->fGraphicsState.fHasClipPathToApply = true; 1856131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 18573aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kOK_SkPdfResult; 1858131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 1859131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 186036026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_BX(SkPdfContext* pdfContext, SkCanvas* canvas, 186136026de64400cbe91552c549cf9a906a0926fef3scroggo@google.com SkPdfTokenLooper* parentLooper) { 186236026de64400cbe91552c549cf9a906a0926fef3scroggo@google.com PdfCompatibilitySectionLooper looper(parentLooper); 186336026de64400cbe91552c549cf9a906a0926fef3scroggo@google.com looper.loop(); 18643aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kOK_SkPdfResult; 1865131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 1866131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 186736026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_EX(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 1868e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kNullObject_SkPdfIssue, 1869e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com "EX operator should not be called, it is handled in a looper, " 1870e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com "unless the file is corrupted, we should assert", 1871e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com NULL, pdfContext); 1872af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com 18733aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kIgnoreError_SkPdfResult; 1874131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 1875131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 187636026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_BI(SkPdfContext* pdfContext, SkCanvas* canvas, 187736026de64400cbe91552c549cf9a906a0926fef3scroggo@google.com SkPdfTokenLooper* parentLooper) { 187836026de64400cbe91552c549cf9a906a0926fef3scroggo@google.com PdfInlineImageLooper looper(parentLooper); 187936026de64400cbe91552c549cf9a906a0926fef3scroggo@google.com looper.loop(); 18803aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kOK_SkPdfResult; 1881131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 1882131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 188336026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_ID(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 1884e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kNullObject_SkPdfIssue, 1885e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com "ID operator should not be called, it is habdled in a looper, " 1886e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com "unless the file is corrupted, we should assert", 1887e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com NULL, pdfContext); 18883aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kIgnoreError_SkPdfResult; 1889131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 1890131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 189136026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_EI(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 1892e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kNullObject_SkPdfIssue, 1893e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com "EI operator should not be called, it is habdled in a looper, " 1894e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com "unless the file is corrupted, we should assert", 1895e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com NULL, pdfContext); 18963aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kIgnoreError_SkPdfResult; 1897131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 1898131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 189933f11b6fcdb7dfce27f953803be40fbacedc7450edisonn@google.comstatic SkPdfResult skpdfGraphicsStateApply_ca(SkPdfContext* pdfContext, double ca) { 1900a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com pdfContext->fGraphicsState.fNonStroking.fOpacity = ca; 19013aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kOK_SkPdfResult; 1902a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com} 1903a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com 190433f11b6fcdb7dfce27f953803be40fbacedc7450edisonn@google.comstatic SkPdfResult skpdfGraphicsStateApply_CA(SkPdfContext* pdfContext, double CA) { 1905a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com pdfContext->fGraphicsState.fStroking.fOpacity = CA; 19063aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kOK_SkPdfResult; 1907a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com} 1908a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com 190933f11b6fcdb7dfce27f953803be40fbacedc7450edisonn@google.comstatic SkPdfResult skpdfGraphicsStateApplyLW(SkPdfContext* pdfContext, double lineWidth) { 1910a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com pdfContext->fGraphicsState.fLineWidth = lineWidth; 19113aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kOK_SkPdfResult; 1912a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com} 1913a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com 191433f11b6fcdb7dfce27f953803be40fbacedc7450edisonn@google.comstatic SkPdfResult skpdfGraphicsStateApplyLC(SkPdfContext* pdfContext, int64_t lineCap) { 1915a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com pdfContext->fGraphicsState.fLineCap = (int)lineCap; 19163aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kOK_SkPdfResult; 1917a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com} 1918a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com 191933f11b6fcdb7dfce27f953803be40fbacedc7450edisonn@google.comstatic SkPdfResult skpdfGraphicsStateApplyLJ(SkPdfContext* pdfContext, int64_t lineJoin) { 1920a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com pdfContext->fGraphicsState.fLineJoin = (int)lineJoin; 19213aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kOK_SkPdfResult; 1922a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com} 1923a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com 192433f11b6fcdb7dfce27f953803be40fbacedc7450edisonn@google.comstatic SkPdfResult skpdfGraphicsStateApplyML(SkPdfContext* pdfContext, double miterLimit) { 1925a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com pdfContext->fGraphicsState.fMiterLimit = miterLimit; 19263aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kOK_SkPdfResult; 1927a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com} 1928a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com 1929e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com// TODO(edisonn): test all dashing rules, not sure if they work as in skia. 193024cdf13b314889a2bfa50969c5a85b74aa49ea1dedisonn@google.com/* 193124cdf13b314889a2bfa50969c5a85b74aa49ea1dedisonn@google.com1) [ ] 0 No dash; solid, unbroken lines 193224cdf13b314889a2bfa50969c5a85b74aa49ea1dedisonn@google.com2) [3] 0 3 units on, 3 units off, … 193324cdf13b314889a2bfa50969c5a85b74aa49ea1dedisonn@google.com3) [2] 1 1 on, 2 off, 2 on, 2 off, … 193424cdf13b314889a2bfa50969c5a85b74aa49ea1dedisonn@google.com4) [2 1] 0 2 on, 1 off, 2 on, 1 off, … 193524cdf13b314889a2bfa50969c5a85b74aa49ea1dedisonn@google.com5) [3 5] 6 2 off, 3 on, 5 off, 3 on, 5 off, … 193624cdf13b314889a2bfa50969c5a85b74aa49ea1dedisonn@google.com6) [2 3] 11 1 on, 3 off, 2 on, 3 off, 2 on, … 193724cdf13b314889a2bfa50969c5a85b74aa49ea1dedisonn@google.com */ 1938a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com 1939e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.comstatic SkPdfResult skpdfGraphicsStateApplyD(SkPdfContext* pdfContext, SkPdfArray* intervals, 1940e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfNativeObject* phase) { 1941af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com if (intervals == NULL) { 1942e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, intervals, 1943e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfNativeObject::_kNumber_PdfObjectType, pdfContext); 1944af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com return kIgnoreError_SkPdfResult; 1945af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com } 1946af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com 1947af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com if (phase == NULL) { 1948e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, phase, 1949e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfNativeObject::_kNumber_PdfObjectType, pdfContext); 1950af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com return kIgnoreError_SkPdfResult; 1951af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com } 1952af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com 19535f008652f69ce7809b920b9fa573bc72216acd51scroggo@google.com int cnt = (int) intervals->size(); 1954a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com if (cnt >= 256) { 1955a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com // TODO(edisonn): alloc memory 1956e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, 1957e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com "dash array size unssuported, cnt > 256", intervals, pdfContext); 19583aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kIgnoreError_SkPdfResult; 1959a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com } 1960a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com for (int i = 0; i < cnt; i++) { 1961af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com if (!intervals->objAtAIndex(i) || !intervals->objAtAIndex(i)->isNumber()) { 1962e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, 1963e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com intervals->objAtAIndex(i), 1964e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfNativeObject::_kNumber_PdfObjectType, NULL); 19653aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kIgnoreError_SkPdfResult; 1966a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com } 1967a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com } 1968a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com 196924cdf13b314889a2bfa50969c5a85b74aa49ea1dedisonn@google.com double total = 0; 1970a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com for (int i = 0 ; i < cnt; i++) { 1971a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com pdfContext->fGraphicsState.fDashArray[i] = intervals->objAtAIndex(i)->scalarValue(); 197224cdf13b314889a2bfa50969c5a85b74aa49ea1dedisonn@google.com total += pdfContext->fGraphicsState.fDashArray[i]; 1973a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com } 1974f111a4b6855277bba8dac84cce7ccfa1b3f25d7cedisonn@google.com if (cnt & 1) { 1975f111a4b6855277bba8dac84cce7ccfa1b3f25d7cedisonn@google.com if (cnt == 1) { 1976f111a4b6855277bba8dac84cce7ccfa1b3f25d7cedisonn@google.com pdfContext->fGraphicsState.fDashArray[1] = pdfContext->fGraphicsState.fDashArray[0]; 1977f111a4b6855277bba8dac84cce7ccfa1b3f25d7cedisonn@google.com cnt++; 1978f111a4b6855277bba8dac84cce7ccfa1b3f25d7cedisonn@google.com } else { 1979f111a4b6855277bba8dac84cce7ccfa1b3f25d7cedisonn@google.com // TODO(edisonn): report error/warning 19803aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kNYI_SkPdfResult; 1981f111a4b6855277bba8dac84cce7ccfa1b3f25d7cedisonn@google.com } 1982f111a4b6855277bba8dac84cce7ccfa1b3f25d7cedisonn@google.com } 1983f111a4b6855277bba8dac84cce7ccfa1b3f25d7cedisonn@google.com pdfContext->fGraphicsState.fDashArrayLength = cnt; 198424cdf13b314889a2bfa50969c5a85b74aa49ea1dedisonn@google.com pdfContext->fGraphicsState.fDashPhase = phase->scalarValue(); 198524cdf13b314889a2bfa50969c5a85b74aa49ea1dedisonn@google.com if (pdfContext->fGraphicsState.fDashPhase == 0) { 198624cdf13b314889a2bfa50969c5a85b74aa49ea1dedisonn@google.com // other rules, changes? 1987063d7072ef45971c17045721626b3f0cd052b3b9edisonn@google.com pdfContext->fGraphicsState.fDashPhase = SkDoubleToScalar(total); 198824cdf13b314889a2bfa50969c5a85b74aa49ea1dedisonn@google.com } 198924cdf13b314889a2bfa50969c5a85b74aa49ea1dedisonn@google.com 19903aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kOK_SkPdfResult; 199124cdf13b314889a2bfa50969c5a85b74aa49ea1dedisonn@google.com} 199224cdf13b314889a2bfa50969c5a85b74aa49ea1dedisonn@google.com 199333f11b6fcdb7dfce27f953803be40fbacedc7450edisonn@google.comstatic SkPdfResult skpdfGraphicsStateApplyD(SkPdfContext* pdfContext, SkPdfArray* dash) { 1994af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com if (!dash || dash->isArray()) { 1995e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, dash, 1996e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfNativeObject::kArray_PdfObjectType, pdfContext); 1997af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com return kIgnoreError_SkPdfResult; 1998af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com } 1999af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com 2000af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com if (dash->size() != 2) { 2001e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kIncostistentSizes_SkPdfIssue, 2002e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com "hash array must have 2 elements", dash, pdfContext); 20033aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kIgnoreError_SkPdfResult; 200424cdf13b314889a2bfa50969c5a85b74aa49ea1dedisonn@google.com } 2005af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com 2006af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com if (!dash->objAtAIndex(0) || !dash->objAtAIndex(0)->isArray()) { 2007e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, dash->objAtAIndex(0), 2008e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfNativeObject::kArray_PdfObjectType, pdfContext); 2009af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com return kIgnoreError_SkPdfResult; 2010af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com } 2011af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com 2012af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com if (!dash->objAtAIndex(1) || !dash->objAtAIndex(1)->isNumber()) { 2013e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, dash->objAtAIndex(1), 2014e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfNativeObject::_kNumber_PdfObjectType, pdfContext); 2015af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com return kIgnoreError_SkPdfResult; 2016af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com } 2017af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com 2018e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com return skpdfGraphicsStateApplyD(pdfContext, (SkPdfArray*)dash->objAtAIndex(0), 2019e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com dash->objAtAIndex(1)); 2020a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com} 2021a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com 202233f11b6fcdb7dfce27f953803be40fbacedc7450edisonn@google.comstatic void skpdfGraphicsStateApplyFont(SkPdfContext* pdfContext, SkPdfArray* fontAndSize) { 2023af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com if (!fontAndSize || !fontAndSize->isArray()) { 2024e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, fontAndSize, 2025e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfNativeObject::kArray_PdfObjectType, pdfContext); 2026a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com return; 2027a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com } 2028af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com 2029af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com if (fontAndSize->size() != 2) { 2030e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kIncostistentSizes_SkPdfIssue, 2031e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com "font array must have 2 elements", fontAndSize, pdfContext); 2032af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com return; 2033af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com } 2034af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com 2035af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com if (!fontAndSize->objAtAIndex(0) || !fontAndSize->objAtAIndex(0)->isName()) { 2036e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, 2037e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com fontAndSize->objAtAIndex(0), 2038e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfNativeObject::kName_PdfObjectType, pdfContext); 2039af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com return; 2040af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com } 2041af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com 2042af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com 2043af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com if (!fontAndSize->objAtAIndex(1) || !fontAndSize->objAtAIndex(1)->isNumber()) { 2044e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, 2045e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com fontAndSize->objAtAIndex(0), 2046e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfNativeObject::_kNumber_PdfObjectType, pdfContext); 2047af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com return; 2048af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com } 2049af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com 2050e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com skpdfGraphicsStateApplyFontCore(pdfContext, fontAndSize->objAtAIndex(0), 2051e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com fontAndSize->objAtAIndex(1)->numberValue()); 2052a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com} 2053a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com 205424cdf13b314889a2bfa50969c5a85b74aa49ea1dedisonn@google.com 205524cdf13b314889a2bfa50969c5a85b74aa49ea1dedisonn@google.com//lineWidth w Set the line width in the graphics state (see “Line Width” on page 152). 205636026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_w(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 2057af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com EXPECT_OPERANDS("w", pdfContext, 1); 2058bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, lw); 2059bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com CHECK_PARAMETERS(); 2060bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com 206124cdf13b314889a2bfa50969c5a85b74aa49ea1dedisonn@google.com return skpdfGraphicsStateApplyLW(pdfContext, lw); 206224cdf13b314889a2bfa50969c5a85b74aa49ea1dedisonn@google.com} 206324cdf13b314889a2bfa50969c5a85b74aa49ea1dedisonn@google.com 206424cdf13b314889a2bfa50969c5a85b74aa49ea1dedisonn@google.com//lineCap J Set the line cap style in the graphics state (see “Line Cap Style” on page 153). 206536026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_J(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 2066063d7072ef45971c17045721626b3f0cd052b3b9edisonn@google.com // TODO(edisonn): round/ceil to int? 2067af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com EXPECT_OPERANDS("J", pdfContext, 1); 2068bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, lc); 2069bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com CHECK_PARAMETERS(); 2070bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com 2071bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com return skpdfGraphicsStateApplyLC(pdfContext, (int)lc); 207224cdf13b314889a2bfa50969c5a85b74aa49ea1dedisonn@google.com} 207324cdf13b314889a2bfa50969c5a85b74aa49ea1dedisonn@google.com 207424cdf13b314889a2bfa50969c5a85b74aa49ea1dedisonn@google.com//lineJoin j Set the line join style in the graphics state (see “Line Join Style” on page 153). 207536026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_j(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 2076063d7072ef45971c17045721626b3f0cd052b3b9edisonn@google.com // TODO(edisonn): round/ceil to int? 2077af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com EXPECT_OPERANDS("j", pdfContext, 1); 2078bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, lj); 2079bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com CHECK_PARAMETERS(); 2080bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com 2081bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com return skpdfGraphicsStateApplyLJ(pdfContext, (int)lj); 208224cdf13b314889a2bfa50969c5a85b74aa49ea1dedisonn@google.com} 208324cdf13b314889a2bfa50969c5a85b74aa49ea1dedisonn@google.com 208424cdf13b314889a2bfa50969c5a85b74aa49ea1dedisonn@google.com//miterLimit M Set the miter limit in the graphics state (see “Miter Limit” on page 153). 208536026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_M(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 2086af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com EXPECT_OPERANDS("M", pdfContext, 1); 2087bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, ml); 2088bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com CHECK_PARAMETERS(); 208924cdf13b314889a2bfa50969c5a85b74aa49ea1dedisonn@google.com return skpdfGraphicsStateApplyML(pdfContext, ml); 209024cdf13b314889a2bfa50969c5a85b74aa49ea1dedisonn@google.com} 209124cdf13b314889a2bfa50969c5a85b74aa49ea1dedisonn@google.com 209224cdf13b314889a2bfa50969c5a85b74aa49ea1dedisonn@google.com//dashArray dashPhase d Set the line dash pattern in the graphics state (see “Line Dash Pattern” on 209324cdf13b314889a2bfa50969c5a85b74aa49ea1dedisonn@google.com//page 155). 209436026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_d(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 2095af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com EXPECT_OPERANDS("d", pdfContext, 2); 2096bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_OBJ(pdfContext, phase); 2097bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_ARRAY(pdfContext, array); 2098bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com CHECK_PARAMETERS(); 209924cdf13b314889a2bfa50969c5a85b74aa49ea1dedisonn@google.com 2100bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com return skpdfGraphicsStateApplyD(pdfContext, array, phase); 210124cdf13b314889a2bfa50969c5a85b74aa49ea1dedisonn@google.com} 210224cdf13b314889a2bfa50969c5a85b74aa49ea1dedisonn@google.com 2103e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com//intent ri (PDF 1.1) Set the color rendering intent in the graphics state (see “Rendering Intents” 2104e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com// on page 197). 210536026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_ri(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 210624cdf13b314889a2bfa50969c5a85b74aa49ea1dedisonn@google.com pdfContext->fObjectStack.pop(); 210724cdf13b314889a2bfa50969c5a85b74aa49ea1dedisonn@google.com 2108e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, "render intent NYI", NULL, 2109e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com pdfContext); 2110af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com 21113aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kNYI_SkPdfResult; 211224cdf13b314889a2bfa50969c5a85b74aa49ea1dedisonn@google.com} 211324cdf13b314889a2bfa50969c5a85b74aa49ea1dedisonn@google.com 211424cdf13b314889a2bfa50969c5a85b74aa49ea1dedisonn@google.com//flatness i Set the flatness tolerance in the graphics state (see Section 6.5.1, “Flatness 211524cdf13b314889a2bfa50969c5a85b74aa49ea1dedisonn@google.com//Tolerance”). flatness is a number in the range 0 to 100; a value of 0 speci- 211624cdf13b314889a2bfa50969c5a85b74aa49ea1dedisonn@google.com//fies the output device’s default flatness tolerance. 211736026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_i(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 2118af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com EXPECT_OPERANDS("i", pdfContext, 1); 2119bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, flatness); 2120bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com CHECK_PARAMETERS(); 2121bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com 2122bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com if (flatness < 0 || flatness > 100) { 2123e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kOutOfRange_SkPdfIssue, 2124e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com "flatness must be a real in [0, 100] range", flatness_obj, pdfContext); 2125af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com return kIgnoreError_SkPdfResult; 2126bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com } 212724cdf13b314889a2bfa50969c5a85b74aa49ea1dedisonn@google.com 21283aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kNYI_SkPdfResult; 212924cdf13b314889a2bfa50969c5a85b74aa49ea1dedisonn@google.com} 213024cdf13b314889a2bfa50969c5a85b74aa49ea1dedisonn@google.com 2131e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.comSkTDict<SkXfermode::Mode> gPdfBlendModes(20); 2132e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com 2133e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.comclass InitBlendModes { 2134e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.compublic: 2135e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com InitBlendModes() { 2136e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com // TODO(edisonn): use the python code generator? 2137e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com // TABLE 7.2 Standard separable blend modes 2138e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com gPdfBlendModes.set("Normal", SkXfermode::kSrc_Mode); 2139e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com gPdfBlendModes.set("Multiply", SkXfermode::kMultiply_Mode); 2140e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com gPdfBlendModes.set("Screen", SkXfermode::kScreen_Mode); 2141e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com gPdfBlendModes.set("Overlay", SkXfermode::kOverlay_Mode); 2142e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com gPdfBlendModes.set("Darken", SkXfermode::kDarken_Mode); 2143e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com gPdfBlendModes.set("Lighten", SkXfermode::kLighten_Mode); 2144e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com gPdfBlendModes.set("ColorDodge", SkXfermode::kColorDodge_Mode); 2145e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com gPdfBlendModes.set("ColorBurn", SkXfermode::kColorBurn_Mode); 2146e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com gPdfBlendModes.set("HardLight", SkXfermode::kHardLight_Mode); 2147e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com gPdfBlendModes.set("SoftLight", SkXfermode::kSoftLight_Mode); 2148e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com gPdfBlendModes.set("Difference", SkXfermode::kDifference_Mode); 2149e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com gPdfBlendModes.set("Exclusion", SkXfermode::kExclusion_Mode); 2150e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com 2151e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com // TABLE 7.3 Standard nonseparable blend modes 2152e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com gPdfBlendModes.set("Hue", SkXfermode::kHue_Mode); 2153e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com gPdfBlendModes.set("Saturation", SkXfermode::kSaturation_Mode); 2154e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com gPdfBlendModes.set("Color", SkXfermode::kColor_Mode); 2155e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com gPdfBlendModes.set("Luminosity", SkXfermode::kLuminosity_Mode); 2156e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com } 2157e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com}; 2158e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com 2159e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.comInitBlendModes _gDummyInniter; 2160e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com 216133f11b6fcdb7dfce27f953803be40fbacedc7450edisonn@google.comstatic SkXfermode::Mode xferModeFromBlendMode(const char* blendMode, size_t len) { 2162e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com SkXfermode::Mode mode = (SkXfermode::Mode)(SkXfermode::kLastMode + 1); 2163e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com if (gPdfBlendModes.find(blendMode, len, &mode)) { 2164e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com return mode; 2165e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com } 2166e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com 2167e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com return (SkXfermode::Mode)(SkXfermode::kLastMode + 1); 2168e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com} 2169e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com 2170063d7072ef45971c17045721626b3f0cd052b3b9edisonn@google.comstatic void skpdfGraphicsStateApplyBM_name(SkPdfContext* pdfContext, const SkString& blendMode) { 2171063d7072ef45971c17045721626b3f0cd052b3b9edisonn@google.com SkXfermode::Mode mode = xferModeFromBlendMode(blendMode.c_str(), blendMode.size()); 2172e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com if (mode <= SkXfermode::kLastMode) { 2173e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com pdfContext->fGraphicsState.fBlendModesLength = 1; 2174e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com pdfContext->fGraphicsState.fBlendModes[0] = mode; 2175e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com } else { 2176e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kUnknownBlendMode_SkPdfIssue, 2177e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com blendMode.c_str(), NULL, pdfContext); 2178e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com } 2179a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com} 2180a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com 218133f11b6fcdb7dfce27f953803be40fbacedc7450edisonn@google.comstatic void skpdfGraphicsStateApplyBM_array(SkPdfContext* pdfContext, SkPdfArray* blendModes) { 2182af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com if (!blendModes || !blendModes->isArray()) { 2183e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, blendModes, 2184e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfNativeObject::kArray_PdfObjectType, pdfContext); 2185af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com return; 2186af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com } 2187af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com 2188af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com if (blendModes->size() == 0 || blendModes->size() > 256) { 2189e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kIncostistentSizes_SkPdfIssue, 2190e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com "length of blendmodes, 0, is an erro, 256+, is NYI", blendModes, pdfContext); 2191e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com return; 2192e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com } 2193af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com 2194e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com SkXfermode::Mode modes[256]; 21955f008652f69ce7809b920b9fa573bc72216acd51scroggo@google.com int cnt = (int) blendModes->size(); 2196e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com for (int i = 0; i < cnt; i++) { 21973aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com SkPdfNativeObject* name = blendModes->objAtAIndex(i); 2198af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com if (!name || !name->isName()) { 2199e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, name, 2200e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfNativeObject::kName_PdfObjectType, pdfContext); 2201e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com return; 2202e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com } 2203e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com SkXfermode::Mode mode = xferModeFromBlendMode(name->c_str(), name->lenstr()); 2204e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com if (mode > SkXfermode::kLastMode) { 2205e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kUnknownBlendMode_SkPdfIssue, NULL, name, 2206e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com pdfContext); 2207e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com return; 2208e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com } 2209e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com } 2210a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com 2211e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com pdfContext->fGraphicsState.fBlendModesLength = cnt; 2212e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com for (int i = 0; i < cnt; i++) { 2213e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com pdfContext->fGraphicsState.fBlendModes[i] = modes[i]; 2214e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com } 2215a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com} 2216a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com 221733f11b6fcdb7dfce27f953803be40fbacedc7450edisonn@google.comstatic void skpdfGraphicsStateApplySMask_dict(SkPdfContext* pdfContext, SkPdfDictionary* sMask) { 2218af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com if (!sMask || !sMask->isName()) { 2219e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, sMask, 2220e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfNativeObject::kArray_PdfObjectType, pdfContext); 2221af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com return; 2222af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com } 2223af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com 2224e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com if (pdfContext->fPdfDoc->mapper()->mapSoftMaskDictionary(sMask)) { 22254ef4bed00efd247a0ea005b95b7239a9d4c14c68edisonn@google.com pdfContext->fGraphicsState.fSoftMaskDictionary = (SkPdfSoftMaskDictionary*)sMask; 2226e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com } else if (pdfContext->fPdfDoc->mapper()->mapSoftMaskImageDictionary(sMask)) { 2227e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com SkPdfSoftMaskImageDictionary* smid = (SkPdfSoftMaskImageDictionary*)sMask; 2228e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com pdfContext->fGraphicsState.fSMask = getImageFromObject(pdfContext, smid, true); 2229e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com } else { 2230e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, 2231e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com "Dictionary must be SoftMask, or SoftMaskImage", 2232e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com sMask, SkPdfNativeObject::kDictionary_PdfObjectType, pdfContext); 2233e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com } 2234e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com} 2235e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com 2236063d7072ef45971c17045721626b3f0cd052b3b9edisonn@google.comstatic void skpdfGraphicsStateApplySMask_name(SkPdfContext* pdfContext, const SkString& sMask) { 2237063d7072ef45971c17045721626b3f0cd052b3b9edisonn@google.com if (sMask.equals("None")) { 22384ef4bed00efd247a0ea005b95b7239a9d4c14c68edisonn@google.com pdfContext->fGraphicsState.fSoftMaskDictionary = NULL; 2239b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com pdfContext->fGraphicsState.fSMask = NULL; 22404ef4bed00efd247a0ea005b95b7239a9d4c14c68edisonn@google.com return; 22414ef4bed00efd247a0ea005b95b7239a9d4c14c68edisonn@google.com } 22424ef4bed00efd247a0ea005b95b7239a9d4c14c68edisonn@google.com 2243e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfDictionary* extGStateDictionary 2244e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com = pdfContext->fGraphicsState.fResources->ExtGState(pdfContext->fPdfDoc); 2245e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com 2246e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com if (extGStateDictionary == NULL) { 2247e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kMissingExtGState_SkPdfIssue, NULL, 2248e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com pdfContext->fGraphicsState.fResources, pdfContext); 2249e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com return; 2250e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com } 2251e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com 2252e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfNativeObject* obj 2253e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com = pdfContext->fPdfDoc->resolveReference(extGStateDictionary->get(sMask.c_str())); 2254e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com if (!obj || !obj->isDictionary()) { 2255e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, obj, 2256e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfNativeObject::kDictionary_PdfObjectType, pdfContext); 2257e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com return; 2258e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com } 22594ef4bed00efd247a0ea005b95b7239a9d4c14c68edisonn@google.com 22604ef4bed00efd247a0ea005b95b7239a9d4c14c68edisonn@google.com pdfContext->fGraphicsState.fSoftMaskDictionary = NULL; 2261b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com pdfContext->fGraphicsState.fSMask = NULL; 22624ef4bed00efd247a0ea005b95b7239a9d4c14c68edisonn@google.com 2263e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com skpdfGraphicsStateApplySMask_dict(pdfContext, obj->asDictionary()); 2264a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com} 2265a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com 226633f11b6fcdb7dfce27f953803be40fbacedc7450edisonn@google.comstatic void skpdfGraphicsStateApplyAIS(SkPdfContext* pdfContext, bool alphaSource) { 2267a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com pdfContext->fGraphicsState.fAlphaSource = alphaSource; 2268a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com} 2269a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com 2270a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com 2271131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com//dictName gs (PDF 1.2) Set the specified parameters in the graphics state. dictName is 2272e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com//the name of a graphics state parameter dictionary in the ExtGState subdictionary of the current 2273e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com//resource dictionary (see the next section). 227436026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_gs(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 2275af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com EXPECT_OPERANDS("gs", pdfContext, 1); 2276bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NAME(pdfContext, name); 2277bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com CHECK_PARAMETERS(); 2278131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 2279e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfDictionary* extGStateDictionary 2280e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com = pdfContext->fGraphicsState.fResources->ExtGState(pdfContext->fPdfDoc); 2281131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 2282131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com if (extGStateDictionary == NULL) { 2283e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kMissingExtGState_SkPdfIssue, NULL, 2284e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com pdfContext->fGraphicsState.fResources, pdfContext); 22853aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kIgnoreError_SkPdfResult; 2286131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 2287131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 2288e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfNativeObject* value 2289e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com = pdfContext->fPdfDoc->resolveReference(extGStateDictionary->get(name)); 2290131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 2291e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com if (kNone_SkPdfNativeObjectType == 2292e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com pdfContext->fPdfDoc->mapper()->mapGraphicsStateDictionary(value)) { 22933aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kIgnoreError_SkPdfResult; 2294571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 2295571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com SkPdfGraphicsStateDictionary* gs = (SkPdfGraphicsStateDictionary*)value; 2296131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 2297131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com if (gs == NULL) { 2298e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, 2299e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com gs, SkPdfNativeObject::kDictionary_PdfObjectType, pdfContext); 23003aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kIgnoreError_SkPdfResult; 2301131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 2302131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 2303a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com if (gs->has_LW()) { 2304a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com skpdfGraphicsStateApplyLW(pdfContext, gs->LW(pdfContext->fPdfDoc)); 2305a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com } 2306a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com 2307a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com if (gs->has_LC()) { 2308a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com skpdfGraphicsStateApplyLC(pdfContext, gs->LC(pdfContext->fPdfDoc)); 2309a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com } 2310a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com 2311a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com if (gs->has_LJ()) { 2312a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com skpdfGraphicsStateApplyLJ(pdfContext, gs->LJ(pdfContext->fPdfDoc)); 2313a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com } 2314a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com 2315a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com if (gs->has_ML()) { 2316a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com skpdfGraphicsStateApplyML(pdfContext, gs->ML(pdfContext->fPdfDoc)); 2317a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com } 2318a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com 2319a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com if (gs->has_D()) { 2320a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com skpdfGraphicsStateApplyD(pdfContext, gs->D(pdfContext->fPdfDoc)); 2321a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com } 2322a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com 2323a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com if (gs->has_Font()) { 2324a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com skpdfGraphicsStateApplyFont(pdfContext, gs->Font(pdfContext->fPdfDoc)); 2325a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com } 2326a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com 2327a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com if (gs->has_BM()) { 2328a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com if (gs->isBMAName(pdfContext->fPdfDoc)) { 2329a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com skpdfGraphicsStateApplyBM_name(pdfContext, gs->getBMAsName(pdfContext->fPdfDoc)); 2330a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com } else if (gs->isBMAArray(pdfContext->fPdfDoc)) { 2331a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com skpdfGraphicsStateApplyBM_array(pdfContext, gs->getBMAsArray(pdfContext->fPdfDoc)); 2332a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com } else { 2333e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, "wrong type", gs->get("BM"), 23345e4d9819dbcbfbbdbd2ad2840b9c1b2b01c98db1edisonn@google.com SkPdfNativeObject::kArray_PdfObjectType | 2335e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfNativeObject::kName_PdfObjectType, pdfContext); 2336a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com } 2337a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com } 2338a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com 2339a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com if (gs->has_SMask()) { 2340a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com if (gs->isSMaskAName(pdfContext->fPdfDoc)) { 2341a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com skpdfGraphicsStateApplySMask_name(pdfContext, gs->getSMaskAsName(pdfContext->fPdfDoc)); 2342a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com } else if (gs->isSMaskADictionary(pdfContext->fPdfDoc)) { 2343e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com skpdfGraphicsStateApplySMask_dict(pdfContext, 2344e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com gs->getSMaskAsDictionary(pdfContext->fPdfDoc)); 2345a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com } else { 2346e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, 2347e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com "wrong type", 2348e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com gs->get("BM"), 23495e4d9819dbcbfbbdbd2ad2840b9c1b2b01c98db1edisonn@google.com SkPdfNativeObject::kDictionary_PdfObjectType | 2350e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfNativeObject::kName_PdfObjectType, 2351e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com pdfContext); 2352a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com } 2353131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 2354131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 2355131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com if (gs->has_ca()) { 2356a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com skpdfGraphicsStateApply_ca(pdfContext, gs->ca(pdfContext->fPdfDoc)); 2357131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 2358131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 2359a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com if (gs->has_CA()) { 2360a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com skpdfGraphicsStateApply_CA(pdfContext, gs->CA(pdfContext->fPdfDoc)); 2361a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com } 2362a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com 2363a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com if (gs->has_AIS()) { 2364a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com skpdfGraphicsStateApplyAIS(pdfContext, gs->AIS(pdfContext->fPdfDoc)); 2365131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 2366131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 2367e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com // TODO(edisonn): make sure we loaded all those properties in graphic state. 2368e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com 23693aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kOK_SkPdfResult; 2370131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 2371131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 2372131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com//charSpace Tc Set the character spacing, Tc 2373e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com//, to charSpace, which is a number expressed in unscaled text space units. 2374e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com// Character spacing is used by the Tj, TJ, and ' operators. 2375131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com//Initial value: 0. 237636026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comSkPdfResult PdfOp_Tc(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 2377af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com EXPECT_OPERANDS("Tc", pdfContext, 1); 2378bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, charSpace); 2379bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com CHECK_PARAMETERS(); 2380bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com 2381131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com pdfContext->fGraphicsState.fCharSpace = charSpace; 2382131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 23833aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kOK_SkPdfResult; 2384131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 2385131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 2386131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com//wordSpace Tw Set the word spacing, T 2387131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com//w 2388131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com//, to wordSpace, which is a number expressed in unscaled 2389131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com//text space units. Word spacing is used by the Tj, TJ, and ' operators. Initial 2390131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com//value: 0. 239136026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comSkPdfResult PdfOp_Tw(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 2392af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com EXPECT_OPERANDS("Tw", pdfContext, 1); 2393bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, wordSpace); 2394bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com CHECK_PARAMETERS(); 2395bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com 2396131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com pdfContext->fGraphicsState.fWordSpace = wordSpace; 2397131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 23983aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kOK_SkPdfResult; 2399131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 2400131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 2401131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com//scale Tz Set the horizontal scaling, Th 2402131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com//, to (scale ˜ 100). scale is a number specifying the 2403131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com//percentage of the normal width. Initial value: 100 (normal width). 240436026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_Tz(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 2405af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com EXPECT_OPERANDS("Tz", pdfContext, 1); 2406bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, scale); 2407bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com CHECK_PARAMETERS(); 2408bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com 2409bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com if (scale < 0) { 2410e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kOutOfRange_SkPdfIssue, 2411e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com "scale must a positive real number", scale_obj, pdfContext); 2412bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com return kError_SkPdfResult; 2413bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com } 2414131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 24153aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kNYI_SkPdfResult; 2416131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 2417131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 2418131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com//render Tr Set the text rendering mode, T 2419131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com//mode, to render, which is an integer. Initial value: 0. 242036026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_Tr(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 2421af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com EXPECT_OPERANDS("Tr", pdfContext, 1); 2422bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_INTEGER(pdfContext, mode); 2423bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com CHECK_PARAMETERS(); 2424bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com 2425bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com if (mode < 0) { // TODO(edisonn): function/enums with supported modes 2426e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kOutOfRange_SkPdfIssue, 2427e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com "mode must a positive integer or 0", mode_obj, pdfContext); 2428bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com return kError_SkPdfResult; 2429bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com } 2430131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 24313aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kNYI_SkPdfResult; 2432131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 2433131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com//rise Ts Set the text rise, Trise, to rise, which is a number expressed in unscaled text space 2434131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com//units. Initial value: 0. 243536026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_Ts(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 2436af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com EXPECT_OPERANDS("Ts", pdfContext, 1); 2437bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, rise); 2438bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com CHECK_PARAMETERS(); 2439bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com 2440bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com if (rise < 0) { 2441e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kOutOfRange_SkPdfIssue, 2442e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com "rise must a positive real number", rise_obj, pdfContext); 2443bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com return kNYI_SkPdfResult; 2444bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com } 2445131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 24463aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kNYI_SkPdfResult; 2447131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 2448131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 2449131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com//wx wy d0 245036026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_d0(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 2451af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com EXPECT_OPERANDS("d0", pdfContext, 2); 2452bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, wy); 2453bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, wx); 2454bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com CHECK_PARAMETERS(); 2455bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com 2456af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com if (wx < 0) { 2457e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kOutOfRange_SkPdfIssue, 2458e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com "wx must a positive real number", wx_obj, pdfContext); 2459af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com return kError_SkPdfResult; 2460af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com } 2461af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com 2462af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com if (wy < 0) { 2463e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kOutOfRange_SkPdfIssue, 2464e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com "wy must a positive real number", wy_obj, pdfContext); 2465bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com return kError_SkPdfResult; 2466bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com } 2467131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 24683aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kNYI_SkPdfResult; 2469131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 2470131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 2471131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com//wx wy llx lly urx ury d1 247236026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_d1(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 2473af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com EXPECT_OPERANDS("d1", pdfContext, 6); 2474bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, ury); 2475bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, urx); 2476bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, lly); 2477bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, llx); 2478bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, wy); 2479bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NUMBER(pdfContext, wx); 2480bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com CHECK_PARAMETERS(); 2481bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com 2482e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com // TODO(edisonn): really silly quick way to remove warning 2483bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com if (wx + wy + llx + lly + urx + ury) { 2484bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com return kNYI_SkPdfResult; 2485bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com } 2486131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 24873aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kNYI_SkPdfResult; 2488131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 2489131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 2490131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com//name sh 249136026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_sh(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 2492af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com EXPECT_OPERANDS("sh", pdfContext, 1); 2493bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NAME(pdfContext, name); 2494bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com CHECK_PARAMETERS(); 2495bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com 2496bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com if (name == NULL) { 2497e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, name, 2498e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfNativeObject::kName_PdfObjectType, pdfContext); 2499bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com return kError_SkPdfResult; 2500bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com } 2501131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 25023aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kNYI_SkPdfResult; 2503131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 2504131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 2505131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com//name Do 250636026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_Do(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 2507af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com EXPECT_OPERANDS("Do", pdfContext, 1); 2508bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_NAME(pdfContext, name); 2509bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com CHECK_PARAMETERS(); 2510131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 2511571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com SkPdfDictionary* xObject = pdfContext->fGraphicsState.fResources->XObject(pdfContext->fPdfDoc); 2512131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 2513131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com if (xObject == NULL) { 2514e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kMissingXObject_SkPdfIssue, NULL, 2515e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com pdfContext->fGraphicsState.fResources, pdfContext); 25163aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kIgnoreError_SkPdfResult; 2517131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 2518131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 25193aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com SkPdfNativeObject* value = xObject->get(name); 2520571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com value = pdfContext->fPdfDoc->resolveReference(value); 2521131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 2522571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com return doXObject(pdfContext, canvas, value); 2523131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 2524131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 2525131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com//tag MP Designate a marked-content point. tag is a name object indicating the role or 2526131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com//significance of the point. 252736026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_MP(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 2528af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com EXPECT_OPERANDS("MP", pdfContext, 1); 2529bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_OBJ(pdfContext, tag); 2530bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com CHECK_PARAMETERS(); 2531bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com 2532bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com if (tag == NULL) { 2533e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, tag, 2534e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfNativeObject::_kObject_PdfObjectType, pdfContext); 2535bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com return kNYI_SkPdfResult; 2536bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com } 2537131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 2538af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, "MP NYI", NULL, NULL); 25393aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kNYI_SkPdfResult; 2540131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 2541131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 2542131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com//tag properties DP Designate a marked-content point with an associated property list. tag is a 2543131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com//name object indicating the role or significance of the point; properties is 2544131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com//either an inline dictionary containing the property list or a name object 2545131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com//associated with it in the Properties subdictionary of the current resource 2546131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com//dictionary (see Section 9.5.1, “Property Lists”). 254736026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_DP(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 2548af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com EXPECT_OPERANDS("DP", pdfContext, 2); 2549bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_OBJ(pdfContext, properties); 2550bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_OBJ(pdfContext, tag); 2551bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com CHECK_PARAMETERS(); 2552bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com 2553af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com if (tag == NULL) { 2554e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, tag, 2555e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfNativeObject::_kObject_PdfObjectType, pdfContext); 2556af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com return kNYI_SkPdfResult; 2557af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com } 2558af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com 2559af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com if (properties == NULL) { 2560e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, properties, 2561e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfNativeObject::_kObject_PdfObjectType, pdfContext); 2562bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com return kNYI_SkPdfResult; 2563bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com } 2564131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 2565af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, "DP NYI", NULL, NULL); 25663aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kNYI_SkPdfResult; 2567131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 2568131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 2569131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com//tag BMC Begin a marked-content sequence terminated by a balancing EMC operator. 2570131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com//tag is a name object indicating the role or significance of the sequence. 257136026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_BMC(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 2572af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com EXPECT_OPERANDS("BMC", pdfContext, 1); 2573bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_OBJ(pdfContext, tag); 2574bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com CHECK_PARAMETERS(); 2575bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com 2576bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com if (tag == NULL) { 2577e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, tag, 2578e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfNativeObject::_kObject_PdfObjectType, pdfContext); 2579bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com return kNYI_SkPdfResult; 2580bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com } 2581131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 2582af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, "BMC NYI", NULL, NULL); 25833aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kNYI_SkPdfResult; 2584131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 2585131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 2586131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com//tag properties BDC Begin a marked-content sequence with an associated property list, terminated 2587e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com//by a balancing EMCoperator. tag is a name object indicating the role or significance of the 2588e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com// sequence; propertiesis either an inline dictionary containing the 2589e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com//property list or a name object associated with it in the Properties subdictionary of the current 2590e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com//resource dictionary (see Section 9.5.1, “Property Lists”). 259136026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_BDC(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 2592af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com EXPECT_OPERANDS("BDC", pdfContext, 2); 2593bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_OBJ(pdfContext, properties); 2594bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com POP_OBJ(pdfContext, tag); 2595bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com CHECK_PARAMETERS(); 2596bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com 2597af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com if (tag == NULL) { 2598e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, tag, 2599e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfNativeObject::_kObject_PdfObjectType, pdfContext); 2600af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com return kNYI_SkPdfResult; 2601af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com } 2602af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com 2603af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com if (properties == NULL) { 2604e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, properties, 2605e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPdfNativeObject::_kObject_PdfObjectType, pdfContext); 2606bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com return kNYI_SkPdfResult; 2607bd2f30132e1433b4dd1276e59a03fc70fd8209d7edisonn@google.com } 2608131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 2609af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, "BDC NYI", NULL, NULL); 26103aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kNYI_SkPdfResult; 2611131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 2612131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 2613131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com//— EMC End a marked-content sequence begun by a BMC or BDC operator. 261436026de64400cbe91552c549cf9a906a0926fef3scroggo@google.comstatic SkPdfResult PdfOp_EMC(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper*) { 2615af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, "EMC NYI", NULL, NULL); 26163aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kNYI_SkPdfResult; 2617131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 2618131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 2619248647cebb3724fd2ce1d41745afb786516af4f8scroggo@google.com#include "SkPdfOps.h" 2620248647cebb3724fd2ce1d41745afb786516af4f8scroggo@google.com 2621248647cebb3724fd2ce1d41745afb786516af4f8scroggo@google.comSkTDict<PdfOperatorRenderer> gPdfOps(100); 2622248647cebb3724fd2ce1d41745afb786516af4f8scroggo@google.com 2623a3356fce903ff75dc332b53dd3a860ba810b9519edisonn@google.comstatic void initPdfOperatorRenderes() { 2624131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com static bool gInitialized = false; 2625131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com if (gInitialized) { 2626131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com return; 2627131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 2628131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 26292ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("q", PdfOp_q); 26302ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("Q", PdfOp_Q); 26312ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("cm", PdfOp_cm); 26322ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com 26332ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("TD", PdfOp_TD); 26342ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("Td", PdfOp_Td); 26352ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("Tm", PdfOp_Tm); 26362ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("T*", PdfOp_T_star); 26372ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com 26382ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("m", PdfOp_m); 26392ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("l", PdfOp_l); 26402ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("c", PdfOp_c); 26412ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("v", PdfOp_v); 26422ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("y", PdfOp_y); 26432ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("h", PdfOp_h); 26442ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("re", PdfOp_re); 26452ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com 26462ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("S", PdfOp_S); 26472ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("s", PdfOp_s); 26482ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("f", PdfOp_f); 26492ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("F", PdfOp_F); 26502ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("f*", PdfOp_f_star); 26512ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("B", PdfOp_B); 26522ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("B*", PdfOp_B_star); 26532ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("b", PdfOp_b); 26542ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("b*", PdfOp_b_star); 26552ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("n", PdfOp_n); 26562ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com 26572ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("BT", PdfOp_BT); 26582ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("ET", PdfOp_ET); 26592ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com 26602ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("Tj", PdfOp_Tj); 26612ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("'", PdfOp_quote); 26622ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("\"", PdfOp_doublequote); 26632ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("TJ", PdfOp_TJ); 26642ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com 26652ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("CS", PdfOp_CS); 26662ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("cs", PdfOp_cs); 26672ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("SC", PdfOp_SC); 26682ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("SCN", PdfOp_SCN); 26692ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("sc", PdfOp_sc); 26702ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("scn", PdfOp_scn); 26712ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("G", PdfOp_G); 26722ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("g", PdfOp_g); 26732ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("RG", PdfOp_RG); 26742ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("rg", PdfOp_rg); 26752ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("K", PdfOp_K); 26762ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("k", PdfOp_k); 26772ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com 26782ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("W", PdfOp_W); 26792ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("W*", PdfOp_W_star); 26802ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com 26812ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("BX", PdfOp_BX); 26822ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("EX", PdfOp_EX); 26832ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com 26842ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("BI", PdfOp_BI); 26852ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("ID", PdfOp_ID); 26862ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("EI", PdfOp_EI); 26872ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com 26882ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("w", PdfOp_w); 26892ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("J", PdfOp_J); 26902ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("j", PdfOp_j); 26912ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("M", PdfOp_M); 26922ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("d", PdfOp_d); 26932ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("ri", PdfOp_ri); 26942ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("i", PdfOp_i); 26952ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("gs", PdfOp_gs); 26962ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com 26972ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("Tc", PdfOp_Tc); 26982ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("Tw", PdfOp_Tw); 26992ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("Tz", PdfOp_Tz); 27002ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("TL", PdfOp_TL); 27012ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("Tf", PdfOp_Tf); 27022ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("Tr", PdfOp_Tr); 27032ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("Ts", PdfOp_Ts); 27042ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com 27052ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("d0", PdfOp_d0); 27062ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("d1", PdfOp_d1); 27072ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com 27082ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("sh", PdfOp_sh); 27092ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com 27102ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("Do", PdfOp_Do); 27112ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com 27122ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("MP", PdfOp_MP); 27132ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("DP", PdfOp_DP); 27142ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("BMC", PdfOp_BMC); 27152ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("BDC", PdfOp_BDC); 27162ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com gPdfOps.set("EMC", PdfOp_EMC); 2717131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 2718131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com gInitialized = true; 2719131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 2720131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 2721131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.comclass InitPdfOps { 2722131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.compublic: 2723131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com InitPdfOps() { 2724131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com initPdfOperatorRenderes(); 2725131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 2726131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com}; 2727131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 2728131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.comInitPdfOps gInitPdfOps; 2729131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 27303aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.comSkPdfResult PdfInlineImageLooper::consumeToken(PdfToken& token) { 273178b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com SkASSERT(false); 27323aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return kIgnoreError_SkPdfResult; 2733131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 2734131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 2735131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.comvoid PdfInlineImageLooper::loop() { 273636026de64400cbe91552c549cf9a906a0926fef3scroggo@google.com // FIXME (scroggo): Does this need to be looper? It does not consumeTokens, 273736026de64400cbe91552c549cf9a906a0926fef3scroggo@google.com // nor does it loop. The one thing it does is provide access to the 273836026de64400cbe91552c549cf9a906a0926fef3scroggo@google.com // protected members of SkPdfTokenLooper. 273978b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com doXObject_Image(fPdfContext, fCanvas, fTokenizer->readInlineImage()); 2740131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 2741131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 27423aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.comSkPdfResult PdfCompatibilitySectionLooper::consumeToken(PdfToken& token) { 2743131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com return fParent->consumeToken(token); 2744131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 2745131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 2746131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.comvoid PdfCompatibilitySectionLooper::loop() { 2747e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com PdfOp_q(fPdfContext, fCanvas, NULL); 2748e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com 2749131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com PdfToken token; 27505092adc5461a7c5cb3e1fad01be2174c3f4a0c46scroggo@google.com while (fTokenizer->readToken(&token)) { 2751131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com if (token.fType == kKeyword_TokenType && strcmp(token.fKeyword, "BX") == 0) { 275236026de64400cbe91552c549cf9a906a0926fef3scroggo@google.com PdfCompatibilitySectionLooper looper(this); 275336026de64400cbe91552c549cf9a906a0926fef3scroggo@google.com looper.loop(); 2754131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } else { 275536026de64400cbe91552c549cf9a906a0926fef3scroggo@google.com if (token.fType == kKeyword_TokenType && strcmp(token.fKeyword, "EX") == 0) { 275636026de64400cbe91552c549cf9a906a0926fef3scroggo@google.com break; 275736026de64400cbe91552c549cf9a906a0926fef3scroggo@google.com } 2758131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com fParent->consumeToken(token); 2759131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 2760131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com } 2761131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 2762e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com PdfOp_Q(fPdfContext, fCanvas, NULL); 2763e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com} 2764131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 2765e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com// TODO(edisonn): for debugging - remove or put it in a #ifdef 27663aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.comSkPdfContext* gPdfContext = NULL; 27673aac1f9f308192f3787265830fe86ce8874e7382edisonn@google.com 2768444e25a66b6a1547fa0903d0cf075a0885a76bb7edisonn@google.combool SkPdfRenderer::renderPage(int page, SkCanvas* canvas, const SkRect& dst) const { 2769222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com if (!fPdfDoc) { 27703aac1f9f308192f3787265830fe86ce8874e7382edisonn@google.com return false; 2771222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com } 2772131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 2773222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com if (page < 0 || page >= pages()) { 2774222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com return false; 2775222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com } 2776131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com 27773aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com SkPdfContext pdfContext(fPdfDoc); 27782ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com 2779b1de123336246ad970e8a593267c37cc3be8105cscroggo@google.com // FIXME (scroggo): Is this matrix needed? 2780222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com pdfContext.fOriginalMatrix = SkMatrix::I(); 2781222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com pdfContext.fGraphicsState.fResources = fPdfDoc->pageResources(page); 2782222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com 2783222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com gPdfContext = &pdfContext; 2784222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com 2785222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com SkScalar z = SkIntToScalar(0); 2786444e25a66b6a1547fa0903d0cf075a0885a76bb7edisonn@google.com SkScalar w = dst.width(); 2787444e25a66b6a1547fa0903d0cf075a0885a76bb7edisonn@google.com SkScalar h = dst.height(); 2788222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com 2789f68aed33819cbc98a95edeadde1da9303eca7fb2edisonn@google.com if (SkScalarTruncToInt(w) <= 0 || SkScalarTruncToInt(h) <= 0) { 2790f68aed33819cbc98a95edeadde1da9303eca7fb2edisonn@google.com return true; 2791f68aed33819cbc98a95edeadde1da9303eca7fb2edisonn@google.com } 2792f68aed33819cbc98a95edeadde1da9303eca7fb2edisonn@google.com 2793b1de123336246ad970e8a593267c37cc3be8105cscroggo@google.com // FIXME (scroggo): The media box may not be anchored at 0,0. Is this okay? 2794444e25a66b6a1547fa0903d0cf075a0885a76bb7edisonn@google.com SkScalar wp = fPdfDoc->MediaBox(page).width(); 2795444e25a66b6a1547fa0903d0cf075a0885a76bb7edisonn@google.com SkScalar hp = fPdfDoc->MediaBox(page).height(); 2796444e25a66b6a1547fa0903d0cf075a0885a76bb7edisonn@google.com 2797e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPoint pdfSpace[4] = {SkPoint::Make(z, z), 2798e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPoint::Make(wp, z), 2799e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPoint::Make(wp, hp), 2800e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPoint::Make(z, hp)}; 28013aac1f9f308192f3787265830fe86ce8874e7382edisonn@google.com 2802e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com#ifdef PDF_DEBUG_3X 2803222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com // Use larger image to make sure we do not draw anything outside of page 2804222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com // could be used in tests. 2805e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPoint skiaSpace[4] = {SkPoint::Make(w+z, h+h), 2806e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPoint::Make(w+w, h+h), 2807e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPoint::Make(w+w, h+z), 2808e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPoint::Make(w+z, h+z)}; 28093aac1f9f308192f3787265830fe86ce8874e7382edisonn@google.com#else 2810e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPoint skiaSpace[4] = {SkPoint::Make(z, h), 2811e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPoint::Make(w, h), 2812e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPoint::Make(w, z), 2813e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com SkPoint::Make(z, z)}; 28143aac1f9f308192f3787265830fe86ce8874e7382edisonn@google.com#endif 2815222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com 2816222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com SkAssertResult(pdfContext.fOriginalMatrix.setPolyToPoly(pdfSpace, skiaSpace, 4)); 2817222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com SkTraceMatrix(pdfContext.fOriginalMatrix, "Original matrix"); 2818222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com 2819b1de123336246ad970e8a593267c37cc3be8105cscroggo@google.com // FIXME (scroggo): Do we need to translate to account for the fact that 2820b1de123336246ad970e8a593267c37cc3be8105cscroggo@google.com // the media box (or the destination rect) may not be anchored at 0,0? 2821d03c2c732e2e914f8429cfc8b077a7b9b853dd8eedisonn@google.com pdfContext.fOriginalMatrix.postConcat(canvas->getTotalMatrix()); 2822d03c2c732e2e914f8429cfc8b077a7b9b853dd8eedisonn@google.com 2823a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com pdfContext.fGraphicsState.fCTM = pdfContext.fOriginalMatrix; 28240f9019008405ad48d73878db9b2d2ee82f90c6bdedisonn@google.com pdfContext.fGraphicsState.fContentStreamMatrix = pdfContext.fOriginalMatrix; 2825a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com pdfContext.fGraphicsState.fMatrixTm = pdfContext.fGraphicsState.fCTM; 2826a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com pdfContext.fGraphicsState.fMatrixTlm = pdfContext.fGraphicsState.fCTM; 2827222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com 2828222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com#ifndef PDF_DEBUG_NO_PAGE_CLIPING 2829444e25a66b6a1547fa0903d0cf075a0885a76bb7edisonn@google.com canvas->clipRect(dst, SkRegion::kIntersect_Op, true); 2830222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com#endif 2831222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com 2832b1de123336246ad970e8a593267c37cc3be8105cscroggo@google.com // FIXME (scroggo): This concat may not be necessary, since we generally 2833b1de123336246ad970e8a593267c37cc3be8105cscroggo@google.com // call SkCanvas::setMatrix() before using the canvas. 2834d03c2c732e2e914f8429cfc8b077a7b9b853dd8eedisonn@google.com canvas->concat(pdfContext.fOriginalMatrix); 2835444e25a66b6a1547fa0903d0cf075a0885a76bb7edisonn@google.com 283688fc03dd1f47ad33b08d60c47013de860f8fa69fedisonn@google.com doPage(&pdfContext, canvas, fPdfDoc->page(page)); 283788fc03dd1f47ad33b08d60c47013de860f8fa69fedisonn@google.com 2838e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com // TODO(edisonn:) erase with white before draw? Right now the caller is responsible. 2839222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com// SkPaint paint; 284088fc03dd1f47ad33b08d60c47013de860f8fa69fedisonn@google.com// paint.setColor(SK_ColorWHITE); 2841222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com// canvas->drawRect(rect, paint); 2842222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com 2843222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com 2844222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com canvas->flush(); 2845131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com return true; 2846131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com} 2847222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com 2848909228992c1671ea7451d1c6bc588a8ec991841escroggo@google.comSkPdfRenderer* SkPdfRenderer::CreateFromFile(const char* inputFileName) { 2849909228992c1671ea7451d1c6bc588a8ec991841escroggo@google.com // FIXME: SkPdfNativeDoc should have a similar Create function. 2850909228992c1671ea7451d1c6bc588a8ec991841escroggo@google.com SkPdfNativeDoc* pdfDoc = SkNEW_ARGS(SkPdfNativeDoc, (inputFileName)); 2851909228992c1671ea7451d1c6bc588a8ec991841escroggo@google.com if (pdfDoc->pages() == 0) { 2852909228992c1671ea7451d1c6bc588a8ec991841escroggo@google.com SkDELETE(pdfDoc); 2853909228992c1671ea7451d1c6bc588a8ec991841escroggo@google.com return NULL; 28546a9d436260582b9453de37877b6e00c2dd24f33aedisonn@google.com } 2855222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com 2856909228992c1671ea7451d1c6bc588a8ec991841escroggo@google.com return SkNEW_ARGS(SkPdfRenderer, (pdfDoc)); 2857222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com} 2858222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com 2859909228992c1671ea7451d1c6bc588a8ec991841escroggo@google.comSkPdfRenderer* SkPdfRenderer::CreateFromStream(SkStream* stream) { 2860147adb10f7f80ae721879e08474fd575e719487cedisonn@google.com // TODO(edisonn): create static function that could return NULL if there are errors 2861909228992c1671ea7451d1c6bc588a8ec991841escroggo@google.com SkPdfNativeDoc* pdfDoc = SkNEW_ARGS(SkPdfNativeDoc, (stream)); 2862909228992c1671ea7451d1c6bc588a8ec991841escroggo@google.com if (pdfDoc->pages() == 0) { 2863909228992c1671ea7451d1c6bc588a8ec991841escroggo@google.com SkDELETE(pdfDoc); 2864909228992c1671ea7451d1c6bc588a8ec991841escroggo@google.com return NULL; 2865147adb10f7f80ae721879e08474fd575e719487cedisonn@google.com } 2866147adb10f7f80ae721879e08474fd575e719487cedisonn@google.com 2867909228992c1671ea7451d1c6bc588a8ec991841escroggo@google.com return SkNEW_ARGS(SkPdfRenderer, (pdfDoc)); 2868147adb10f7f80ae721879e08474fd575e719487cedisonn@google.com} 2869147adb10f7f80ae721879e08474fd575e719487cedisonn@google.com 2870909228992c1671ea7451d1c6bc588a8ec991841escroggo@google.comSkPdfRenderer::SkPdfRenderer(SkPdfNativeDoc* doc) 2871909228992c1671ea7451d1c6bc588a8ec991841escroggo@google.com :fPdfDoc(doc) { 2872909228992c1671ea7451d1c6bc588a8ec991841escroggo@google.com} 2873147adb10f7f80ae721879e08474fd575e719487cedisonn@google.com 2874909228992c1671ea7451d1c6bc588a8ec991841escroggo@google.comSkPdfRenderer::~SkPdfRenderer() { 2875909228992c1671ea7451d1c6bc588a8ec991841escroggo@google.com SkDELETE(fPdfDoc); 2876222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com} 2877222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com 2878909228992c1671ea7451d1c6bc588a8ec991841escroggo@google.comint SkPdfRenderer::pages() const { 2879909228992c1671ea7451d1c6bc588a8ec991841escroggo@google.com SkASSERT(fPdfDoc != NULL); 2880909228992c1671ea7451d1c6bc588a8ec991841escroggo@google.com return fPdfDoc->pages(); 2881222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com} 2882222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com 2883222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.comSkRect SkPdfRenderer::MediaBox(int page) const { 2884909228992c1671ea7451d1c6bc588a8ec991841escroggo@google.com SkASSERT(fPdfDoc != NULL); 2885222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com return fPdfDoc->MediaBox(page); 2886222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com} 2887a5aaa7998fc18489701660f781d7daa33ffc6f6eedisonn@google.com 28887b328fddf94eea5f05ffa36de02d7d9922f504daedisonn@google.comsize_t SkPdfRenderer::bytesUsed() const { 2889909228992c1671ea7451d1c6bc588a8ec991841escroggo@google.com SkASSERT(fPdfDoc != NULL); 2890909228992c1671ea7451d1c6bc588a8ec991841escroggo@google.com return fPdfDoc->bytesUsed(); 2891a5aaa7998fc18489701660f781d7daa33ffc6f6eedisonn@google.com} 2892147adb10f7f80ae721879e08474fd575e719487cedisonn@google.com 2893147adb10f7f80ae721879e08474fd575e719487cedisonn@google.combool SkPDFNativeRenderToBitmap(SkStream* stream, 2894147adb10f7f80ae721879e08474fd575e719487cedisonn@google.com SkBitmap* output, 2895147adb10f7f80ae721879e08474fd575e719487cedisonn@google.com int page, 2896909228992c1671ea7451d1c6bc588a8ec991841escroggo@google.com SkPdfContent unused, 2897147adb10f7f80ae721879e08474fd575e719487cedisonn@google.com double dpi) { 2898147adb10f7f80ae721879e08474fd575e719487cedisonn@google.com SkASSERT(page >= 0); 2899909228992c1671ea7451d1c6bc588a8ec991841escroggo@google.com SkPdfRenderer* renderer = SkPdfRenderer::CreateFromStream(stream); 2900909228992c1671ea7451d1c6bc588a8ec991841escroggo@google.com if (NULL == renderer) { 2901147adb10f7f80ae721879e08474fd575e719487cedisonn@google.com return false; 2902147adb10f7f80ae721879e08474fd575e719487cedisonn@google.com } 2903147adb10f7f80ae721879e08474fd575e719487cedisonn@google.com 2904909228992c1671ea7451d1c6bc588a8ec991841escroggo@google.com SkRect rect = renderer->MediaBox(page < 0 ? 0 :page); 2905147adb10f7f80ae721879e08474fd575e719487cedisonn@google.com 2906909228992c1671ea7451d1c6bc588a8ec991841escroggo@google.com SkScalar width = SkScalarMul(rect.width(), SkDoubleToScalar(dpi / 72.0)); 2907909228992c1671ea7451d1c6bc588a8ec991841escroggo@google.com SkScalar height = SkScalarMul(rect.height(), SkDoubleToScalar(dpi / 72.0)); 2908147adb10f7f80ae721879e08474fd575e719487cedisonn@google.com 2909147adb10f7f80ae721879e08474fd575e719487cedisonn@google.com rect = SkRect::MakeWH(width, height); 2910147adb10f7f80ae721879e08474fd575e719487cedisonn@google.com 2911909228992c1671ea7451d1c6bc588a8ec991841escroggo@google.com setup_bitmap(output, SkScalarCeilToInt(width), SkScalarCeilToInt(height)); 2912147adb10f7f80ae721879e08474fd575e719487cedisonn@google.com 29131f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkAutoTUnref<SkBaseDevice> device(SkNEW_ARGS(SkBitmapDevice, (*output))); 2914147adb10f7f80ae721879e08474fd575e719487cedisonn@google.com SkCanvas canvas(device); 2915147adb10f7f80ae721879e08474fd575e719487cedisonn@google.com 2916909228992c1671ea7451d1c6bc588a8ec991841escroggo@google.com return renderer->renderPage(page, &canvas, rect); 2917147adb10f7f80ae721879e08474fd575e719487cedisonn@google.com} 2918