--- /dev/null
+/*
+ Copyright 2011 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef SkTLazy_DEFINED
+#define SkTLazy_DEFINED
+
+#include "SkTypes.h"
+
+/**
+ * Efficient way to defer allocating/initializing a class until it is needed
+ * (if ever).
+ */
+template <typename T> class SkTLazy {
+public:
+ SkTLazy() : fPtr(NULL) {}
+
+ explicit SkTLazy(const T* src) : fPtr(NULL) {
+ if (src) {
+ fPtr = new (fStorage) T(*src);
+ }
+ }
+
+ SkTLazy(const SkTLazy<T>& src) : fPtr(NULL) {
+ const T* ptr = src.get();
+ if (ptr) {
+ fPtr = new (fStorage) T(*ptr);
+ }
+ }
+
+ ~SkTLazy() {
+ if (fPtr) {
+ fPtr->~T();
+ }
+ }
+
+ /**
+ * Copy src into this, and return a pointer to a copy of it. Note this
+ * will always return the same pointer, so if it is called on a lazy that
+ * has already been initialized, then this will copy over the previous
+ * contents.
+ */
+ T* set(const T& src) {
+ if (fPtr) {
+ *fPtr = src;
+ } else {
+ fPtr = new (fStorage) T(src);
+ }
+ return fPtr;
+ }
+
+ /**
+ * Returns either NULL, or a copy of the object that was passed to
+ * set() or the constructor.
+ */
+ T* get() const { return fPtr; }
+
+private:
+ T* fPtr; // NULL or fStorage
+ char fStorage[sizeof(T)];
+};
+
+#endif
+
#include "SkScalarCompare.h"
#include "SkShape.h"
#include "SkTemplates.h"
+#include "SkTLazy.h"
#include "SkUtils.h"
#include <new>
SkDeviceFilteredPaint(SkDevice* device, const SkPaint& paint) {
SkDevice::TextFlags flags;
if (device->filterTextFlags(paint, &flags)) {
- SkPaint* newPaint = new (fStorage) SkPaint(paint);
+ SkPaint* newPaint = fLazy.set(paint);
newPaint->setFlags(flags.fFlags);
newPaint->setHinting(flags.fHinting);
fPaint = newPaint;
}
}
- ~SkDeviceFilteredPaint() {
- if (reinterpret_cast<SkPaint*>(fStorage) == fPaint) {
- fPaint->~SkPaint();
- }
- }
-
const SkPaint& paint() const { return *fPaint; }
private:
- // points to either fStorage or the caller's paint
- const SkPaint* fPaint;
- // we rely on the fPaint above to ensure proper alignment of fStorage
- char fStorage[sizeof(SkPaint)];
+ const SkPaint* fPaint;
+ SkTLazy<SkPaint> fLazy;
};
void SkCanvas::drawText(const void* text, size_t byteLength,