pdfviewer: add macros to automatically check number and type of parameters

Review URL: https://codereview.chromium.org/23038021

git-svn-id: http://skia.googlecode.com/svn/trunk@10872 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
edisonn@google.com 2013-08-22 14:18:04 +00:00
parent 37c18e4e38
commit bd2f30132e

View File

@ -71,6 +71,116 @@ __SK_FORCE_IMAGE_DECODER_LINKING;
* - deal with specific type in spec directly, add all dictionary types to known types
*/
#define EXPECT_OPERANDS(pdfContext,n) \
bool __failed = pdfContext->fObjectStack.count() < n; \
SkDEBUGCODE(int __cnt = n);
#define POP_OBJ(pdfContext,name) \
SkDEBUGCODE(__cnt--); \
SkASSERT(__cnt >= 0); \
SkPdfNativeObject* name = NULL; \
__failed = __failed || pdfContext->fObjectStack.count() == 0; \
if (pdfContext->fObjectStack.count() > 0) { \
name = pdfContext->fObjectStack.top(); \
pdfContext->fObjectStack.pop(); \
}
#define POP_NUMBER(pdfContext,name) \
SkDEBUGCODE(__cnt--); \
SkASSERT(__cnt >= 0); \
double name = 0; \
__failed = __failed || pdfContext->fObjectStack.count() == 0; \
if (pdfContext->fObjectStack.count() > 0) { \
SkPdfNativeObject* tmp = pdfContext->fObjectStack.top(); \
pdfContext->fObjectStack.pop(); \
if (!tmp || !tmp->isNumber()) { \
__failed = true;\
} else { \
name = tmp->numberValue(); \
} \
}
#define POP_INTEGER(pdfContext,name) \
SkDEBUGCODE(__cnt--); \
SkASSERT(__cnt >= 0); \
int64_t name = 0; \
__failed = __failed || pdfContext->fObjectStack.count() == 0; \
if (pdfContext->fObjectStack.count() > 0) { \
SkPdfNativeObject* tmp = pdfContext->fObjectStack.top(); \
pdfContext->fObjectStack.pop(); \
if (!tmp || !tmp->isInteger()) { \
__failed = true;\
} else { \
name = tmp->intValue(); \
} \
}
#define POP_NUMBER_INTO(pdfContext,var) \
SkDEBUGCODE(__cnt--); \
SkASSERT(__cnt >= 0); \
__failed = __failed || pdfContext->fObjectStack.count() == 0; \
if (pdfContext->fObjectStack.count() > 0) { \
SkPdfNativeObject* tmp = pdfContext->fObjectStack.top(); \
pdfContext->fObjectStack.pop(); \
if (!tmp || !tmp->isNumber()) { \
__failed = true;\
} else { \
var = tmp->numberValue(); \
} \
}
#define POP_NAME(pdfContext,name) \
SkDEBUGCODE(__cnt--); \
SkASSERT(__cnt >= 0); \
SkPdfNativeObject* name = NULL; \
__failed = __failed || pdfContext->fObjectStack.count() == 0; \
if (pdfContext->fObjectStack.count() > 0) { \
SkPdfNativeObject* tmp = pdfContext->fObjectStack.top(); \
pdfContext->fObjectStack.pop(); \
if (!tmp || !tmp->isName()) { \
__failed = true;\
} else { \
name = tmp; \
} \
}
#define POP_STRING(pdfContext,name) \
SkDEBUGCODE(__cnt--); \
SkASSERT(__cnt >= 0); \
SkPdfNativeObject* name = NULL; \
__failed = __failed || pdfContext->fObjectStack.count() == 0; \
if (pdfContext->fObjectStack.count() > 0) { \
SkPdfNativeObject* tmp = pdfContext->fObjectStack.top(); \
pdfContext->fObjectStack.pop(); \
if (!tmp || !tmp->isAnyString()) { \
__failed = true;\
} else { \
name = tmp; \
} \
}
#define POP_ARRAY(pdfContext,name) \
SkDEBUGCODE(__cnt--); \
SkASSERT(__cnt >= 0); \
SkPdfArray* name = NULL; \
__failed = __failed || pdfContext->fObjectStack.count() == 0; \
if (pdfContext->fObjectStack.count() > 0) { \
SkPdfNativeObject* tmp = pdfContext->fObjectStack.top(); \
pdfContext->fObjectStack.pop(); \
if (!tmp || !tmp->isArray()) { \
__failed = true;\
} else { \
name = (SkPdfArray*)tmp; \
} \
}
// TODO(edisonn): ability to turn on asserts for known good files
// log error - add name of function? location in file?
#define CHECK_PARAMETERS() \
SkASSERT(__cnt == 0); \
if (__failed) return kIgnoreError_SkPdfResult;
NotOwnedString strings_DeviceRGB;
NotOwnedString strings_DeviceCMYK;
@ -971,6 +1081,8 @@ static SkPdfResult doPage(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfPageO
}
SkPdfResult PdfOp_q(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
// TODO(edisonn): create a new stack of parameters, so once we start a q,
// it is not possible to see under the previous q?
pdfContext->fStateStack.push(pdfContext->fGraphicsState);
canvas->save();
return kOK_SkPdfResult;
@ -984,11 +1096,15 @@ SkPdfResult PdfOp_Q(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper**
}
static SkPdfResult PdfOp_cm(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
double array[6];
for (int i = 0 ; i < 6 ; i++) {
array[5 - i] = pdfContext->fObjectStack.top()->numberValue();
pdfContext->fObjectStack.pop();
}
EXPECT_OPERANDS(pdfContext, 6);
POP_NUMBER(pdfContext, f);
POP_NUMBER(pdfContext, e);
POP_NUMBER(pdfContext, d);
POP_NUMBER(pdfContext, c);
POP_NUMBER(pdfContext, b);
POP_NUMBER(pdfContext, a);
CHECK_PARAMETERS();
double array[6] = {a, b, c, d, e, f};
// a b
// c d
@ -1021,7 +1137,9 @@ static SkPdfResult PdfOp_cm(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
//, to leading, which is a number expressed in unscaled text
//space units. Text leading is used only by the T*, ', and " operators. Initial value: 0.
static SkPdfResult PdfOp_TL(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
double ty = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop();
EXPECT_OPERANDS(pdfContext, 1)
POP_NUMBER(pdfContext, ty);
CHECK_PARAMETERS();
pdfContext->fGraphicsState.fTextLeading = ty;
@ -1029,11 +1147,10 @@ static SkPdfResult PdfOp_TL(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
}
static SkPdfResult PdfOp_Td(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
#ifdef PDF_TRACE
printf("stack size = %i\n", (int)pdfContext->fObjectStack.size());
#endif
double ty = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop();
double tx = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop();
EXPECT_OPERANDS(pdfContext, 2);
POP_NUMBER(pdfContext, ty);
POP_NUMBER(pdfContext, tx);
CHECK_PARAMETERS();
double array[6] = {1, 0, 0, 1, tx, -ty};
SkMatrix matrix = SkMatrixFromPdfMatrix(array);
@ -1045,8 +1162,10 @@ static SkPdfResult PdfOp_Td(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
}
static SkPdfResult PdfOp_TD(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
double ty = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop();
double tx = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop();
EXPECT_OPERANDS(pdfContext, 2)
POP_NUMBER(pdfContext, ty);
POP_NUMBER(pdfContext, tx);
CHECK_PARAMETERS();
// TODO(edisonn): Create factory methods or constructors so native is hidden
SkPdfReal* _ty = pdfContext->fPdfDoc->createReal(-ty);
@ -1069,12 +1188,14 @@ static SkPdfResult PdfOp_TD(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
}
static SkPdfResult PdfOp_Tm(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
double f = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop();
double e = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop();
double d = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop();
double c = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop();
double b = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop();
double a = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop();
EXPECT_OPERANDS(pdfContext, 6);
POP_NUMBER(pdfContext, f);
POP_NUMBER(pdfContext, e);
POP_NUMBER(pdfContext, d);
POP_NUMBER(pdfContext, c);
POP_NUMBER(pdfContext, b);
POP_NUMBER(pdfContext, a);
CHECK_PARAMETERS();
double array[6];
array[0] = a;
@ -1116,8 +1237,13 @@ static SkPdfResult PdfOp_m(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenL
pdfContext->fGraphicsState.fPathClosed = false;
}
pdfContext->fGraphicsState.fCurPosY = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop();
pdfContext->fGraphicsState.fCurPosX = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop();
EXPECT_OPERANDS(pdfContext, 2);
POP_NUMBER(pdfContext, y);
POP_NUMBER(pdfContext, x);
CHECK_PARAMETERS();
pdfContext->fGraphicsState.fCurPosY = y;
pdfContext->fGraphicsState.fCurPosX = x;
pdfContext->fGraphicsState.fPath.moveTo(SkDoubleToScalar(pdfContext->fGraphicsState.fCurPosX),
SkDoubleToScalar(pdfContext->fGraphicsState.fCurPosY));
@ -1131,8 +1257,13 @@ static SkPdfResult PdfOp_l(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenL
pdfContext->fGraphicsState.fPathClosed = false;
}
pdfContext->fGraphicsState.fCurPosY = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop();
pdfContext->fGraphicsState.fCurPosX = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop();
EXPECT_OPERANDS(pdfContext, 2);
POP_NUMBER(pdfContext, y);
POP_NUMBER(pdfContext, x);
CHECK_PARAMETERS();
pdfContext->fGraphicsState.fCurPosY = y;
pdfContext->fGraphicsState.fCurPosX = x;
pdfContext->fGraphicsState.fPath.lineTo(SkDoubleToScalar(pdfContext->fGraphicsState.fCurPosX),
SkDoubleToScalar(pdfContext->fGraphicsState.fCurPosY));
@ -1146,12 +1277,14 @@ static SkPdfResult PdfOp_c(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenL
pdfContext->fGraphicsState.fPathClosed = false;
}
double y3 = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop();
double x3 = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop();
double y2 = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop();
double x2 = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop();
double y1 = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop();
double x1 = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop();
EXPECT_OPERANDS(pdfContext, 6);
POP_NUMBER(pdfContext, y3);
POP_NUMBER(pdfContext, x3);
POP_NUMBER(pdfContext, y2);
POP_NUMBER(pdfContext, x2);
POP_NUMBER(pdfContext, y1);
POP_NUMBER(pdfContext, x1);
CHECK_PARAMETERS();
pdfContext->fGraphicsState.fPath.cubicTo(SkDoubleToScalar(x1), SkDoubleToScalar(y1),
SkDoubleToScalar(x2), SkDoubleToScalar(y2),
@ -1169,10 +1302,13 @@ static SkPdfResult PdfOp_v(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenL
pdfContext->fGraphicsState.fPathClosed = false;
}
double y3 = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop();
double x3 = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop();
double y2 = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop();
double x2 = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop();
EXPECT_OPERANDS(pdfContext, 4);
POP_NUMBER(pdfContext, y3);
POP_NUMBER(pdfContext, x3);
POP_NUMBER(pdfContext, y2);
POP_NUMBER(pdfContext, x2);
CHECK_PARAMETERS();
double y1 = pdfContext->fGraphicsState.fCurPosY;
double x1 = pdfContext->fGraphicsState.fCurPosX;
@ -1192,12 +1328,15 @@ static SkPdfResult PdfOp_y(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenL
pdfContext->fGraphicsState.fPathClosed = false;
}
double y3 = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop();
double x3 = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop();
EXPECT_OPERANDS(pdfContext, 4);
POP_NUMBER(pdfContext, y3);
POP_NUMBER(pdfContext, x3);
POP_NUMBER(pdfContext, y1);
POP_NUMBER(pdfContext, x1);
CHECK_PARAMETERS();
double y2 = pdfContext->fGraphicsState.fCurPosY;
double x2 = pdfContext->fGraphicsState.fCurPosX;
double y1 = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop();
double x1 = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop();
pdfContext->fGraphicsState.fPath.cubicTo(SkDoubleToScalar(x1), SkDoubleToScalar(y1),
SkDoubleToScalar(x2), SkDoubleToScalar(y2),
@ -1215,10 +1354,12 @@ static SkPdfResult PdfOp_re(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
pdfContext->fGraphicsState.fPathClosed = false;
}
double height = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop();
double width = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop();
double y = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop();
double x = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop();
EXPECT_OPERANDS(pdfContext, 4);
POP_NUMBER(pdfContext, height);
POP_NUMBER(pdfContext, width);
POP_NUMBER(pdfContext, y);
POP_NUMBER(pdfContext, x);
CHECK_PARAMETERS();
pdfContext->fGraphicsState.fPath.addRect(SkDoubleToScalar(x), SkDoubleToScalar(y),
SkDoubleToScalar(x + width), SkDoubleToScalar(y + height));
@ -1469,21 +1610,25 @@ static SkPdfResult skpdfGraphicsStateApplyFontCore(SkPdfContext* pdfContext, con
//a number representing a scale factor. There is no initial value for either font or
//size; they must be specified explicitly using Tf before any text is shown.
static SkPdfResult PdfOp_Tf(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
double fontSize = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop();
SkPdfNativeObject* fontName = pdfContext->fObjectStack.top(); pdfContext->fObjectStack.pop();
EXPECT_OPERANDS(pdfContext, 2);
POP_NUMBER(pdfContext, fontSize);
POP_NAME(pdfContext, fontName);
CHECK_PARAMETERS();
return skpdfGraphicsStateApplyFontCore(pdfContext, fontName, fontSize);
}
static SkPdfResult PdfOp_Tj(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
EXPECT_OPERANDS(pdfContext, 1);
POP_STRING(pdfContext, str);
CHECK_PARAMETERS();
if (!pdfContext->fGraphicsState.fTextBlock) {
// TODO(edisonn): try to recover and draw it any way?
return kIgnoreError_SkPdfResult;
}
SkPdfResult ret = DrawText(pdfContext,
pdfContext->fObjectStack.top(),
canvas);
pdfContext->fObjectStack.pop();
SkPdfResult ret = DrawText(pdfContext, str, canvas);
return ret;
}
@ -1505,9 +1650,11 @@ static SkPdfResult PdfOp_doublequote(SkPdfContext* pdfContext, SkCanvas* canvas,
return kIgnoreError_SkPdfResult;
}
SkPdfNativeObject* str = pdfContext->fObjectStack.top(); pdfContext->fObjectStack.pop();
SkPdfNativeObject* ac = pdfContext->fObjectStack.top(); pdfContext->fObjectStack.pop();
SkPdfNativeObject* aw = pdfContext->fObjectStack.top(); pdfContext->fObjectStack.pop();
EXPECT_OPERANDS(pdfContext, 3);
POP_OBJ(pdfContext, str);
POP_OBJ(pdfContext, ac);
POP_OBJ(pdfContext, aw);
CHECK_PARAMETERS();
pdfContext->fObjectStack.push(aw);
PdfOp_Tw(pdfContext, canvas, looper);
@ -1522,14 +1669,15 @@ static SkPdfResult PdfOp_doublequote(SkPdfContext* pdfContext, SkCanvas* canvas,
}
static SkPdfResult PdfOp_TJ(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
EXPECT_OPERANDS(pdfContext, 1);
POP_ARRAY(pdfContext, array);
CHECK_PARAMETERS();
if (!pdfContext->fGraphicsState.fTextBlock) {
// TODO(edisonn): try to recover and draw it any way?
return kIgnoreError_SkPdfResult;
}
SkPdfArray* array = (SkPdfArray*)pdfContext->fObjectStack.top();
pdfContext->fObjectStack.pop();
if (!array->isArray()) {
return kIgnoreError_SkPdfResult;
}
@ -1538,9 +1686,7 @@ static SkPdfResult PdfOp_TJ(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
{
if( (*array)[i]->isAnyString()) {
SkPdfNativeObject* obj = (*array)[i];
DrawText(pdfContext,
obj,
canvas);
DrawText(pdfContext, obj, canvas);
} else if ((*array)[i]->isNumber()) {
double dx = (*array)[i]->numberValue();
SkMatrix matrix;
@ -1562,7 +1708,9 @@ static SkPdfResult PdfOp_TJ(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
}
static SkPdfResult PdfOp_CS_cs(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfColorOperator* colorOperator) {
SkPdfNativeObject* name = pdfContext->fObjectStack.top(); pdfContext->fObjectStack.pop();
EXPECT_OPERANDS(pdfContext, 1);
POP_NAME(pdfContext, name);
CHECK_PARAMETERS();
//Next, get the ColorSpace Dictionary from the Resource Dictionary:
SkPdfDictionary* colorSpaceResource = pdfContext->fGraphicsState.fResources->ColorSpace(pdfContext->fPdfDoc);
@ -1630,13 +1778,16 @@ static SkPdfResult PdfOp_SC_sc(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdf
printf("color space = %s, N = %i\n", colorOperator->fColorSpace.fBuffer, n);
#endif
EXPECT_OPERANDS(pdfContext, n);
for (int i = n - 1; i >= 0 ; i--) {
if (doubles) {
c[i] = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop();
POP_NUMBER_INTO(pdfContext, c[i]);
// } else {
// v[i] = pdfContext->fObjectStack.top()->intValue(); pdfContext->fObjectStack.pop();
}
}
CHECK_PARAMETERS();
// TODO(edisonn): Now, set that color. Only DeviceRGB supported.
// TODO(edisonn): do possible field values to enum at parsing time!
@ -1656,7 +1807,7 @@ static SkPdfResult PdfOp_sc(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
}
static SkPdfResult PdfOp_SCN_scn(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfColorOperator* colorOperator) {
if (pdfContext->fObjectStack.top()->isName()) {
if (pdfContext->fObjectStack.count() > 0 && pdfContext->fObjectStack.top()->isName()) {
SkPdfNativeObject* name = pdfContext->fObjectStack.top(); pdfContext->fObjectStack.pop();
//Next, get the ExtGState Dictionary from the Resource Dictionary:
@ -1687,8 +1838,14 @@ static SkPdfResult PdfOp_scn(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToke
}
static SkPdfResult PdfOp_G_g(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfColorOperator* colorOperator) {
/*double gray = */pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop();
return kNYI_SkPdfResult;
EXPECT_OPERANDS(pdfContext, 1);
POP_NUMBER(pdfContext, gray);
CHECK_PARAMETERS();
colorOperator->fColorSpace = strings_DeviceRGB; // TODO(edisonn): HACK - it should be device gray, but not suported right now
colorOperator->setRGBColor(SkColorSetRGB((U8CPU)(255*gray), (U8CPU)(255*gray), (U8CPU)(255*gray)));
return kPartial_SkPdfResult;
}
static SkPdfResult PdfOp_G(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
@ -1700,9 +1857,11 @@ static SkPdfResult PdfOp_g(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenL
}
static SkPdfResult PdfOp_RG_rg(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfColorOperator* colorOperator) {
double b = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop();
double g = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop();
double r = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop();
EXPECT_OPERANDS(pdfContext, 3);
POP_NUMBER(pdfContext, b);
POP_NUMBER(pdfContext, g);
POP_NUMBER(pdfContext, r);
CHECK_PARAMETERS();
colorOperator->fColorSpace = strings_DeviceRGB;
colorOperator->setRGBColor(SkColorSetRGB((U8CPU)(255*r), (U8CPU)(255*g), (U8CPU)(255*b)));
@ -1719,12 +1878,19 @@ static SkPdfResult PdfOp_rg(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
static SkPdfResult PdfOp_K_k(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfColorOperator* colorOperator) {
// TODO(edisonn): spec has some rules about overprint, implement them.
/*double k = */pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop();
/*double y = */pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop();
/*double m = */pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop();
/*double c = */pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop();
EXPECT_OPERANDS(pdfContext, 4);
POP_NUMBER(pdfContext, k);
POP_NUMBER(pdfContext, y);
POP_NUMBER(pdfContext, m);
POP_NUMBER(pdfContext, c);
CHECK_PARAMETERS();
colorOperator->fColorSpace = strings_DeviceCMYK;
// TODO(edisonn): silly way to remove compiler warning
if (k + y + m + c == 0) {
return kNYI_SkPdfResult;
}
//colorOperator->fColorSpace = strings_DeviceCMYK;
// TODO(edisonn): Set color.
return kNYI_SkPdfResult;
}
@ -1887,41 +2053,50 @@ static void skpdfGraphicsStateApplyFont(SkPdfContext* pdfContext, SkPdfArray* fo
//lineWidth w Set the line width in the graphics state (see “Line Width” on page 152).
static SkPdfResult PdfOp_w(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
double lw = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop();
EXPECT_OPERANDS(pdfContext, 1);
POP_NUMBER(pdfContext, lw);
CHECK_PARAMETERS();
return skpdfGraphicsStateApplyLW(pdfContext, lw);
}
//lineCap J Set the line cap style in the graphics state (see “Line Cap Style” on page 153).
static SkPdfResult PdfOp_J(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
// TODO(edisonn): round/ceil to int?
int lc = (int)pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop();
return skpdfGraphicsStateApplyLC(pdfContext, lc);
EXPECT_OPERANDS(pdfContext, 1);
POP_NUMBER(pdfContext, lc);
CHECK_PARAMETERS();
return skpdfGraphicsStateApplyLC(pdfContext, (int)lc);
}
//lineJoin j Set the line join style in the graphics state (see “Line Join Style” on page 153).
static SkPdfResult PdfOp_j(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
// TODO(edisonn): round/ceil to int?
int lj = (int)pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop();
return skpdfGraphicsStateApplyLJ(pdfContext, lj);
EXPECT_OPERANDS(pdfContext, 1);
POP_NUMBER(pdfContext, lj);
CHECK_PARAMETERS();
return skpdfGraphicsStateApplyLJ(pdfContext, (int)lj);
}
//miterLimit M Set the miter limit in the graphics state (see “Miter Limit” on page 153).
static SkPdfResult PdfOp_M(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
double ml = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop();
EXPECT_OPERANDS(pdfContext, 1);
POP_NUMBER(pdfContext, ml);
CHECK_PARAMETERS();
return skpdfGraphicsStateApplyML(pdfContext, ml);
}
//dashArray dashPhase d Set the line dash pattern in the graphics state (see “Line Dash Pattern” on
//page 155).
static SkPdfResult PdfOp_d(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
SkPdfNativeObject* phase = pdfContext->fObjectStack.top(); pdfContext->fObjectStack.pop();
SkPdfNativeObject* array = pdfContext->fObjectStack.top(); pdfContext->fObjectStack.pop();
EXPECT_OPERANDS(pdfContext, 2);
POP_OBJ(pdfContext, phase);
POP_ARRAY(pdfContext, array);
CHECK_PARAMETERS();
if (!array->isArray()) {
return kIgnoreError_SkPdfResult;
}
return skpdfGraphicsStateApplyD(pdfContext, (SkPdfArray*)array, phase);
return skpdfGraphicsStateApplyD(pdfContext, array, phase);
}
//intent ri (PDF 1.1) Set the color rendering intent in the graphics state (see “Rendering Intents” on page 197).
@ -1935,7 +2110,13 @@ static SkPdfResult PdfOp_ri(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
//Tolerance”). flatness is a number in the range 0 to 100; a value of 0 speci-
//fies the output devices default flatness tolerance.
static SkPdfResult PdfOp_i(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
pdfContext->fObjectStack.pop();
EXPECT_OPERANDS(pdfContext, 1);
POP_NUMBER(pdfContext, flatness);
CHECK_PARAMETERS();
if (flatness < 0 || flatness > 100) {
return kError_SkPdfResult;
}
return kNYI_SkPdfResult;
}
@ -2065,7 +2246,9 @@ static void skpdfGraphicsStateApplyAIS(SkPdfContext* pdfContext, bool alphaSourc
//dictName gs (PDF 1.2) Set the specified parameters in the graphics state. dictName is
//the name of a graphics state parameter dictionary in the ExtGState subdictionary of the current resource dictionary (see the next section).
static SkPdfResult PdfOp_gs(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
SkPdfNativeObject* name = pdfContext->fObjectStack.top(); pdfContext->fObjectStack.pop();
EXPECT_OPERANDS(pdfContext, 1);
POP_NAME(pdfContext, name);
CHECK_PARAMETERS();
#ifdef PDF_TRACE
SkString str;
@ -2156,7 +2339,10 @@ static SkPdfResult PdfOp_gs(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
//, to charSpace, which is a number expressed in unscaled text space units. Character spacing is used by the Tj, TJ, and ' operators.
//Initial value: 0.
SkPdfResult PdfOp_Tc(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
double charSpace = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop();
EXPECT_OPERANDS(pdfContext, 1);
POP_NUMBER(pdfContext, charSpace);
CHECK_PARAMETERS();
pdfContext->fGraphicsState.fCharSpace = charSpace;
return kOK_SkPdfResult;
@ -2168,7 +2354,10 @@ SkPdfResult PdfOp_Tc(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper*
//text space units. Word spacing is used by the Tj, TJ, and ' operators. Initial
//value: 0.
SkPdfResult PdfOp_Tw(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
double wordSpace = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop();
EXPECT_OPERANDS(pdfContext, 1);
POP_NUMBER(pdfContext, wordSpace);
CHECK_PARAMETERS();
pdfContext->fGraphicsState.fWordSpace = wordSpace;
return kOK_SkPdfResult;
@ -2178,7 +2367,13 @@ SkPdfResult PdfOp_Tw(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper*
//, to (scale ˜ 100). scale is a number specifying the
//percentage of the normal width. Initial value: 100 (normal width).
static SkPdfResult PdfOp_Tz(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
/*double scale = */pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop();
EXPECT_OPERANDS(pdfContext, 1);
POP_NUMBER(pdfContext, scale);
CHECK_PARAMETERS();
if (scale < 0) {
return kError_SkPdfResult;
}
return kNYI_SkPdfResult;
}
@ -2186,48 +2381,80 @@ static SkPdfResult PdfOp_Tz(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
//render Tr Set the text rendering mode, T
//mode, to render, which is an integer. Initial value: 0.
static SkPdfResult PdfOp_Tr(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
/*double render = */pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop();
EXPECT_OPERANDS(pdfContext, 1);
POP_INTEGER(pdfContext, mode);
CHECK_PARAMETERS();
if (mode < 0) { // TODO(edisonn): function/enums with supported modes
return kError_SkPdfResult;
}
return kNYI_SkPdfResult;
}
//rise Ts Set the text rise, Trise, to rise, which is a number expressed in unscaled text space
//units. Initial value: 0.
static SkPdfResult PdfOp_Ts(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
/*double rise = */pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop();
EXPECT_OPERANDS(pdfContext, 1);
POP_NUMBER(pdfContext, rise);
CHECK_PARAMETERS();
if (rise < 0) {
return kNYI_SkPdfResult;
}
return kNYI_SkPdfResult;
}
//wx wy d0
static SkPdfResult PdfOp_d0(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
pdfContext->fObjectStack.pop();
pdfContext->fObjectStack.pop();
EXPECT_OPERANDS(pdfContext, 2);
POP_NUMBER(pdfContext, wy);
POP_NUMBER(pdfContext, wx);
CHECK_PARAMETERS();
if (wx < 0 || wy < 0) {
return kError_SkPdfResult;
}
return kNYI_SkPdfResult;
}
//wx wy llx lly urx ury d1
static SkPdfResult PdfOp_d1(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
pdfContext->fObjectStack.pop();
pdfContext->fObjectStack.pop();
pdfContext->fObjectStack.pop();
pdfContext->fObjectStack.pop();
pdfContext->fObjectStack.pop();
pdfContext->fObjectStack.pop();
EXPECT_OPERANDS(pdfContext, 6);
POP_NUMBER(pdfContext, ury);
POP_NUMBER(pdfContext, urx);
POP_NUMBER(pdfContext, lly);
POP_NUMBER(pdfContext, llx);
POP_NUMBER(pdfContext, wy);
POP_NUMBER(pdfContext, wx);
CHECK_PARAMETERS();
if (wx + wy + llx + lly + urx + ury) {
return kNYI_SkPdfResult;
}
return kNYI_SkPdfResult;
}
//name sh
static SkPdfResult PdfOp_sh(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
pdfContext->fObjectStack.pop();
EXPECT_OPERANDS(pdfContext, 1);
POP_NAME(pdfContext, name);
CHECK_PARAMETERS();
if (name == NULL) {
return kError_SkPdfResult;
}
return kNYI_SkPdfResult;
}
//name Do
static SkPdfResult PdfOp_Do(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
SkPdfNativeObject* name = pdfContext->fObjectStack.top(); pdfContext->fObjectStack.pop();
EXPECT_OPERANDS(pdfContext, 1);
POP_NAME(pdfContext, name);
CHECK_PARAMETERS();
SkPdfDictionary* xObject = pdfContext->fGraphicsState.fResources->XObject(pdfContext->fPdfDoc);
@ -2252,7 +2479,13 @@ static SkPdfResult PdfOp_Do(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
//tag MP Designate a marked-content point. tag is a name object indicating the role or
//significance of the point.
static SkPdfResult PdfOp_MP(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
pdfContext->fObjectStack.pop();
EXPECT_OPERANDS(pdfContext, 1);
POP_OBJ(pdfContext, tag);
CHECK_PARAMETERS();
if (tag == NULL) {
return kNYI_SkPdfResult;
}
return kNYI_SkPdfResult;
}
@ -2263,8 +2496,14 @@ static SkPdfResult PdfOp_MP(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
//associated with it in the Properties subdictionary of the current resource
//dictionary (see Section 9.5.1, “Property Lists”).
static SkPdfResult PdfOp_DP(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
pdfContext->fObjectStack.pop();
pdfContext->fObjectStack.pop();
EXPECT_OPERANDS(pdfContext, 2);
POP_OBJ(pdfContext, properties);
POP_OBJ(pdfContext, tag);
CHECK_PARAMETERS();
if (tag == NULL || properties == NULL) {
return kNYI_SkPdfResult;
}
return kNYI_SkPdfResult;
}
@ -2272,7 +2511,13 @@ static SkPdfResult PdfOp_DP(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
//tag BMC Begin a marked-content sequence terminated by a balancing EMC operator.
//tag is a name object indicating the role or significance of the sequence.
static SkPdfResult PdfOp_BMC(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
pdfContext->fObjectStack.pop();
EXPECT_OPERANDS(pdfContext, 1);
POP_OBJ(pdfContext, tag);
CHECK_PARAMETERS();
if (tag == NULL) {
return kNYI_SkPdfResult;
}
return kNYI_SkPdfResult;
}
@ -2281,8 +2526,14 @@ static SkPdfResult PdfOp_BMC(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToke
//by a balancing EMCoperator. tag is a name object indicating the role or significance of the sequence; propertiesis either an inline dictionary containing the
//property list or a name object associated with it in the Properties subdictionary of the current resource dictionary (see Section 9.5.1, “Property Lists”).
static SkPdfResult PdfOp_BDC(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
pdfContext->fObjectStack.pop();
pdfContext->fObjectStack.pop();
EXPECT_OPERANDS(pdfContext, 2);
POP_OBJ(pdfContext, properties);
POP_OBJ(pdfContext, tag);
CHECK_PARAMETERS();
if (tag == NULL || properties == NULL) {
return kNYI_SkPdfResult;
}
return kNYI_SkPdfResult;
}