From 063d7072ef45971c17045721626b3f0cd052b3b9 Mon Sep 17 00:00:00 2001 From: "edisonn@google.com" Date: Fri, 16 Aug 2013 15:05:08 +0000 Subject: pdfviewer: code cleanup - remove STL usage Review URL: https://codereview.chromium.org/23258004 git-svn-id: http://skia.googlecode.com/svn/trunk@10772 2bbb7eff-a529-9590-31e7-b0007b416f81 --- experimental/PdfViewer/SkPdfFont.cpp | 172 +++++++++++---------- experimental/PdfViewer/SkPdfFont.h | 9 +- experimental/PdfViewer/SkPdfGraphicsState.h | 108 ++++++++++++- experimental/PdfViewer/SkPdfRenderer.cpp | 58 +++---- experimental/PdfViewer/SkPdfUtils.cpp | 4 + experimental/PdfViewer/SkPdfUtils.h | 5 + experimental/PdfViewer/generate_code.py | 8 +- .../pdfparser/native/SkPdfNativeObject.cpp | 2 +- .../PdfViewer/pdfparser/native/SkPdfNativeObject.h | 24 ++- 9 files changed, 249 insertions(+), 141 deletions(-) (limited to 'experimental/PdfViewer') diff --git a/experimental/PdfViewer/SkPdfFont.cpp b/experimental/PdfViewer/SkPdfFont.cpp index 46cbf5715e..90c54e55f7 100644 --- a/experimental/PdfViewer/SkPdfFont.cpp +++ b/experimental/PdfViewer/SkPdfFont.cpp @@ -4,89 +4,89 @@ #include "SkTypeface.h" #include "SkPdfNativeTokenizer.h" -std::map& getStandardFonts() { - static std::map gPdfStandardFonts; +SkTDict& getStandardFonts() { + static SkTDict gPdfStandardFonts(100); // TODO (edisonn): , vs - ? what does it mean? // TODO (edisonn): MT, PS, Oblique=italic?, ... what does it mean? - if (gPdfStandardFonts.empty()) { - gPdfStandardFonts["Arial"] = SkPdfStandardFontEntry("Arial", false, false); - gPdfStandardFonts["Arial,Bold"] = SkPdfStandardFontEntry("Arial", true, false); - gPdfStandardFonts["Arial,BoldItalic"] = SkPdfStandardFontEntry("Arial", true, true); - gPdfStandardFonts["Arial,Italic"] = SkPdfStandardFontEntry("Arial", false, true); - gPdfStandardFonts["Arial-Bold"] = SkPdfStandardFontEntry("Arial", true, false); - gPdfStandardFonts["Arial-BoldItalic"] = SkPdfStandardFontEntry("Arial", true, true); - gPdfStandardFonts["Arial-BoldItalicMT"] = SkPdfStandardFontEntry("Arial", true, true); - gPdfStandardFonts["Arial-BoldMT"] = SkPdfStandardFontEntry("Arial", true, false); - gPdfStandardFonts["Arial-Italic"] = SkPdfStandardFontEntry("Arial", false, true); - gPdfStandardFonts["Arial-ItalicMT"] = SkPdfStandardFontEntry("Arial", false, true); - gPdfStandardFonts["ArialMT"] = SkPdfStandardFontEntry("Arial", false, false); - gPdfStandardFonts["Courier"] = SkPdfStandardFontEntry("Courier New", false, false); - gPdfStandardFonts["Courier,Bold"] = SkPdfStandardFontEntry("Courier New", true, false); - gPdfStandardFonts["Courier,BoldItalic"] = SkPdfStandardFontEntry("Courier New", true, true); - gPdfStandardFonts["Courier,Italic"] = SkPdfStandardFontEntry("Courier New", false, true); - gPdfStandardFonts["Courier-Bold"] = SkPdfStandardFontEntry("Courier New", true, false); - gPdfStandardFonts["Courier-BoldOblique"] = SkPdfStandardFontEntry("Courier New", true, true); - gPdfStandardFonts["Courier-Oblique"] = SkPdfStandardFontEntry("Courier New", false, true); - gPdfStandardFonts["CourierNew"] = SkPdfStandardFontEntry("Courier New", false, false); - gPdfStandardFonts["CourierNew,Bold"] = SkPdfStandardFontEntry("Courier New", true, false); - gPdfStandardFonts["CourierNew,BoldItalic"] = SkPdfStandardFontEntry("Courier New", true, true); - gPdfStandardFonts["CourierNew,Italic"] = SkPdfStandardFontEntry("Courier New", false, true); - gPdfStandardFonts["CourierNew-Bold"] = SkPdfStandardFontEntry("Courier New", true, false); - gPdfStandardFonts["CourierNew-BoldItalic"] = SkPdfStandardFontEntry("Courier New", true, true); - gPdfStandardFonts["CourierNew-Italic"] = SkPdfStandardFontEntry("Courier New", false, true); - gPdfStandardFonts["CourierNewPS-BoldItalicMT"] = SkPdfStandardFontEntry("Courier New", true, true); - gPdfStandardFonts["CourierNewPS-BoldMT"] = SkPdfStandardFontEntry("Courier New", true, false); - gPdfStandardFonts["CourierNewPS-ItalicMT"] = SkPdfStandardFontEntry("Courier New", false, true); - gPdfStandardFonts["CourierNewPSMT"] = SkPdfStandardFontEntry("Courier New", false, false); - gPdfStandardFonts["Helvetica"] = SkPdfStandardFontEntry("Helvetica", false, false); - gPdfStandardFonts["Helvetica,Bold"] = SkPdfStandardFontEntry("Helvetica", true, false); - gPdfStandardFonts["Helvetica,BoldItalic"] = SkPdfStandardFontEntry("Helvetica", true, true); - gPdfStandardFonts["Helvetica,Italic"] = SkPdfStandardFontEntry("Helvetica", false, true); - gPdfStandardFonts["Helvetica-Bold"] = SkPdfStandardFontEntry("Helvetica", true, false); - gPdfStandardFonts["Helvetica-BoldItalic"] = SkPdfStandardFontEntry("Helvetica", true, true); - gPdfStandardFonts["Helvetica-BoldOblique"] = SkPdfStandardFontEntry("Helvetica", true, true); - gPdfStandardFonts["Helvetica-Italic"] = SkPdfStandardFontEntry("Helvetica", false, true); - gPdfStandardFonts["Helvetica-Oblique"] = SkPdfStandardFontEntry("Helvetica", false, true); - gPdfStandardFonts["Times-Bold"] = SkPdfStandardFontEntry("Times New Roman", true, false); - gPdfStandardFonts["Times-BoldItalic"] = SkPdfStandardFontEntry("Times New Roman", true, true); - gPdfStandardFonts["Times-Italic"] = SkPdfStandardFontEntry("Times New Roman", false, true); - gPdfStandardFonts["Times-Roman"] = SkPdfStandardFontEntry("Times New Roman", false, false); - gPdfStandardFonts["TimesNewRoman"] = SkPdfStandardFontEntry("Times New Roman", false, false); - gPdfStandardFonts["TimesNewRoman,Bold"] = SkPdfStandardFontEntry("Times New Roman", true, false); - gPdfStandardFonts["TimesNewRoman,BoldItalic"] = SkPdfStandardFontEntry("Times New Roman", true, true); - gPdfStandardFonts["TimesNewRoman,Italic"] = SkPdfStandardFontEntry("Times New Roman", false, true); - gPdfStandardFonts["TimesNewRoman-Bold"] = SkPdfStandardFontEntry("Times New Roman", true, false); - gPdfStandardFonts["TimesNewRoman-BoldItalic"] = SkPdfStandardFontEntry("Times New Roman", true, true); - gPdfStandardFonts["TimesNewRoman-Italic"] = SkPdfStandardFontEntry("Times New Roman", false, true); - gPdfStandardFonts["TimesNewRomanPS"] = SkPdfStandardFontEntry("Times New Roman", false, false); - gPdfStandardFonts["TimesNewRomanPS-Bold"] = SkPdfStandardFontEntry("Times New Roman", true, false); - gPdfStandardFonts["TimesNewRomanPS-BoldItalic"] = SkPdfStandardFontEntry("Times New Roman", true, true); - gPdfStandardFonts["TimesNewRomanPS-BoldItalicMT"] = SkPdfStandardFontEntry("Times New Roman", true, true); - gPdfStandardFonts["TimesNewRomanPS-BoldMT"] = SkPdfStandardFontEntry("Times New Roman", true, false); - gPdfStandardFonts["TimesNewRomanPS-Italic"] = SkPdfStandardFontEntry("Times New Roman", false, true); - gPdfStandardFonts["TimesNewRomanPS-ItalicMT"] = SkPdfStandardFontEntry("Times New Roman", false, true); - gPdfStandardFonts["TimesNewRomanPSMT"] = SkPdfStandardFontEntry("Times New Roman", false, false); - gPdfStandardFonts["Symbol"] = SkPdfStandardFontEntry("Symbol", false, false); - gPdfStandardFonts["ZapfDingbats"] = SkPdfStandardFontEntry("ZapfDingbats", false, false); + if (gPdfStandardFonts.count() == 0) { + gPdfStandardFonts.set("Arial", SkPdfStandardFontEntry("Arial", false, false)); + gPdfStandardFonts.set("Arial,Bold", SkPdfStandardFontEntry("Arial", true, false)); + gPdfStandardFonts.set("Arial,BoldItalic", SkPdfStandardFontEntry("Arial", true, true)); + gPdfStandardFonts.set("Arial,Italic", SkPdfStandardFontEntry("Arial", false, true)); + gPdfStandardFonts.set("Arial-Bold", SkPdfStandardFontEntry("Arial", true, false)); + gPdfStandardFonts.set("Arial-BoldItalic", SkPdfStandardFontEntry("Arial", true, true)); + gPdfStandardFonts.set("Arial-BoldItalicMT", SkPdfStandardFontEntry("Arial", true, true)); + gPdfStandardFonts.set("Arial-BoldMT", SkPdfStandardFontEntry("Arial", true, false)); + gPdfStandardFonts.set("Arial-Italic", SkPdfStandardFontEntry("Arial", false, true)); + gPdfStandardFonts.set("Arial-ItalicMT", SkPdfStandardFontEntry("Arial", false, true)); + gPdfStandardFonts.set("ArialMT", SkPdfStandardFontEntry("Arial", false, false)); + gPdfStandardFonts.set("Courier", SkPdfStandardFontEntry("Courier New", false, false)); + gPdfStandardFonts.set("Courier,Bold", SkPdfStandardFontEntry("Courier New", true, false)); + gPdfStandardFonts.set("Courier,BoldItalic", SkPdfStandardFontEntry("Courier New", true, true)); + gPdfStandardFonts.set("Courier,Italic", SkPdfStandardFontEntry("Courier New", false, true)); + gPdfStandardFonts.set("Courier-Bold", SkPdfStandardFontEntry("Courier New", true, false)); + gPdfStandardFonts.set("Courier-BoldOblique", SkPdfStandardFontEntry("Courier New", true, true)); + gPdfStandardFonts.set("Courier-Oblique", SkPdfStandardFontEntry("Courier New", false, true)); + gPdfStandardFonts.set("CourierNew", SkPdfStandardFontEntry("Courier New", false, false)); + gPdfStandardFonts.set("CourierNew,Bold", SkPdfStandardFontEntry("Courier New", true, false)); + gPdfStandardFonts.set("CourierNew,BoldItalic", SkPdfStandardFontEntry("Courier New", true, true)); + gPdfStandardFonts.set("CourierNew,Italic", SkPdfStandardFontEntry("Courier New", false, true)); + gPdfStandardFonts.set("CourierNew-Bold", SkPdfStandardFontEntry("Courier New", true, false)); + gPdfStandardFonts.set("CourierNew-BoldItalic", SkPdfStandardFontEntry("Courier New", true, true)); + gPdfStandardFonts.set("CourierNew-Italic", SkPdfStandardFontEntry("Courier New", false, true)); + gPdfStandardFonts.set("CourierNewPS-BoldItalicMT", SkPdfStandardFontEntry("Courier New", true, true)); + gPdfStandardFonts.set("CourierNewPS-BoldMT", SkPdfStandardFontEntry("Courier New", true, false)); + gPdfStandardFonts.set("CourierNewPS-ItalicMT", SkPdfStandardFontEntry("Courier New", false, true)); + gPdfStandardFonts.set("CourierNewPSMT", SkPdfStandardFontEntry("Courier New", false, false)); + gPdfStandardFonts.set("Helvetica", SkPdfStandardFontEntry("Helvetica", false, false)); + gPdfStandardFonts.set("Helvetica,Bold", SkPdfStandardFontEntry("Helvetica", true, false)); + gPdfStandardFonts.set("Helvetica,BoldItalic", SkPdfStandardFontEntry("Helvetica", true, true)); + gPdfStandardFonts.set("Helvetica,Italic", SkPdfStandardFontEntry("Helvetica", false, true)); + gPdfStandardFonts.set("Helvetica-Bold", SkPdfStandardFontEntry("Helvetica", true, false)); + gPdfStandardFonts.set("Helvetica-BoldItalic", SkPdfStandardFontEntry("Helvetica", true, true)); + gPdfStandardFonts.set("Helvetica-BoldOblique", SkPdfStandardFontEntry("Helvetica", true, true)); + gPdfStandardFonts.set("Helvetica-Italic", SkPdfStandardFontEntry("Helvetica", false, true)); + gPdfStandardFonts.set("Helvetica-Oblique", SkPdfStandardFontEntry("Helvetica", false, true)); + gPdfStandardFonts.set("Times-Bold", SkPdfStandardFontEntry("Times New Roman", true, false)); + gPdfStandardFonts.set("Times-BoldItalic", SkPdfStandardFontEntry("Times New Roman", true, true)); + gPdfStandardFonts.set("Times-Italic", SkPdfStandardFontEntry("Times New Roman", false, true)); + gPdfStandardFonts.set("Times-Roman", SkPdfStandardFontEntry("Times New Roman", false, false)); + gPdfStandardFonts.set("TimesNewRoman", SkPdfStandardFontEntry("Times New Roman", false, false)); + gPdfStandardFonts.set("TimesNewRoman,Bold", SkPdfStandardFontEntry("Times New Roman", true, false)); + gPdfStandardFonts.set("TimesNewRoman,BoldItalic", SkPdfStandardFontEntry("Times New Roman", true, true)); + gPdfStandardFonts.set("TimesNewRoman,Italic", SkPdfStandardFontEntry("Times New Roman", false, true)); + gPdfStandardFonts.set("TimesNewRoman-Bold", SkPdfStandardFontEntry("Times New Roman", true, false)); + gPdfStandardFonts.set("TimesNewRoman-BoldItalic", SkPdfStandardFontEntry("Times New Roman", true, true)); + gPdfStandardFonts.set("TimesNewRoman-Italic", SkPdfStandardFontEntry("Times New Roman", false, true)); + gPdfStandardFonts.set("TimesNewRomanPS", SkPdfStandardFontEntry("Times New Roman", false, false)); + gPdfStandardFonts.set("TimesNewRomanPS-Bold", SkPdfStandardFontEntry("Times New Roman", true, false)); + gPdfStandardFonts.set("TimesNewRomanPS-BoldItalic", SkPdfStandardFontEntry("Times New Roman", true, true)); + gPdfStandardFonts.set("TimesNewRomanPS-BoldItalicMT", SkPdfStandardFontEntry("Times New Roman", true, true)); + gPdfStandardFonts.set("TimesNewRomanPS-BoldMT", SkPdfStandardFontEntry("Times New Roman", true, false)); + gPdfStandardFonts.set("TimesNewRomanPS-Italic", SkPdfStandardFontEntry("Times New Roman", false, true)); + gPdfStandardFonts.set("TimesNewRomanPS-ItalicMT", SkPdfStandardFontEntry("Times New Roman", false, true)); + gPdfStandardFonts.set("TimesNewRomanPSMT", SkPdfStandardFontEntry("Times New Roman", false, false)); + gPdfStandardFonts.set("Symbol", SkPdfStandardFontEntry("Symbol", false, false)); + gPdfStandardFonts.set("ZapfDingbats", SkPdfStandardFontEntry("ZapfDingbats", false, false)); // TODO(edisonn): these are hacks. Load Post Script font name. // see FT_Get_Postscript_Name // Font config is not using it, yet. //https://bugs.freedesktop.org/show_bug.cgi?id=18095 - gPdfStandardFonts["Arial-Black"] = SkPdfStandardFontEntry("Arial", true, false); - gPdfStandardFonts["DejaVuSans"] = SkPdfStandardFontEntry("DejaVu Sans", false, false); - gPdfStandardFonts["DejaVuSansMono"] = SkPdfStandardFontEntry("DejaVuSans Mono", false, false); - gPdfStandardFonts["DejaVuSansMono-Bold"] = SkPdfStandardFontEntry("DejaVuSans Mono", true, false); - gPdfStandardFonts["DejaVuSansMono-Oblique"] = SkPdfStandardFontEntry("DejaVuSans Mono", false, true); - gPdfStandardFonts["Georgia-Bold"] = SkPdfStandardFontEntry("Georgia", true, false); - gPdfStandardFonts["Georgia-BoldItalic"] = SkPdfStandardFontEntry("Georgia", true, true); - gPdfStandardFonts["Georgia-Italic"] = SkPdfStandardFontEntry("Georgia", false, true); - gPdfStandardFonts["TrebuchetMS"] = SkPdfStandardFontEntry("Trebuchet MS", false, false); - gPdfStandardFonts["TrebuchetMS-Bold"] = SkPdfStandardFontEntry("Trebuchet MS", true, false); - gPdfStandardFonts["Verdana-Bold"] = SkPdfStandardFontEntry("Verdana", true, false); - gPdfStandardFonts["WenQuanYiMicroHei"] = SkPdfStandardFontEntry("WenQuanYi Micro Hei", false, false); + gPdfStandardFonts.set("Arial-Black", SkPdfStandardFontEntry("Arial", true, false)); + gPdfStandardFonts.set("DejaVuSans", SkPdfStandardFontEntry("DejaVu Sans", false, false)); + gPdfStandardFonts.set("DejaVuSansMono", SkPdfStandardFontEntry("DejaVuSans Mono", false, false)); + gPdfStandardFonts.set("DejaVuSansMono-Bold", SkPdfStandardFontEntry("DejaVuSans Mono", true, false)); + gPdfStandardFonts.set("DejaVuSansMono-Oblique", SkPdfStandardFontEntry("DejaVuSans Mono", false, true)); + gPdfStandardFonts.set("Georgia-Bold", SkPdfStandardFontEntry("Georgia", true, false)); + gPdfStandardFonts.set("Georgia-BoldItalic", SkPdfStandardFontEntry("Georgia", true, true)); + gPdfStandardFonts.set("Georgia-Italic", SkPdfStandardFontEntry("Georgia", false, true)); + gPdfStandardFonts.set("TrebuchetMS", SkPdfStandardFontEntry("Trebuchet MS", false, false)); + gPdfStandardFonts.set("TrebuchetMS-Bold", SkPdfStandardFontEntry("Trebuchet MS", true, false)); + gPdfStandardFonts.set("Verdana-Bold", SkPdfStandardFontEntry("Verdana", true, false)); + gPdfStandardFonts.set("WenQuanYiMicroHei", SkPdfStandardFontEntry("WenQuanYi Micro Hei", false, false)); // TODO(edisonn): list all phonts available, builf post script name as in pdf spec /* @@ -121,12 +121,12 @@ becomes /MinionMM_366_465_11_. } SkTypeface* SkTypefaceFromPdfStandardFont(const char* fontName, bool bold, bool italic) { - std::map& standardFontMap = getStandardFonts(); + SkTDict& standardFontMap = getStandardFonts(); SkTypeface* typeface = NULL; - if (standardFontMap.find(fontName) != standardFontMap.end()) { - SkPdfStandardFontEntry fontData = standardFontMap[fontName]; + SkPdfStandardFontEntry fontData; + if (standardFontMap.find(fontName, &fontData)) { // TODO(edisonn): How does the bold/italic specified in standard definition combines with // the one in /font key? use OR for now. bold = bold || fontData.fIsBold; @@ -207,7 +207,7 @@ SkPdfFont* fontFromName(SkPdfNativeDoc* doc, SkPdfNativeObject* obj, const char* continue; } - if (fd->has_FontName() && fd->FontName(doc) == fontName) { + if (fd->has_FontName() && fd->FontName(doc).equals(fontName)) { SkPdfFont* font = SkPdfFont::fontFromFontDescriptor(doc, fd, false); if (font) { return font; @@ -432,18 +432,22 @@ SkPdfType0Font::SkPdfType0Font(SkPdfNativeDoc* doc, SkPdfType0FontDictionary* di } } -std::map& getStandardEncodings() { - static std::map encodings; - if (encodings.empty()) { - encodings["Identity-H"] = SkPdfIdentityHEncoding::instance(); +SkTDict& getStandardEncodings() { + static SkTDict encodings(10); + if (encodings.count() == 0) { + encodings.set("Identity-H", SkPdfIdentityHEncoding::instance()); } return encodings; } - SkPdfEncoding* SkPdfEncoding::fromName(const char* name) { - SkPdfEncoding* encoding = getStandardEncodings()[name]; + SkPdfEncoding* encoding = NULL; + if (!getStandardEncodings().find(name, &encoding)) { + // TODO(edisonn): if the function return false, and we a guaranteed that the value is not + // changed, delete this set to null + encoding = NULL; + } #ifdef PDF_TRACE if (encoding == NULL) { diff --git a/experimental/PdfViewer/SkPdfFont.h b/experimental/PdfViewer/SkPdfFont.h index 386aaf5c6f..3c850a63a4 100644 --- a/experimental/PdfViewer/SkPdfFont.h +++ b/experimental/PdfViewer/SkPdfFont.h @@ -4,14 +4,11 @@ #include "SkPdfHeaders_autogen.h" #include "SkPdfMapper_autogen.h" -#include -#include - #include "SkTypeface.h" #include "SkUtils.h" #include "SkPdfGraphicsState.h" #include "SkPdfUtils.h" - +#include "SkTDict.h" class SkPdfType0Font; class SkPdfType1Font; @@ -36,7 +33,7 @@ struct SkPdfStandardFontEntry { fIsItalic(italic) {} }; -std::map& getStandardFonts(); +SkTDict& getStandardFonts(); SkTypeface* SkTypefaceFromPdfStandardFont(const char* fontName, bool bold, bool italic); SkPdfFont* fontFromName(SkPdfNativeDoc* doc, SkPdfNativeObject* obj, const char* fontName); @@ -74,7 +71,7 @@ public: static SkPdfEncoding* fromName(const char* name); }; -std::map& getStandardEncodings(); +SkTDict& getStandardEncodings(); class SkPdfToUnicode { SkPdfNativeDoc* fParsed; diff --git a/experimental/PdfViewer/SkPdfGraphicsState.h b/experimental/PdfViewer/SkPdfGraphicsState.h index d17dc816f7..7ed1fd3c6a 100644 --- a/experimental/PdfViewer/SkPdfGraphicsState.h +++ b/experimental/PdfViewer/SkPdfGraphicsState.h @@ -6,7 +6,7 @@ #include "SkPdfConfig.h" #include "SkPdfUtils.h" -#include +//#include "SkTDStack.h" class SkPdfFont; class SkPdfDoc; @@ -17,6 +17,106 @@ class SkPdfSoftMaskDictionary; class SkPdfNativeDoc; class SkPdfAllocator; +// TODO(edisonn): move this class in iclude/core? +// Ref objects can't be dealt unless we use a specific class initialization +// The difference between SkTDStackNew and SkTDStack is that SkTDStackNew uses new/delete +// to be a manage c++ stuff (like initializations) +#include "SkTypes.h" +template class SkTDStackNew : SkNoncopyable { +public: + SkTDStackNew() : fCount(0), fTotalCount(0) { + fInitialRec.fNext = NULL; + fRec = &fInitialRec; + + // fCount = kSlotCount; + } + + ~SkTDStackNew() { + Rec* rec = fRec; + while (rec != &fInitialRec) { + Rec* next = rec->fNext; + delete rec; + rec = next; + } + } + + int count() const { return fTotalCount; } + int depth() const { return fTotalCount; } + bool empty() const { return fTotalCount == 0; } + + T* push() { + SkASSERT(fCount <= kSlotCount); + if (fCount == kSlotCount) { + Rec* rec = new Rec(); + rec->fNext = fRec; + fRec = rec; + fCount = 0; + } + ++fTotalCount; + return &fRec->fSlots[fCount++]; + } + + void push(const T& elem) { *this->push() = elem; } + + const T& index(int idx) const { + SkASSERT(fRec && fCount > idx); + return fRec->fSlots[fCount - idx - 1]; + } + + T& index(int idx) { + SkASSERT(fRec && fCount > idx); + return fRec->fSlots[fCount - idx - 1]; + } + + const T& top() const { + SkASSERT(fRec && fCount > 0); + return fRec->fSlots[fCount - 1]; + } + + T& top() { + SkASSERT(fRec && fCount > 0); + return fRec->fSlots[fCount - 1]; + } + + void pop(T* elem) { + if (elem) { + *elem = fRec->fSlots[fCount - 1]; + } + this->pop(); + } + + void pop() { + SkASSERT(fCount > 0 && fRec); + --fTotalCount; + if (--fCount == 0) { + if (fRec != &fInitialRec) { + Rec* rec = fRec->fNext; + delete fRec; + fCount = kSlotCount; + fRec = rec; + } else { + SkASSERT(fTotalCount == 0); + } + } + } + +private: + enum { + kSlotCount = 64 + }; + + struct Rec; + friend struct Rec; + + struct Rec { + Rec* fNext; + T fSlots[kSlotCount]; + }; + Rec fInitialRec; + Rec* fRec; + int fCount, fTotalCount; +}; + // TODO(edisonn): better class design. class SkPdfColorOperator { @@ -88,8 +188,6 @@ struct SkPdfGraphicsState { SkPath fPath; bool fPathClosed; - - double fTextLeading; double fWordSpace; double fCharSpace; @@ -361,8 +459,8 @@ smoothness number (PDF 1.3) The precision with which col // TODO(edisonn): rename to SkPdfContext class SkPdfContext { public: - std::stack fObjectStack; - std::stack fStateStack; + SkTDStackNew fObjectStack; + SkTDStackNew fStateStack; SkPdfGraphicsState fGraphicsState; SkPdfNativeDoc* fPdfDoc; // TODO(edisonn): the allocator, could be freed after the page is done drawing. diff --git a/experimental/PdfViewer/SkPdfRenderer.cpp b/experimental/PdfViewer/SkPdfRenderer.cpp index bd95a982ba..ef13c55305 100644 --- a/experimental/PdfViewer/SkPdfRenderer.cpp +++ b/experimental/PdfViewer/SkPdfRenderer.cpp @@ -20,9 +20,6 @@ #include "SkPdfGraphicsState.h" #include "SkPdfNativeTokenizer.h" -#include -#include -#include extern "C" SkPdfContext* gPdfContext; extern "C" SkBitmap* gDumpBitmap; @@ -42,7 +39,7 @@ __SK_FORCE_IMAGE_DECODER_LINKING; // TODO(edisonn): move trace dump in the get functions, and mapper ones too so it ghappens automatically /* #ifdef PDF_TRACE - std::string str; + SkString str; pdfContext->fGraphicsState.fResources->native()->ToString(str); printf("Print Tf Resources: %s\n", str.c_str()); #endif @@ -74,8 +71,6 @@ __SK_FORCE_IMAGE_DECODER_LINKING; * - deal with specific type in spec directly, add all dictionary types to known types */ -using namespace std; - NotOwnedString strings_DeviceRGB; NotOwnedString strings_DeviceCMYK; @@ -414,7 +409,7 @@ static SkColorTable* getGrayColortable() { static SkBitmap* transferImageStreamToBitmap(const unsigned char* uncompressedStream, size_t uncompressedStreamLength, int width, int height, int bytesPerLine, - int bpc, const std::string& colorSpace, + int bpc, const SkString& colorSpace, bool transparencyMask) { SkBitmap* bitmap = new SkBitmap(); @@ -425,7 +420,7 @@ static SkBitmap* transferImageStreamToBitmap(const unsigned char* uncompressedSt // Is there a faster way to load the uncompressed stream into a bitmap? // minimal support for now - if ((colorSpace == "DeviceRGB" || colorSpace == "RGB") && bpc == 8) { + if ((colorSpace.equals("DeviceRGB") || colorSpace.equals("RGB")) && bpc == 8) { SkColor* uncompressedStreamArgb = (SkColor*)malloc(width * height * sizeof(SkColor)); for (int h = 0 ; h < height; h++) { @@ -442,7 +437,7 @@ static SkBitmap* transferImageStreamToBitmap(const unsigned char* uncompressedSt bitmap->setConfig(SkBitmap::kARGB_8888_Config, width, height); bitmap->setPixels(uncompressedStreamArgb); } - else if ((colorSpace == "DeviceGray" || colorSpace == "Gray") && bpc == 8) { + else if ((colorSpace.equals("DeviceGray") || colorSpace.equals("Gray")) && bpc == 8) { unsigned char* uncompressedStreamA8 = (unsigned char*)malloc(width * height); for (int h = 0 ; h < height; h++) { @@ -482,7 +477,7 @@ static SkBitmap* getImageFromObjectCore(SkPdfContext* pdfContext, SkPdfImageDict int bpc = (int)image->BitsPerComponent(pdfContext->fPdfDoc); int width = (int)image->Width(pdfContext->fPdfDoc); int height = (int)image->Height(pdfContext->fPdfDoc); - std::string colorSpace = "DeviceRGB"; + SkString colorSpace("DeviceRGB"); bool indexed = false; SkPMColor colors[256]; @@ -543,11 +538,11 @@ static SkBitmap* getImageFromObjectCore(SkPdfContext* pdfContext, SkPdfImageDict SkPdfStreamCommonDictionary* streamDict = (SkPdfStreamCommonDictionary*)stream; if (streamDict->has_Filter() && ((streamDict->isFilterAName(NULL) && - streamDict->getFilterAsName(NULL) == "DCTDecode") || + streamDict->getFilterAsName(NULL).equals("DCTDecode")) || (streamDict->isFilterAArray(NULL) && streamDict->getFilterAsArray(NULL)->size() > 0 && streamDict->getFilterAsArray(NULL)->objAtAIndex(0)->isName() && - streamDict->getFilterAsArray(NULL)->objAtAIndex(0)->nameValue2() == "DCTDecode"))) { + streamDict->getFilterAsArray(NULL)->objAtAIndex(0)->nameValue2().equals("DCTDecode")))) { SkBitmap* bitmap = new SkBitmap(); SkImageDecoder::DecodeMemory(uncompressedStream, uncompressedStreamLength, bitmap); return bitmap; @@ -877,28 +872,25 @@ SkPdfResult doType3Char(SkPdfContext* pdfContext, SkCanvas* canvas, const SkPdfN return kPartial_SkPdfResult; } - -// TODO(edisonn): make sure the pointer is unique -std::set gInRendering; - class CheckRecursiveRendering { - const SkPdfNativeObject* fUniqueData; + SkPdfNativeObject* fObj; public: - CheckRecursiveRendering(const SkPdfNativeObject* obj) : fUniqueData(obj) { - gInRendering.insert(obj); + CheckRecursiveRendering(SkPdfNativeObject* obj) : fObj(obj) { + SkASSERT(!obj->inRendering()); + obj->startRendering(); } ~CheckRecursiveRendering() { - //SkASSERT(fObj.fInRendering); - gInRendering.erase(fUniqueData); + SkASSERT(fObj->inRendering()); + fObj->doneRendering(); } static bool IsInRendering(const SkPdfNativeObject* obj) { - return gInRendering.find(obj) != gInRendering.end(); + return obj->inRendering(); } }; -static SkPdfResult doXObject(SkPdfContext* pdfContext, SkCanvas* canvas, const SkPdfNativeObject* obj) { +static SkPdfResult doXObject(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfNativeObject* obj) { if (CheckRecursiveRendering::IsInRendering(obj)) { // Oops, corrupt PDF! return kIgnoreError_SkPdfResult; @@ -1869,7 +1861,7 @@ static SkPdfResult skpdfGraphicsStateApplyD(SkPdfContext* pdfContext, SkPdfArray pdfContext->fGraphicsState.fDashPhase = phase->scalarValue(); if (pdfContext->fGraphicsState.fDashPhase == 0) { // other rules, changes? - pdfContext->fGraphicsState.fDashPhase = total; + pdfContext->fGraphicsState.fDashPhase = SkDoubleToScalar(total); } return kOK_SkPdfResult; @@ -1901,13 +1893,15 @@ static SkPdfResult PdfOp_w(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenL //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) { - int64_t lc = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop(); + // TODO(edisonn): round/ceil to int? + int lc = (int)pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop(); return skpdfGraphicsStateApplyLC(pdfContext, 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) { - double lj = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop(); + // TODO(edisonn): round/ceil to int? + int lj = (int)pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjectStack.pop(); return skpdfGraphicsStateApplyLJ(pdfContext, lj); } @@ -1985,8 +1979,8 @@ static SkXfermode::Mode xferModeFromBlendMode(const char* blendMode, size_t len) return (SkXfermode::Mode)(SkXfermode::kLastMode + 1); } -static void skpdfGraphicsStateApplyBM_name(SkPdfContext* pdfContext, const std::string& blendMode) { - SkXfermode::Mode mode = xferModeFromBlendMode(blendMode.c_str(), blendMode.length()); +static void skpdfGraphicsStateApplyBM_name(SkPdfContext* pdfContext, const SkString& blendMode) { + SkXfermode::Mode mode = xferModeFromBlendMode(blendMode.c_str(), blendMode.size()); if (mode <= SkXfermode::kLastMode) { pdfContext->fGraphicsState.fBlendModesLength = 1; pdfContext->fGraphicsState.fBlendModes[0] = mode; @@ -2033,8 +2027,8 @@ static void skpdfGraphicsStateApplySMask_dict(SkPdfContext* pdfContext, SkPdfDic } } -static void skpdfGraphicsStateApplySMask_name(SkPdfContext* pdfContext, const std::string& sMask) { - if (sMask == "None") { +static void skpdfGraphicsStateApplySMask_name(SkPdfContext* pdfContext, const SkString& sMask) { + if (sMask.equals("None")) { pdfContext->fGraphicsState.fSoftMaskDictionary = NULL; pdfContext->fGraphicsState.fSMask = NULL; return; @@ -2074,7 +2068,7 @@ static SkPdfResult PdfOp_gs(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken SkPdfNativeObject* name = pdfContext->fObjectStack.top(); pdfContext->fObjectStack.pop(); #ifdef PDF_TRACE - std::string str; + SkString str; #endif //Next, get the ExtGState Dictionary from the Resource Dictionary: @@ -2406,8 +2400,6 @@ public: InitPdfOps gInitPdfOps; void reportPdfRenderStats() { - std::map::iterator iter; - for (int i = 0 ; i < kCount_SkPdfResult; i++) { SkTDict::Iter iter(gRenderStats[i]); const char* key; diff --git a/experimental/PdfViewer/SkPdfUtils.cpp b/experimental/PdfViewer/SkPdfUtils.cpp index 42cf842e74..e3128f663a 100644 --- a/experimental/PdfViewer/SkPdfUtils.cpp +++ b/experimental/PdfViewer/SkPdfUtils.cpp @@ -1,5 +1,9 @@ #include "SkPdfUtils.h" +bool operator !=(const SkString& first, const char* second) { + return !first.equals(second); +} + #ifdef PDF_TRACE void SkTraceMatrix(const SkMatrix& matrix, const char* sz) { printf("SkMatrix %s ", sz); diff --git a/experimental/PdfViewer/SkPdfUtils.h b/experimental/PdfViewer/SkPdfUtils.h index 31dfc0b95e..11a5d2c4fe 100644 --- a/experimental/PdfViewer/SkPdfUtils.h +++ b/experimental/PdfViewer/SkPdfUtils.h @@ -4,6 +4,7 @@ #include "SkMatrix.h" #include "SkRect.h" #include "SkPdfConfig.h" +#include "SkString.h" class SkPdfArray; class SkPdfContext; @@ -42,6 +43,10 @@ struct NotOwnedString { } }; +// TODO(edisonn): hack to make code generation simpler. Alternatively we can update the +// generate_code.py not to rely on != operator +bool operator !=(const SkString& first, const char* second); + SkMatrix SkMatrixFromPdfArray(SkPdfArray* pdfArray); SkPdfResult doType3Char(SkPdfContext* pdfContext, SkCanvas* canvas, const SkPdfNativeObject* skobj, SkRect bBox, SkMatrix matrix, double textSize); diff --git a/experimental/PdfViewer/generate_code.py b/experimental/PdfViewer/generate_code.py index 66dc41dcab..da8a359a8c 100644 --- a/experimental/PdfViewer/generate_code.py +++ b/experimental/PdfViewer/generate_code.py @@ -21,15 +21,15 @@ knowTypes = { 'function': ['SkPdfFunction', 'ret->functionValue()', datatypes.PdfFunctionNone(), 'ret->isFunction()'], 'integer': ['int64_t', 'ret->intValue()', datatypes.PdfInteger(0), 'ret->isInteger()'], 'file_specification': ['SkPdfFileSpec', 'ret->fileSpecValue()', datatypes.FileSpecNone(), 'false'], -'name': ['std::string', 'ret->nameValue2()', datatypes.PdfString('""'), 'ret->isName()'], +'name': ['SkString', 'ret->nameValue2()', datatypes.PdfString('SkString()'), 'ret->isName()'], #should assert, references should never be allowed here, should be resolved way earlier 'tree': ['SkPdfTree', 'ret->treeValue()', datatypes.EmptyTree(), 'false'], 'number': ['double', 'ret->numberValue()', datatypes.PdfNumber(0), 'ret->isNumber()'], 'rectangle': ['SkRect', 'ret->rectangleValue()', datatypes.EmptyRect(), 'ret->isRectangle()'], 'stream': ['SkPdfStream*', 'ret->getStream()', datatypes.CppNull(), 'ret->hasStream()'], -'string': ['std::string', 'ret->stringValue2()', datatypes.PdfString('""'), 'ret->isAnyString()'], -'text': ['std::string', 'ret->stringValue2()', datatypes.PdfString('""'), 'ret->isAnyString()'], -'text string': ['std::string', 'ret->stringValue2()', datatypes.PdfString('""'), 'ret->isAnyString()'], +'string': ['SkString', 'ret->stringValue2()', datatypes.PdfString('SkString()'), 'ret->isAnyString()'], +'text': ['SkString', 'ret->stringValue2()', datatypes.PdfString('SkString()'), 'ret->isAnyString()'], +'text string': ['SkString', 'ret->stringValue2()', datatypes.PdfString('SkString()'), 'ret->isAnyString()'], 'matrix': ['SkMatrix', 'ret->matrixValue()', datatypes.IdentityMatrix(), 'ret->isMatrix()'], } diff --git a/experimental/PdfViewer/pdfparser/native/SkPdfNativeObject.cpp b/experimental/PdfViewer/pdfparser/native/SkPdfNativeObject.cpp index 4b5f59e401..26f9897f00 100644 --- a/experimental/PdfViewer/pdfparser/native/SkPdfNativeObject.cpp +++ b/experimental/PdfViewer/pdfparser/native/SkPdfNativeObject.cpp @@ -73,7 +73,7 @@ bool SkPdfNativeObject::filterStream() { if (!stream->has_Filter()) { fStr.fBytes = ((fStr.fBytes >> 1) << 1) + kFilteredStreamBit; } else if (stream->isFilterAName(NULL)) { - std::string filterName = stream->getFilterAsName(NULL); + SkString filterName = stream->getFilterAsName(NULL); applyFilter(filterName.c_str()); } else if (stream->isFilterAArray(NULL)) { const SkPdfArray* filters = stream->getFilterAsArray(NULL); diff --git a/experimental/PdfViewer/pdfparser/native/SkPdfNativeObject.h b/experimental/PdfViewer/pdfparser/native/SkPdfNativeObject.h index 1fa627290f..187f2b83fc 100644 --- a/experimental/PdfViewer/pdfparser/native/SkPdfNativeObject.h +++ b/experimental/PdfViewer/pdfparser/native/SkPdfNativeObject.h @@ -3,7 +3,7 @@ #include #include -#include +#include "SkString.h" #include "SkTDArray.h" #include "SkTDict.h" #include "SkRect.h" @@ -59,6 +59,11 @@ class SkPdfNativeObject { }; private: + // TODO(edisonn): assert reset operations while in rendering! + uint32_t fInRendering : 1; + uint32_t fUnused : 31; + + struct Reference { unsigned int fId; unsigned int fGen; @@ -93,8 +98,11 @@ private: public: - SkPdfNativeObject() : fObjectType(kInvalid_PdfObjectType), fMap(NULL), fData(NULL), fDataType(kEmpty_Data) {} + SkPdfNativeObject() : fInRendering(0), fObjectType(kInvalid_PdfObjectType), fMap(NULL), fData(NULL), fDataType(kEmpty_Data) {} + bool inRendering() const { return fInRendering != 0; } + void startRendering() {fInRendering = 1;} + void doneRendering() {fInRendering = 0;} inline bool hasData(DataType type) { return type == fDataType; @@ -722,24 +730,24 @@ public: // TODO(edisonn): nameValue2 and stringValue2 are used to make code generation easy, // but it is not a performat way to do it, since it will create an extra copy // remove these functions and make code generated faster - inline std::string nameValue2() const { + inline SkString nameValue2() const { SkASSERT(fObjectType == kName_PdfObjectType); if (fObjectType != kName_PdfObjectType) { // TODO(edisonn): log err - return ""; + return SkString(); } - return std::string((const char*)fStr.fBuffer, fStr.fBytes); + return SkString((const char*)fStr.fBuffer, fStr.fBytes); } - inline std::string stringValue2() const { + inline SkString stringValue2() const { SkASSERT(fObjectType == kString_PdfObjectType || fObjectType == kHexString_PdfObjectType); if (fObjectType != kString_PdfObjectType && fObjectType != kHexString_PdfObjectType) { // TODO(edisonn): log err - return ""; + return SkString(); } - return std::string((const char*)fStr.fBuffer, fStr.fBytes); + return SkString((const char*)fStr.fBuffer, fStr.fBytes); } inline bool boolValue() const { -- cgit v1.2.3