Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(31)

Unified Diff: experimental/PdfViewer/src/SkTDStackNester.h

Issue 68843006: Changes to SkTDStackNester. (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « experimental/PdfViewer/src/SkPdfRenderer.cpp ('k') | gyp/experimental.gyp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: experimental/PdfViewer/src/SkTDStackNester.h
diff --git a/experimental/PdfViewer/src/SkTDStackNester.h b/experimental/PdfViewer/src/SkTDStackNester.h
index 4910ad1a3d9e201108a18099e6c9258b781ccc43..dd936baaeddaacd59df94852bf6987705a9d6516 100644
--- a/experimental/PdfViewer/src/SkTDStackNester.h
+++ b/experimental/PdfViewer/src/SkTDStackNester.h
@@ -9,25 +9,34 @@
#define SkTDStackNester_DEFINED
#include "SkTypes.h"
+#include "SkPdfReporter.h"
-// Adobe limits it to 28, so 256 should be more than enough
+// Adobe limits it to 28. Allow deeper nesting in case a file does not quite meet the
+// spec. 256 should be more than enough.
#define MAX_NESTING 256
/** \class SkTDStackNester
*
+ * Specialized version of SkTDStack which allows a stack of stacks.
+ * FIXME (scroggo): Could this be a subclass of SkTDStack? Could it have-a SkTDStack?
* The difference between SkTDStackNester and SkTDStack is that:
* - SkTDStackNester uses new/delete to manage initializations
+ * FIXME (scroggo): Why use new rather than malloc?
* - Supports nest/unnest which simulates a stack of stack. unnest will pop all the
* objects pushed since the last nest
+ * - kSlotCount is 64, instead of 8.
+ * FIXME (scroggo): How did we arrive at this number?
*/
template <typename T> class SkTDStackNester : SkNoncopyable {
public:
- SkTDStackNester() : fCount(0), fTotalCount(0), fLocalCount(0) {
+ SkTDStackNester()
+ : fCount(0)
+ , fLocalCount(0)
+ , fNestingLevel(0) {
fInitialRec.fNext = NULL;
fRec = &fInitialRec;
-
- // fCount = kSlotCount;
+ SkDEBUGCODE(fTotalCount = 0;)
}
~SkTDStackNester() {
@@ -39,36 +48,73 @@ public:
}
}
+ /**
+ * Return the number of objects in the current nesting level.
+ */
int count() const { return fLocalCount; }
+
+ /**
+ * Whether the current nesting level is empty.
+ */
bool empty() const { return fLocalCount == 0; }
- int nests() {
+ /**
+ * The current nesting level.
+ */
+ int nestingLevel() const {
return fNestingLevel;
}
+ /**
+ * Analogous to an SkCanvas::save(). When unnest() is called, the state of this SkTDStackNester
+ * will return to its state when nest() was called.
+ *
+ * After a call to nest(), fLocalCount is reset to 0, since the stack is on a new nesting
+ * level.
+ */
void nest() {
- // We are are past max nesting levels, we will still continue to work, but we might fail
- // to properly ignore errors. Ideally it should only mean poor rendering in exceptional
- // cases
- if (fNestingLevel >= 0 && fNestingLevel < MAX_NESTING) {
+ SkASSERT(fNestingLevel >= 0);
+ if (fNestingLevel < MAX_NESTING) {
fNestings[fNestingLevel] = fLocalCount;
fLocalCount = 0;
+ } else {
+ // We are are past max nesting levels. We will still continue to work, but we might fail
+ // to properly ignore errors. Ideally it should only mean poor rendering in exceptional
+ // cases.
+ SkPdfReport(kWarning_SkPdfIssueSeverity, kStackNestingOverflow_SkPdfIssue,
+ "Past maximum nesting level", NULL, NULL);
}
fNestingLevel++;
}
+ /**
+ * Analagous to an SkCanvas::restore(). Will revert this stack to the state it was in the last
+ * time nest() was called. It is an error to call unnest() more times than nest() has been
+ * called.
+ */
void unnest() {
- SkASSERT(fNestingLevel > 0);
+ SkASSERT(fNestingLevel >= 0);
+ if (0 == fNestingLevel) {
+ SkPdfReport(kWarning_SkPdfIssueSeverity, kStackNestingOverflow_SkPdfIssue,
+ "Nesting underflow", NULL, NULL);
+ return;
+ }
+
fNestingLevel--;
- if (fNestingLevel >= 0 && fNestingLevel < MAX_NESTING) {
- // TODO(edisonn): warn if fLocal > 0
+ if (fNestingLevel < MAX_NESTING) {
while (fLocalCount > 0) {
- pop();
+ // FIXME (scroggo): Pass the object?
+ SkPdfReport(kInfo_SkPdfIssueSeverity, kUnusedObject_SkPdfIssue,
+ "Unused object when calling unnest!", NULL, NULL);
+ this->pop();
}
fLocalCount = fNestings[fNestingLevel];
}
}
+ /**
+ * Add an object to the stack, and return a pointer to it for modification.
+ */
T* push() {
SkASSERT(fCount <= kSlotCount);
if (fCount == kSlotCount) {
@@ -77,33 +123,35 @@ public:
fRec = rec;
fCount = 0;
}
- ++fTotalCount;
+ SkDEBUGCODE(++fTotalCount;)
++fLocalCount;
return &fRec->fSlots[fCount++];
}
+ /**
+ * Add an object to the stack, copied from elem.
+ */
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];
- }
-
+ /**
+ * Return the top element.
+ */
const T& top() const {
SkASSERT(fRec && fCount > 0);
return fRec->fSlots[fCount - 1];
}
+ /**
+ * Return the top element.
+ */
T& top() {
SkASSERT(fRec && fCount > 0);
return fRec->fSlots[fCount - 1];
}
+ /**
+ * Pop an object off the stack (via pop()), and copy its members into elem.
+ */
void pop(T* elem) {
if (elem) {
*elem = fRec->fSlots[fCount - 1];
@@ -111,10 +159,15 @@ public:
this->pop();
}
+ /**
+ * Pop an object off the stack. It is an error to call pop() more times
+ * than push() has been called in total or since the last call to nest().
+ */
void pop() {
SkASSERT(fCount > 0 && fRec);
+ SkASSERT(fLocalCount > 0);
--fLocalCount;
- --fTotalCount;
+ SkDEBUGCODE(--fTotalCount;)
if (--fCount == 0) {
if (fRec != &fInitialRec) {
Rec* rec = fRec->fNext;
@@ -129,20 +182,33 @@ public:
private:
enum {
+ // Number of objects held per Rec. Storing multiple objects in one Rec
+ // means that we call new less often.
kSlotCount = 64
};
- struct Rec;
- friend struct Rec;
-
struct Rec {
Rec* fNext;
T fSlots[kSlotCount];
};
+
+ // First Rec, requiring no allocation.
Rec fInitialRec;
+ // The Rec on top of the stack.
Rec* fRec;
- int fCount, fTotalCount, fLocalCount;
+ // Number of objects in fRec.
+ int fCount;
+ // Number of objects in the current nesting level.
+ int fLocalCount;
+ // Array of counts of objects per nesting level.
+ // Only valid for fNestings[0] through fNestings[fNestingLevel-1].
int fNestings[MAX_NESTING];
+ // Current nesting level.
int fNestingLevel;
+ // Total number of objects in this SkTDStackNester.
+ SkDEBUGCODE(int fTotalCount;)
+
+ // For testing.
+ friend class SkTDStackNesterTester;
};
#endif // SkTDStackNester_DEFINED
« no previous file with comments | « experimental/PdfViewer/src/SkPdfRenderer.cpp ('k') | gyp/experimental.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698