Index: experimental/PdfViewer/pdf_viewer_main.cpp |
=================================================================== |
--- experimental/PdfViewer/pdf_viewer_main.cpp (revision 9735) |
+++ experimental/PdfViewer/pdf_viewer_main.cpp (working copy) |
@@ -28,174 +28,32 @@ |
__SK_FORCE_IMAGE_DECODER_LINKING; |
+// TODO(edisonn): tool, show what objects were read at least, show the ones not even read |
+// keep for each object pos in file |
+// plug in for VS? syntax coloring, show selected object ... from the text, or from rendered x,y |
-//#define PDF_TRACE |
-//#define PDF_TRACE_DIFF_IN_PNG |
-//#define PDF_DEBUG_NO_CLIPING |
-//#define PDF_DEBUG_NO_PAGE_CLIPING |
-//#define PDF_DEBUG_3X |
+// TODO(edisonn): security - validate all the user input, all pdf! |
-const PdfObject* resolveReferenceObject(const PdfMemDocument* pdfDoc, |
- const PdfObject* obj, |
- bool resolveOneElementArrays = false); |
- |
-bool LongFromDictionary(const PdfMemDocument* pdfDoc, |
- const PdfDictionary& dict, |
- const char* key, |
- const char* abr, |
- long* data); |
- |
-bool DoubleFromDictionary(const PdfMemDocument* pdfDoc, |
- const PdfDictionary& dict, |
- const char* key, |
- const char* abr, |
- double* data); |
- |
-bool BoolFromDictionary(const PdfMemDocument* pdfDoc, |
- const PdfDictionary& dict, |
- const char* key, |
- const char* abr, |
- bool* data); |
- |
-bool NameFromDictionary(const PdfMemDocument* pdfDoc, |
- const PdfDictionary& dict, |
- const char* key, |
- const char* abr, |
- std::string* data); |
- |
-bool StringFromDictionary(const PdfMemDocument* pdfDoc, |
- const PdfDictionary& dict, |
- const char* key, |
- const char* abr, |
- std::string* data); |
- |
-class SkPdfDictionary; |
-bool DictionaryFromDictionary(const PdfMemDocument* pdfDoc, |
- const PdfDictionary& dict, |
- const char* key, |
- const char* abr, |
- SkPdfDictionary** data); |
- |
-template <typename T> |
-bool DictionaryFromDictionary2(const PdfMemDocument* pdfDoc, |
- const PdfDictionary& dict, |
- const char* key, |
- const char* abr, |
- T** data); |
- |
-class SkPdfObject; |
-bool ObjectFromDictionary(const PdfMemDocument* pdfDoc, |
- const PdfDictionary& dict, |
- const char* key, |
- const char* abr, |
- SkPdfObject** data); |
- |
- |
-struct SkPdfFileSpec {}; |
-class SkPdfArray; |
-class SkPdfStream; |
-struct SkPdfDate {}; |
-struct SkPdfTree {}; |
-struct SkPdfFunction {}; |
- |
-bool ArrayFromDictionary(const PdfMemDocument* pdfDoc, |
- const PdfDictionary& dict, |
- const char* key, |
- const char* abr, |
- SkPdfArray* data); |
- |
- |
-bool FileSpecFromDictionary(const PdfMemDocument* pdfDoc, |
- const PdfDictionary& dict, |
- const char* key, |
- const char* abr, |
- SkPdfFileSpec* data); |
- |
- |
-bool StreamFromDictionary(const PdfMemDocument* pdfDoc, |
- const PdfDictionary& dict, |
- const char* key, |
- const char* abr, |
- SkPdfStream** data); |
- |
-bool TreeFromDictionary(const PdfMemDocument* pdfDoc, |
- const PdfDictionary& dict, |
- const char* key, |
- const char* abr, |
- SkPdfTree** data); |
- |
-bool DateFromDictionary(const PdfMemDocument* pdfDoc, |
- const PdfDictionary& dict, |
- const char* key, |
- const char* abr, |
- SkPdfDate* data); |
- |
-bool SkRectFromDictionary(const PdfMemDocument* pdfDoc, |
- const PdfDictionary& dict, |
- const char* key, |
- const char* abr, |
- SkRect* data); |
- |
-bool FunctionFromDictionary(const PdfMemDocument* pdfDoc, |
- const PdfDictionary& dict, |
- const char* key, |
- const char* abr, |
- SkPdfFunction* data); |
- |
-bool skpdfmap(const PdfMemDocument& podofoDoc, const PdfObject& podofoObj, SkPdfObject** out); |
- |
#include "SkPdfHeaders_autogen.h" |
#include "SkPdfPodofoMapper_autogen.h" |
#include "SkPdfParser.h" |
+ |
+#include "SkPdfBasics.h" |
+#include "SkPdfUtils.h" |
+ |
#include "SkPdfFont.h" |
// TODO(edisonn): fix the mess with the files. |
#include "SkPdfFont.cpp" |
+#include "SkPdfBasics.cpp" |
+#include "SkPdfUtils.cpp" |
bool skpdfmap(const PdfMemDocument& podofoDoc, const PdfObject& podofoObj, SkPdfObject** out) { |
return PodofoMapper::map(podofoDoc, podofoObj, out); |
} |
-bool ArrayFromDictionary(const PdfMemDocument* pdfDoc, |
- const PdfDictionary& dict, |
- const char* key, |
- const char* abr, |
- SkPdfArray* data) {return false;} |
- |
-bool FileSpecFromDictionary(const PdfMemDocument* pdfDoc, |
- const PdfDictionary& dict, |
- const char* key, |
- const char* abr, |
- SkPdfFileSpec* data) {return false;} |
- |
-bool StreamFromDictionary(const PdfMemDocument* pdfDoc, |
- const PdfDictionary& dict, |
- const char* key, |
- const char* abr, |
- SkPdfStream** data); |
- |
-bool TreeFromDictionary(const PdfMemDocument* pdfDoc, |
- const PdfDictionary& dict, |
- const char* key, |
- const char* abr, |
- SkPdfTree** data) {return false;} |
- |
-bool DateFromDictionary(const PdfMemDocument* pdfDoc, |
- const PdfDictionary& dict, |
- const char* key, |
- const char* abr, |
- SkPdfDate* data) {return false;} |
- |
-bool FunctionFromDictionary(const PdfMemDocument* pdfDoc, |
- const PdfDictionary& dict, |
- const char* key, |
- const char* abr, |
- SkPdfFunction* data) {return false;} |
- |
- |
- |
/* |
* TODO(edisonn): |
* - all font types and all ppdf font features |
@@ -224,8 +82,19 @@ |
} |
printf("\n"); |
} |
+ |
+static void SkTraceRect(const SkRect& rect, const char* sz = "") { |
+ printf("SkRect %s ", sz); |
+ printf("x = %f ", SkScalarToDouble(rect.x())); |
+ printf("y = %f ", SkScalarToDouble(rect.y())); |
+ printf("w = %f ", SkScalarToDouble(rect.width())); |
+ printf("h = %f ", SkScalarToDouble(rect.height())); |
+ printf("\n"); |
+} |
+ |
#else |
#define SkTraceMatrix(a,b) |
+#define SkTraceRect(a,b) |
#endif |
using namespace std; |
@@ -289,126 +158,21 @@ |
return matrix; |
} |
-// TODO(edisonn): better class design. |
-struct PdfColorOperator { |
- std::string fColorSpace; // TODO(edisonn): use SkString |
- SkColor fColor; |
- double fOpacity; // ca or CA |
- // TODO(edisonn): add here other color space options. |
+SkMatrix SkMatrixFromPdfArray(SkPdfArray* pdfArray) { |
+ double array[6]; |
- void setRGBColor(SkColor color) { |
- // TODO(edisonn): ASSERT DeviceRGB is the color space. |
- fColor = color; |
- } |
- // TODO(edisonn): double check the default values for all fields. |
- PdfColorOperator() : fColor(SK_ColorBLACK), fOpacity(1) {} |
- |
- void applyGraphicsState(SkPaint* paint) { |
- paint->setColor(SkColorSetA(fColor, fOpacity * 255)); |
- } |
- |
-}; |
- |
-// TODO(edisonn): better class design. |
-struct PdfGraphicsState { |
- SkMatrix fMatrix; |
- SkMatrix fMatrixTm; |
- SkMatrix fMatrixTlm; |
- |
- double fCurPosX; |
- double fCurPosY; |
- |
- double fCurFontSize; |
- bool fTextBlock; |
- PdfFont* fCurFont; |
- SkPdfFont* fSkFont; |
- SkPath fPath; |
- bool fPathClosed; |
- |
- // Clip that is applied after the drawing is done!!! |
- bool fHasClipPathToApply; |
- SkPath fClipPath; |
- |
- PdfColorOperator fStroking; |
- PdfColorOperator fNonStroking; |
- |
- double fLineWidth; |
- double fTextLeading; |
- double fWordSpace; |
- double fCharSpace; |
- |
- SkPdfResourceDictionary* fResources; |
- |
- SkBitmap fSMask; |
- |
- PdfGraphicsState() { |
- fCurPosX = 0.0; |
- fCurPosY = 0.0; |
- fCurFontSize = 0.0; |
- fTextBlock = false; |
- fCurFont = NULL; |
- fMatrix = SkMatrix::I(); |
- fMatrixTm = SkMatrix::I(); |
- fMatrixTlm = SkMatrix::I(); |
- fPathClosed = true; |
- fLineWidth = 0; |
- fTextLeading = 0; |
- fWordSpace = 0; |
- fCharSpace = 0; |
- fHasClipPathToApply = false; |
- fResources = NULL; |
- fSkFont = NULL; |
- } |
- |
- void applyGraphicsState(SkPaint* paint, bool stroking) { |
- if (stroking) { |
- fStroking.applyGraphicsState(paint); |
- } else { |
- fNonStroking.applyGraphicsState(paint); |
+ // TODO(edisonn): security issue, ret if size() != 6 |
+ for (int i = 0; i < 6; i++) { |
+ const PdfObject* elem = resolveReferenceObject(pdfArray->doc(), (*pdfArray)[i]->podofo()); |
+ if (elem == NULL || (!elem->IsReal() && !elem->IsNumber())) { |
+ return SkMatrix::I(); // TODO(edisonn): report issue |
} |
- |
- // TODO(edisonn): get this from pdfContext->options, |
- // or pdfContext->addPaintOptions(&paint); |
- paint->setAntiAlias(true); |
- |
- // TODO(edisonn): dashing, miter, ... |
- paint->setStrokeWidth(SkDoubleToScalar(fLineWidth)); |
+ array[i] = elem->GetReal(); |
} |
-}; |
-// TODO(edisonn): better class design. |
-struct PdfInlineImage { |
- std::map<std::string, std::string> fKeyValuePairs; |
- std::string fImageData; |
+ return SkMatrixFromPdfMatrix(array); |
+} |
-}; |
- |
-// TODO(edisonn): better class design. |
-struct PdfContext { |
- std::stack<SkPdfObject*> fObjectStack; |
- std::stack<PdfGraphicsState> fStateStack; |
- PdfGraphicsState fGraphicsState; |
- SkPdfDoc& fPdfDoc; |
- SkMatrix fOriginalMatrix; |
- |
- PdfInlineImage fInlineImage; |
- |
- PdfContext(SkPdfDoc& doc) : fPdfDoc(doc) {} |
- |
-}; |
- |
-// TODO(edisonn): temporary code, to report how much of the PDF we actually think we rendered. |
-enum PdfResult { |
- kOK_PdfResult, |
- kPartial_PdfResult, |
- kNYI_PdfResult, |
- kIgnoreError_PdfResult, |
- kError_PdfResult, |
- kUnsupported_PdfResult, |
- |
- kCount_PdfResult |
-}; |
- |
PdfContext* gPdfContext = NULL; |
SkBitmap* gDumpBitmap = NULL; |
SkCanvas* gDumpCanvas = NULL; |
@@ -651,29 +415,6 @@ |
(font->IsItalic() ? SkTypeface::kItalic : 0))); |
} |
- |
-// TODO(edisonn): move this code in podofo, so we don't have to fix the font. |
-// This logic needs to be moved in PdfEncodingObjectFactory::CreateEncoding |
-std::map<PdfFont*, PdfCMapEncoding*> gFontsFixed; |
-PdfEncoding* FixPdfFont(PdfContext* pdfContext, PdfFont* fCurFont) { |
- // TODO(edisonn): and is Identity-H |
- if (gFontsFixed.find(fCurFont) == gFontsFixed.end()) { |
- if (fCurFont->GetObject()->IsDictionary() && fCurFont->GetObject()->GetDictionary().HasKey(PdfName("ToUnicode"))) { |
- PdfCMapEncoding* enc = new PdfCMapEncoding( |
- fCurFont->GetObject(), |
- (PdfObject*)resolveReferenceObject(&pdfContext->fPdfDoc.podofo(), |
- fCurFont->GetObject()->GetDictionary().GetKey(PdfName("ToUnicode"))), |
- PdfCMapEncoding::eBaseEncoding_Identity); // todo, read the base encoding |
- gFontsFixed[fCurFont] = enc; |
- return enc; |
- } |
- |
- return NULL; |
- } |
- |
- return gFontsFixed[fCurFont]; |
-} |
- |
PdfResult DrawText(PdfContext* pdfContext, |
const SkPdfObject* str, |
SkCanvas* canvas) |
@@ -687,11 +428,14 @@ |
SkUnencodedText binary(str); |
SkDecodedText decoded; |
- skfont->encoding()->decodeText(binary, &decoded); |
- SkUnicodeText unicode; |
- skfont->ToUnicode(decoded, &unicode); |
+ if (skfont->encoding() == NULL) { |
+ // TODO(edisonn): report warning |
+ return kNYI_PdfResult; |
+ } |
+ skfont->encoding()->decodeText(binary, &decoded); |
+ |
SkPaint paint; |
// TODO(edisonn): when should fCurFont->GetFontSize() used? When cur is fCurFontSize == 0? |
// Or maybe just not call setTextSize at all? |
@@ -727,155 +471,9 @@ |
SkTraceMatrix(matrix, "mirrored"); |
#endif |
- skfont->drawText(unicode, &paint, canvas, &pdfContext->fGraphicsState.fMatrixTm); |
+ skfont->drawText(decoded, &paint, pdfContext, canvas, &pdfContext->fGraphicsState.fMatrixTm); |
canvas->restore(); |
-/* |
- PdfString& rString = str->podofo()->GetString(); |
- |
- //pdfContext->fGraphicsState.fSkFont->GetDecoding()->ToUnicode(rString); |
- //void* text; |
- //int len; |
- //SkPaint paint; |
- //pdfContext->fGraphicsState.fSkFont->drawText(text, len, paint, canvas, &pdfContext->fGraphicsState.fMatrixTm); |
- |
- PdfFont* fCurFont = pdfContext->fGraphicsState.fCurFont; |
- |
- if (!fCurFont) |
- { |
- // TODO(edisonn): ignore the error, use the default font? |
- // return kError_PdfResult; |
- } |
- |
- const PdfEncoding* enc = fCurFont ? FixPdfFont(pdfContext, fCurFont) : NULL; |
- bool cMapUnicodeFont = enc != NULL; |
- if (!enc) enc = fCurFont ? fCurFont->GetEncoding() : NULL; |
- if (!enc) |
- { |
- // TODO(edisonn): Can we recover from this error? |
- //return kError_PdfResult; |
- } |
- |
- PdfString r2 = rString; |
- PdfString unicode; |
- |
- if (cMapUnicodeFont) { |
- r2 = PdfString((pdf_utf16be*)rString.GetString(), rString.GetLength() / 2); |
- } |
- |
- unicode = enc ? enc->ConvertToUnicode( r2, fCurFont ) : r2.ToUnicode(); |
- |
-#ifdef PDF_TRACE |
- printf("%i %i ? %c rString.len = %i\n", (int)rString.GetString()[0], (int)rString.GetString()[1], (int)rString.GetString()[1], rString.GetLength()); |
- printf("%i %i %i %i %c unicode.len = %i\n", (int)unicode.GetString()[0], (int)unicode.GetString()[1], (int)unicode.GetString()[2], (int)unicode.GetString()[3], (int)unicode.GetString()[0], unicode.GetLength()); |
-#endif |
- |
- SkPaint paint; |
- // TODO(edisonn): when should fCurFont->GetFontSize() used? When cur is fCurFontSize == 0? |
- // Or maybe just not call setTextSize at all? |
- if (pdfContext->fGraphicsState.fCurFontSize != 0) { |
- paint.setTextSize(SkDoubleToScalar(pdfContext->fGraphicsState.fCurFontSize)); |
- } |
- if (fCurFont && fCurFont->GetFontScale() != 0) { |
- paint.setTextScaleX(SkFloatToScalar(fCurFont->GetFontScale() / 100.0)); |
- } |
- |
- pdfContext->fGraphicsState.applyGraphicsState(&paint, false); |
- |
- paint.setTypeface(SkTypefaceFromPdfFont(fCurFont)); |
- |
- canvas->save(); |
- SkMatrix matrix = pdfContext->fGraphicsState.fMatrixTm; |
- |
-#if 0 |
- // Reverse now the space, otherwise the text is upside down. |
- SkScalar z = SkIntToScalar(0); |
- SkScalar one = SkIntToScalar(1); |
- |
- SkPoint normalSpace1[4] = {SkPoint::Make(z, z), SkPoint::Make(one, z), SkPoint::Make(one, one), SkPoint::Make(z, one)}; |
- SkPoint mirrorSpace1[4]; |
- pdfContext->fGraphicsState.fMatrixTm.mapPoints(mirrorSpace1, normalSpace1, 4); |
- |
- SkPoint normalSpace2[4] = {SkPoint::Make(z, z), SkPoint::Make(one, z), SkPoint::Make(one, -one), SkPoint::Make(z, -one)}; |
- SkPoint mirrorSpace2[4]; |
- pdfContext->fGraphicsState.fMatrixTm.mapPoints(mirrorSpace2, normalSpace2, 4); |
- |
-#ifdef PDF_TRACE |
- printf("mirror1[0], x = %f y = %f\n", SkScalarToDouble(mirrorSpace1[0].x()), SkScalarToDouble(mirrorSpace1[0].y())); |
- printf("mirror1[1], x = %f y = %f\n", SkScalarToDouble(mirrorSpace1[1].x()), SkScalarToDouble(mirrorSpace1[1].y())); |
- printf("mirror1[2], x = %f y = %f\n", SkScalarToDouble(mirrorSpace1[2].x()), SkScalarToDouble(mirrorSpace1[2].y())); |
- printf("mirror1[3], x = %f y = %f\n", SkScalarToDouble(mirrorSpace1[3].x()), SkScalarToDouble(mirrorSpace1[3].y())); |
- printf("mirror2[0], x = %f y = %f\n", SkScalarToDouble(mirrorSpace2[0].x()), SkScalarToDouble(mirrorSpace2[0].y())); |
- printf("mirror2[1], x = %f y = %f\n", SkScalarToDouble(mirrorSpace2[1].x()), SkScalarToDouble(mirrorSpace2[1].y())); |
- printf("mirror2[2], x = %f y = %f\n", SkScalarToDouble(mirrorSpace2[2].x()), SkScalarToDouble(mirrorSpace2[2].y())); |
- printf("mirror2[3], x = %f y = %f\n", SkScalarToDouble(mirrorSpace2[3].x()), SkScalarToDouble(mirrorSpace2[3].y())); |
-#endif |
- |
- SkMatrix mirror; |
- SkASSERT(mirror.setPolyToPoly(mirrorSpace1, mirrorSpace2, 4)); |
- |
- // TODO(edisonn): text positioning wrong right now. Need to get matrix operations right. |
- matrix.preConcat(mirror); |
- canvas->setMatrix(matrix); |
-#endif |
- |
- SkPoint point1; |
- pdfContext->fGraphicsState.fMatrixTm.mapXY(SkIntToScalar(0), SkIntToScalar(0), &point1); |
- |
- SkMatrix mirror; |
- mirror.setTranslate(0, -point1.y()); |
- // TODO(edisonn): fix rotated text, and skewed too |
- mirror.postScale(SK_Scalar1, -SK_Scalar1); |
- // TODO(edisonn): post rotate, skew |
- mirror.postTranslate(0, point1.y()); |
- |
- matrix.postConcat(mirror); |
- |
- canvas->setMatrix(matrix); |
- |
- SkTraceMatrix(matrix, "mirrored"); |
- |
-#ifdef PDF_TRACE |
- SkPoint point; |
- pdfContext->fGraphicsState.fMatrixTm.mapXY(SkDoubleToScalar(0), SkDoubleToScalar(0), &point); |
- printf("Original SkCanvas resolved coordinates, x = %f y = %f\n", SkScalarToDouble(point.x()), SkScalarToDouble(point.y())); |
- matrix.mapXY(SkDoubleToScalar(0), SkDoubleToScalar(0), &point); |
- printf("Mirored SkCanvas resolved coordinates, x = %f y = %f\n", SkScalarToDouble(point.x()), SkScalarToDouble(point.y())); |
-#endif |
- |
- // TODO(edisonn): remove this call once we load the font properly |
- // The extra * will show that we got at least the text positioning right |
- // even if font failed to be loaded |
-// canvas->drawText(".", 1, SkDoubleToScalar(-5.0), SkDoubleToScalar(0.0), paint); |
- |
- |
- |
- // TODO(edisonn): use character and word spacing .. add utility function |
- if (cMapUnicodeFont) { |
- paint.setTextEncoding(SkPaint::kUTF16_TextEncoding); |
- SkScalar textWidth = paint.measureText(unicode.GetString(), unicode.GetLength()); |
- pdfContext->fGraphicsState.fMatrixTm.preTranslate(textWidth, SkDoubleToScalar(0.0)); |
- canvas->drawText(unicode.GetString(), unicode.GetLength(), SkDoubleToScalar(0.0), SkDoubleToScalar(0.0), paint); |
- } |
- else { |
- paint.setTextEncoding(SkPaint::kUTF8_TextEncoding); |
- SkScalar textWidth = paint.measureText(unicode.GetStringUtf8().c_str(), strlen(unicode.GetStringUtf8().c_str())); |
- pdfContext->fGraphicsState.fMatrixTm.preTranslate(textWidth, SkDoubleToScalar(0.0)); |
- canvas->drawText(unicode.GetStringUtf8().c_str(), strlen(unicode.GetStringUtf8().c_str()), SkDoubleToScalar(0.0), SkDoubleToScalar(0.0), paint); |
- } |
- |
-// paint.setTextEncoding(SkPaint::kUTF8_TextEncoding); |
-// unsigned char ch = *(unicode.GetString() + 3); |
-// if ((ch & 0xC0) != 0x80 && ch < 0x80) { |
-// printf("x%i", ch); |
-// SkScalar textWidth = paint.measureText(&ch, 1); |
-// pdfContext->fGraphicsState.fMatrixTm.preTranslate(textWidth, SkDoubleToScalar(0.0)); |
-// canvas->drawText(&ch, 1, SkDoubleToScalar(0.0), SkDoubleToScalar(0.0), paint); |
-// } |
- |
- canvas->restore(); |
- |
-*/ |
return kPartial_PdfResult; |
} |
@@ -1028,6 +626,35 @@ |
return StringFromDictionary(pdfDoc, dict, abr, data); |
} |
+bool ArrayFromDictionary(const PdfMemDocument* pdfDoc, |
+ const PdfDictionary& dict, |
+ const char* key, |
+ SkPdfArray** data) { |
+ const PdfObject* value = resolveReferenceObject(pdfDoc, |
+ dict.GetKey(PdfName(key)), |
+ true); |
+ if (value == NULL || !value->IsArray()) { |
+ return false; |
+ } |
+ if (data == NULL) { |
+ return true; |
+ } |
+ |
+ return PodofoMapper::map(*pdfDoc, *value, (SkPdfObject**)data); |
+} |
+ |
+ |
+bool ArrayFromDictionary(const PdfMemDocument* pdfDoc, |
+ const PdfDictionary& dict, |
+ const char* key, |
+ const char* abr, |
+ SkPdfArray** data) { |
+ if (ArrayFromDictionary(pdfDoc, dict, key, data)) return true; |
+ if (abr == NULL || *abr == '\0') return false; |
+ return ArrayFromDictionary(pdfDoc, dict, abr, data); |
+} |
+ |
+ |
bool DictionaryFromDictionary(const PdfMemDocument* pdfDoc, |
const PdfDictionary& dict, |
const char* key, |
@@ -1059,7 +686,7 @@ |
bool DictionaryFromDictionary2(const PdfMemDocument* pdfDoc, |
const PdfDictionary& dict, |
const char* key, |
- SkPdfDictionary** data) { |
+ T** data) { |
const PdfObject* value = resolveReferenceObject(pdfDoc, |
dict.GetKey(PdfName(key)), |
true); |
@@ -1337,7 +964,7 @@ |
} |
SkBitmap getSmaskFromObject(PdfContext* pdfContext, const SkPdfImageDictionary* obj) { |
- const PdfObject* sMask = resolveReferenceObject(&pdfContext->fPdfDoc.podofo(), |
+ const PdfObject* sMask = resolveReferenceObject(&pdfContext->fPdfDoc->podofo(), |
obj->podofo()->GetDictionary().GetKey(PdfName("SMask"))); |
#ifdef PDF_TRACE |
@@ -1349,7 +976,7 @@ |
#endif |
if (sMask) { |
- SkPdfImageDictionary skxobjmask(&pdfContext->fPdfDoc.podofo(), sMask); |
+ SkPdfImageDictionary skxobjmask(&pdfContext->fPdfDoc->podofo(), sMask); |
return getImageFromObject(pdfContext, &skxobjmask, true); |
} |
@@ -1386,11 +1013,11 @@ |
return kPartial_PdfResult; |
} |
-bool SkMatrixFromDictionary(PdfContext* pdfContext, |
+bool SkMatrixFromDictionary(const PdfMemDocument* pdfDoc, |
const PdfDictionary& dict, |
const char* key, |
- SkMatrix* matrix) { |
- const PdfObject* value = resolveReferenceObject(&pdfContext->fPdfDoc.podofo(), |
+ SkMatrix** matrix) { |
+ const PdfObject* value = resolveReferenceObject(pdfDoc, |
dict.GetKey(PdfName(key))); |
if (value == NULL || !value->IsArray()) { |
@@ -1403,21 +1030,33 @@ |
double array[6]; |
for (int i = 0; i < 6; i++) { |
- const PdfObject* elem = resolveReferenceObject(&pdfContext->fPdfDoc.podofo(), &value->GetArray()[i]); |
+ const PdfObject* elem = resolveReferenceObject(pdfDoc, &value->GetArray()[i]); |
if (elem == NULL || (!elem->IsReal() && !elem->IsNumber())) { |
return false; |
} |
array[i] = elem->GetReal(); |
} |
- *matrix = SkMatrixFromPdfMatrix(array); |
+ *matrix = new SkMatrix(); |
+ **matrix = SkMatrixFromPdfMatrix(array); |
return true; |
} |
+bool SkMatrixFromDictionary(const PdfMemDocument* pdfDoc, |
+ const PdfDictionary& dict, |
+ const char* key, |
+ const char* abr, |
+ SkMatrix** data) { |
+ if (SkMatrixFromDictionary(pdfDoc, dict, key, data)) return true; |
+ if (abr == NULL || *abr == '\0') return false; |
+ return SkMatrixFromDictionary(pdfDoc, dict, abr, data); |
+ |
+} |
+ |
bool SkRectFromDictionary(const PdfMemDocument* pdfDoc, |
const PdfDictionary& dict, |
const char* key, |
- SkRect* rect) { |
+ SkRect** rect) { |
const PdfObject* value = resolveReferenceObject(pdfDoc, |
dict.GetKey(PdfName(key))); |
@@ -1438,10 +1077,11 @@ |
array[i] = elem->GetReal(); |
} |
- *rect = SkRect::MakeLTRB(SkDoubleToScalar(array[0]), |
- SkDoubleToScalar(array[1]), |
- SkDoubleToScalar(array[2]), |
- SkDoubleToScalar(array[3])); |
+ *rect = new SkRect(); |
+ **rect = SkRect::MakeLTRB(SkDoubleToScalar(array[0]), |
+ SkDoubleToScalar(array[1]), |
+ SkDoubleToScalar(array[2]), |
+ SkDoubleToScalar(array[3])); |
return true; |
} |
@@ -1449,7 +1089,7 @@ |
const PdfDictionary& dict, |
const char* key, |
const char* abr, |
- SkRect* data) { |
+ SkRect** data) { |
if (SkRectFromDictionary(pdfDoc, dict, key, data)) return true; |
if (abr == NULL || *abr == '\0') return false; |
return SkRectFromDictionary(pdfDoc, dict, abr, data); |
@@ -1475,21 +1115,15 @@ |
PdfOp_q(pdfContext, canvas, NULL); |
canvas->save(); |
- if (get(skobj, "Resources")) { |
- SkPdfResourceDictionary* res = NULL; |
- PodofoMapper::map(*get(skobj, "Resources"), &res); |
- |
- if (res) { |
- pdfContext->fGraphicsState.fResources = res; |
- } |
+ if (skobj->Resources()) { |
+ pdfContext->fGraphicsState.fResources = skobj->Resources(); |
} |
SkTraceMatrix(pdfContext->fGraphicsState.fMatrix, "Current matrix"); |
- SkMatrix matrix; |
- if (SkMatrixFromDictionary(pdfContext, skobj->podofo()->GetDictionary(), "Matrix", &matrix)) { |
- pdfContext->fGraphicsState.fMatrix.preConcat(matrix); |
+ if (skobj->Matrix()) { |
+ pdfContext->fGraphicsState.fMatrix.preConcat(*skobj->Matrix()); |
pdfContext->fGraphicsState.fMatrixTm = pdfContext->fGraphicsState.fMatrix; |
pdfContext->fGraphicsState.fMatrixTlm = pdfContext->fGraphicsState.fMatrix; |
// TODO(edisonn) reset matrixTm and matricTlm also? |
@@ -1499,9 +1133,8 @@ |
canvas->setMatrix(pdfContext->fGraphicsState.fMatrix); |
- SkRect bbox; |
- if (SkRectFromDictionary(&pdfContext->fPdfDoc.podofo(), skobj->podofo()->GetDictionary(), "BBox", &bbox)) { |
- canvas->clipRect(bbox, SkRegion::kIntersect_Op, true); // TODO(edisonn): AA from settings. |
+ if (skobj->BBox()) { |
+ canvas->clipRect(*skobj->BBox(), SkRegion::kIntersect_Op, true); // TODO(edisonn): AA from settings. |
} |
// TODO(edisonn): iterate smart on the stream even if it is compressed, tokenize it as we go. |
@@ -1523,6 +1156,47 @@ |
return kNYI_PdfResult; |
} |
+PdfResult doType3Char(PdfContext* pdfContext, SkCanvas* canvas, SkPdfObject* skobj, SkRect bBox, SkMatrix matrix, double textSize) { |
+ if (!skobj || !skobj->podofo() || !skobj->podofo()->HasStream() || skobj->podofo()->GetStream() == NULL || skobj->podofo()->GetStream()->GetLength() == 0) { |
+ return kOK_PdfResult; |
+ } |
+ |
+ PdfOp_q(pdfContext, canvas, NULL); |
+ canvas->save(); |
+ |
+ pdfContext->fGraphicsState.fMatrixTm.preConcat(matrix); |
+ pdfContext->fGraphicsState.fMatrixTm.preScale(SkDoubleToScalar(textSize), SkDoubleToScalar(textSize)); |
+ |
+ pdfContext->fGraphicsState.fMatrix = pdfContext->fGraphicsState.fMatrixTm; |
+ pdfContext->fGraphicsState.fMatrixTlm = pdfContext->fGraphicsState.fMatrix; |
+ |
+ SkTraceMatrix(pdfContext->fGraphicsState.fMatrix, "Total matrix"); |
+ |
+ canvas->setMatrix(pdfContext->fGraphicsState.fMatrix); |
+ |
+ SkRect rm = bBox; |
+ pdfContext->fGraphicsState.fMatrix.mapRect(&rm); |
+ |
+ SkTraceRect(rm, "bbox mapped"); |
+ |
+ canvas->clipRect(bBox, SkRegion::kIntersect_Op, true); // TODO(edisonn): AA from settings. |
+ |
+ // TODO(edisonn): iterate smart on the stream even if it is compressed, tokenize it as we go. |
+ // For this PdfContentsTokenizer needs to be extended. |
+ |
+ PdfResult ret = kPartial_PdfResult; |
+ SkPdfTokenizer tokenizer(skobj); |
+ PdfMainLooper looper(NULL, &tokenizer, pdfContext, canvas); |
+ looper.loop(); |
+ |
+ // TODO(edisonn): should we restore the variable stack at the same state? |
+ // There could be operands left, that could be consumed by a parent tokenizer when we pop. |
+ canvas->restore(); |
+ PdfOp_Q(pdfContext, canvas, NULL); |
+ return ret; |
+} |
+ |
+ |
// TODO(edisonn): faster, have the property on the SkPdfObject itself? |
std::set<const PdfObject*> gInRendering; |
@@ -1651,15 +1325,15 @@ |
// TODO(edisonn): Create factory methods or constructors so podofo is hidden |
PdfObject _ty(PdfVariant(-ty)); |
- pdfContext->fObjectStack.push(new SkPdfNumber(&pdfContext->fPdfDoc.podofo(), &_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) |
- pdfContext->fObjectStack.push(new SkPdfNumber(&pdfContext->fPdfDoc.podofo(), &vtx)); |
+ pdfContext->fObjectStack.push(new SkPdfNumber(&pdfContext->fPdfDoc->podofo(), &vtx)); |
PdfObject vty(PdfVariant(-(-ty))); |
- pdfContext->fObjectStack.push(new SkPdfNumber(&pdfContext->fPdfDoc.podofo(), &vty)); |
+ pdfContext->fObjectStack.push(new SkPdfNumber(&pdfContext->fPdfDoc->podofo(), &vty)); |
return PdfOp_Td(pdfContext, canvas, looper); |
} |
@@ -1697,8 +1371,8 @@ |
PdfObject zero(PdfVariant(0.0)); |
PdfObject tl(PdfVariant(-(-pdfContext->fGraphicsState.fTextLeading))); |
- pdfContext->fObjectStack.push(new SkPdfNumber(&pdfContext->fPdfDoc.podofo(), &zero)); |
- pdfContext->fObjectStack.push(new SkPdfNumber(&pdfContext->fPdfDoc.podofo(), &tl)); |
+ pdfContext->fObjectStack.push(new SkPdfNumber(&pdfContext->fPdfDoc->podofo(), &zero)); |
+ pdfContext->fObjectStack.push(new SkPdfNumber(&pdfContext->fPdfDoc->podofo(), &tl)); |
return PdfOp_Td(pdfContext, canvas, looper); |
} |
@@ -1823,7 +1497,6 @@ |
PdfResult PdfOp_h(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) { |
pdfContext->fGraphicsState.fPath.close(); |
- pdfContext->fGraphicsState.fPathClosed = true; |
return kOK_PdfResult; |
} |
@@ -1972,11 +1645,11 @@ |
SkPdfFontDictionary* fd = NULL; |
if (pdfContext->fGraphicsState.fResources->Font()) { |
- SkPdfObject objFont = pdfContext->fGraphicsState.fResources->Font()->get(fontName.c_str()); |
- PodofoMapper::map(objFont, &fd); |
+ SkPdfObject* objFont = pdfContext->fGraphicsState.fResources->Font()->get(fontName.c_str()); |
+ PodofoMapper::map(*objFont, &fd); |
#ifdef PDF_TRACE |
- objFont.podofo()->ToString(str); |
+ objFont->podofo()->ToString(str); |
printf("Print Font loaded: %s\n", str.c_str()); |
fd->podofo()->ToString(str); |
printf("Print Font loaded and resolved and upgraded: %s\n", str.c_str()); |
@@ -1990,24 +1663,6 @@ |
pdfContext->fGraphicsState.fSkFont = skfont; |
} |
- // TODO(edisonn): Load font from pdfContext->fGraphicsState.fObjectWithResources ? |
- const PdfObject* pFont = resolveReferenceObject(&pdfContext->fPdfDoc.podofo(), |
- pdfContext->fGraphicsState.fResources->Font()->get(fontName.c_str()).podofo()); |
- if( !pFont ) |
- { |
- // TODO(edisonn): try to ignore the error, make sure we do not crash. |
- return kIgnoreError_PdfResult; |
- } |
- |
- PdfFont* font = pdfContext->fPdfDoc.podofo().GetFont( (PdfObject*)pFont ); |
- if (font) { |
- pdfContext->fGraphicsState.fCurFont = font; |
- } else { |
- // TODO(edisonn): check ~/crasing, for one of the files PoDoFo throws exception |
- // when calling pFont->Reference(), with Linked list corruption. |
- return kIgnoreError_PdfResult; |
- } |
- |
return kPartial_PdfResult; |
} |
@@ -2350,7 +2005,7 @@ |
return kIgnoreError_PdfResult; |
} |
- SkPdfObject value = extGStateDictionary->get(name.c_str()); |
+ SkPdfObject* value = extGStateDictionary->get(name.c_str()); |
#ifdef PDF_TRACE |
// value->ToString(str); |
@@ -2358,7 +2013,7 @@ |
#endif |
SkPdfGraphicsStateDictionary* gs = NULL; |
- PodofoMapper::map(value, &gs); |
+ PodofoMapper::map(*value, &gs); |
// TODO(edisonn): now load all those properties in graphic state. |
if (gs == NULL) { |
@@ -2420,7 +2075,6 @@ |
return kNYI_PdfResult; |
} |
- |
//rise Ts Set the text rise, Trise, to rise, which is a number expressed in unscaled text space |
//units. Initial value: 0. |
PdfResult PdfOp_Ts(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) { |
@@ -2469,14 +2123,14 @@ |
return kIgnoreError_PdfResult; |
} |
- SkPdfObject value = xObject->get(name.c_str()); |
+ SkPdfObject* value = xObject->get(name.c_str()); |
#ifdef PDF_TRACE |
// value->ToString(str); |
// printf("Do object value: %s\n", str.c_str()); |
#endif |
- return doXObject(pdfContext, canvas, value); |
+ return doXObject(pdfContext, canvas, *value); |
} |
//tag MP Designate a marked-content point. tag is a name object indicating the role or |
@@ -2779,7 +2433,7 @@ |
SkBitmap bitmap; |
#ifdef PDF_DEBUG_3X |
- setup_bitmap(&bitmap, 3 * (int)SkScalarToDouble(rect.width()), 3 * (int)SkScalarToDouble(rect.height())) |
+ setup_bitmap(&bitmap, 3 * (int)SkScalarToDouble(rect.width()), 3 * (int)SkScalarToDouble(rect.height())); |
#else |
setup_bitmap(&bitmap, (int)SkScalarToDouble(rect.width()), (int)SkScalarToDouble(rect.height())); |
#endif |
@@ -2788,7 +2442,7 @@ |
SkPdfTokenizer* tokenizer = doc.tokenizerOfPage(pn); |
- PdfContext pdfContext(doc); |
+ PdfContext pdfContext(&doc); |
pdfContext.fOriginalMatrix = SkMatrix::I(); |
pdfContext.fGraphicsState.fResources = NULL; |
PodofoMapper::map(*page->Resources(), &pdfContext.fGraphicsState.fResources); |