Index: experimental/PdfViewer/pdf_viewer_main.cpp |
=================================================================== |
--- experimental/PdfViewer/pdf_viewer_main.cpp (revision 9684) |
+++ experimental/PdfViewer/pdf_viewer_main.cpp (working copy) |
@@ -7,6 +7,7 @@ |
#include "SkCanvas.h" |
#include "SkDevice.h" |
+#include "SkForceLinking.h" |
#include "SkGraphics.h" |
#include "SkImageDecoder.h" |
#include "SkImageEncoder.h" |
@@ -24,6 +25,8 @@ |
#include "podofo.h" |
using namespace PoDoFo; |
+__SK_FORCE_IMAGE_DECODER_LINKING; |
+ |
const PdfObject* resolveReferenceObject(const PdfMemDocument* pdfDoc, |
const PdfObject* obj, |
bool resolveOneElementArrays = false); |
@@ -176,14 +179,20 @@ |
/* |
* TODO(edisonn): |
- * - encapsulate podofo in the pdf api so the skpdf does not know anything about podofo |
+ * - encapsulate podofo in the pdf api so the skpdf does not know anything about podofo ... in progress |
* - ASAP so skp -> pdf -> png looks great |
- * - load gs/ especially smask and already known prop (skp) |
- * - use transparency (I think ca and CA ops) (skp) |
- * - all font types |
- * - word spacing |
- * - load font for baidu.pdf |
- * - load font for youtube.pdf |
+ * - load gs/ especially smask and already known prop (skp)... |
+ * - all font types and all ppdf font features |
+ * - word spacing |
+ * - load font for baidu.pdf |
+ * - load font for youtube.pdf |
+ * - parser for pdf from the definition already available in pdfspec_autogen.py |
+ * - wrapper on classes for customizations? e.g. |
+ * SkPdfPageObjectVanila - has only the basic loaders/getters |
+ * SkPdfPageObject : public SkPdfPageObjectVanila, extends, and I can add customizations here |
+ * need to find a nice object model for all this with constructors and factories |
+ * - deal with inheritable automatically ? |
+ * - deal with specific type in spec directly, add all dictionary types to known types |
*/ |
//#define PDF_TRACE |
@@ -270,6 +279,7 @@ |
struct PdfColorOperator { |
std::string fColorSpace; // TODO(edisonn): use SkString |
SkColor fColor; |
+ double fOpacity; // ca or CA |
// TODO(edisonn): add here other color space options. |
void setRGBColor(SkColor color) { |
@@ -277,7 +287,12 @@ |
fColor = color; |
} |
// TODO(edisonn): double check the default values for all fields. |
- PdfColorOperator() : fColor(SK_ColorBLACK) {} |
+ PdfColorOperator() : fColor(SK_ColorBLACK), fOpacity(1) {} |
+ |
+ void applyGraphicsState(SkPaint* paint) { |
+ paint->setColor(SkColorSetA(fColor, fOpacity * 255)); |
+ } |
+ |
}; |
// TODO(edisonn): better class design. |
@@ -326,8 +341,23 @@ |
fWordSpace = 0; |
fCharSpace = 0; |
fHasClipPathToApply = false; |
- fResources = NULL; |
+ fResources = NULL; |
} |
+ |
+ void applyGraphicsState(SkPaint* paint, bool stroking) { |
+ if (stroking) { |
+ fStroking.applyGraphicsState(paint); |
+ } else { |
+ fNonStroking.applyGraphicsState(paint); |
+ } |
+ |
+ // TODO(edisonn): get this from pdfContext->options, |
+ // or pdfContext->addPaintOptions(&paint); |
+ paint->setAntiAlias(true); |
+ |
+ // TODO(edisonn): dashing, miter, ... |
+ paint->setStrokeWidth(SkDoubleToScalar(fLineWidth)); |
+ } |
}; |
// TODO(edisonn): better class design. |
@@ -763,8 +793,9 @@ |
if (fCurFont->GetFontScale() != 0) { |
paint.setTextScaleX(SkFloatToScalar(fCurFont->GetFontScale() / 100.0)); |
} |
- paint.setColor(pdfContext->fGraphicsState.fNonStroking.fColor); |
+ pdfContext->fGraphicsState.applyGraphicsState(&paint, false); |
+ |
paint.setTypeface(SkTypefaceFromPdfFont(fCurFont)); |
paint.setAntiAlias(true); |
@@ -883,6 +914,9 @@ |
if (value == NULL || !value->IsNumber()) { |
return false; |
} |
+ if (data == NULL) { |
+ return true; |
+ } |
*data = value->GetNumber(); |
return true; |
@@ -905,9 +939,12 @@ |
const PdfObject* value = resolveReferenceObject(pdfDoc, |
dict.GetKey(PdfName(key))); |
- if (value == NULL || !value->IsReal()) { |
+ if (value == NULL || (!value->IsReal() && !value->IsNumber())) { |
return false; |
} |
+ if (data == NULL) { |
+ return true; |
+ } |
*data = value->GetReal(); |
return true; |
@@ -934,6 +971,9 @@ |
if (value == NULL || !value->IsBool()) { |
return false; |
} |
+ if (data == NULL) { |
+ return true; |
+ } |
*data = value->GetBool(); |
return true; |
@@ -959,6 +999,9 @@ |
if (value == NULL || !value->IsName()) { |
return false; |
} |
+ if (data == NULL) { |
+ return true; |
+ } |
*data = value->GetName().GetName(); |
return true; |
@@ -984,6 +1027,9 @@ |
if (value == NULL || (!value->IsString() && !value->IsHexString())) { |
return false; |
} |
+ if (data == NULL) { |
+ return true; |
+ } |
*data = value->GetString().GetString(); |
return true; |
@@ -1009,6 +1055,9 @@ |
if (value == NULL || !value->IsDictionary()) { |
return false; |
} |
+ if (data == NULL) { |
+ return true; |
+ } |
return PodofoMapper::map(*pdfDoc, *value, (SkPdfObject**)data); |
} |
@@ -1035,6 +1084,10 @@ |
return false; |
} |
+ if (data == NULL) { |
+ return true; |
+ } |
+ |
return PodofoMapper::map(*pdfDoc, *value, (T**)data); |
} |
@@ -1059,6 +1112,9 @@ |
if (value == NULL) { |
return false; |
} |
+ if (data == NULL) { |
+ return true; |
+ } |
return PodofoMapper::map(*pdfDoc, *value, data); |
} |
@@ -1311,6 +1367,7 @@ |
canvas->saveLayer(&dst, NULL); |
canvas->drawBitmapRect(image, dst, NULL); |
SkPaint xfer; |
+ pdfContext->fGraphicsState.applyGraphicsState(&xfer, false); |
xfer.setXfermodeMode(SkXfermode::kSrcOut_Mode); // SkXfermode::kSdtOut_Mode |
canvas->drawBitmapRect(sMask, dst, &xfer); |
canvas->restore(); |
@@ -1597,12 +1654,13 @@ |
double ty = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext->fObjectStack.pop(); |
double tx = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext->fObjectStack.pop(); |
+ // TODO(edisonn): Create factory methods or constructors so podofo is hidden |
PdfObject _ty(PdfVariant(-ty)); |
pdfContext->fObjectStack.push(new SkPdfNumber(&pdfContext->fPdfDoc.podofo(), &_ty)); |
PdfOp_TL(pdfContext, canvas, looper); |
- PdfObject vtx(PdfVariant(-(-tx))); // TODO(edisonn) Hmm, the compiler thinks I have here a function pointer if we use (tx), but not -(-tx) |
+ PdfObject vtx(PdfVariant(-(-tx))); // TODO(edisonn): Hmm, the compiler thinks I have here a function pointer if we use (tx), but not -(-tx) |
pdfContext->fObjectStack.push(new SkPdfNumber(&pdfContext->fPdfDoc.podofo(), &vtx)); |
PdfObject vty(PdfVariant(-(-ty))); |
@@ -1785,20 +1843,13 @@ |
SkPaint paint; |
- // TODO(edisonn): get this from pdfContext->options, |
- // or pdfContext->addPaintOptions(&paint); |
- paint.setAntiAlias(true); |
- |
- // TODO(edisonn): dashing, miter, ... |
- |
-// path.transform(pdfContext->fGraphicsState.fMatrix); |
-// path.transform(pdfContext->fOriginalMatrix); |
- |
SkPoint line[2]; |
if (fill && !stroke && path.isLine(line)) { |
paint.setStyle(SkPaint::kStroke_Style); |
- paint.setColor(pdfContext->fGraphicsState.fNonStroking.fColor); |
+ |
+ pdfContext->fGraphicsState.applyGraphicsState(&paint, false); |
paint.setStrokeWidth(SkDoubleToScalar(0)); |
+ |
canvas->drawPath(path, paint); |
} else { |
if (fill) { |
@@ -1806,14 +1857,17 @@ |
if (evenOdd) { |
path.setFillType(SkPath::kEvenOdd_FillType); |
} |
- paint.setColor(pdfContext->fGraphicsState.fNonStroking.fColor); |
+ |
+ pdfContext->fGraphicsState.applyGraphicsState(&paint, false); |
+ |
canvas->drawPath(path, paint); |
} |
if (stroke) { |
paint.setStyle(SkPaint::kStroke_Style); |
- paint.setColor(pdfContext->fGraphicsState.fStroking.fColor); |
- paint.setStrokeWidth(SkDoubleToScalar(pdfContext->fGraphicsState.fLineWidth)); |
+ |
+ pdfContext->fGraphicsState.applyGraphicsState(&paint, true); |
+ |
path.setFillType(SkPath::kWinding_FillType); // reset it, just in case it messes up the stroke |
canvas->drawPath(path, paint); |
} |
@@ -2290,7 +2344,24 @@ |
PodofoMapper::map(value, &gs); |
// TODO(edisonn): now load all those properties in graphic state. |
+ if (gs == NULL) { |
+ return kIgnoreError_PdfResult; |
+ } |
+ if (gs->has_CA()) { |
+ pdfContext->fGraphicsState.fStroking.fOpacity = gs->CA(); |
+ } |
+ |
+ if (gs->has_ca()) { |
+ pdfContext->fGraphicsState.fNonStroking.fOpacity = gs->ca(); |
+ } |
+ |
+ if (gs->has_LW()) { |
+ pdfContext->fGraphicsState.fLineWidth = gs->LW(); |
+ } |
+ |
+ |
+ |
return kNYI_PdfResult; |
} |