aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--gyp/pdf.gyp2
-rw-r--r--gyp/tests.gyp1
-rwxr-xr-xinclude/pdf/SkBitSet.h65
-rwxr-xr-xsrc/pdf/SkBitSet.cpp91
-rw-r--r--tests/BitSetTest.cpp66
5 files changed, 225 insertions, 0 deletions
diff --git a/gyp/pdf.gyp b/gyp/pdf.gyp
index 3957e481d6..f0c39372ab 100644
--- a/gyp/pdf.gyp
+++ b/gyp/pdf.gyp
@@ -13,6 +13,7 @@
'../src/core', # needed to get SkGlyphCache.h and SkTextFormatParams.h
],
'sources': [
+ '../include/pdf/SkBitSet.h',
'../include/pdf/SkPDFCatalog.h',
'../include/pdf/SkPDFDevice.h',
'../include/pdf/SkPDFDocument.h',
@@ -26,6 +27,7 @@
'../include/pdf/SkPDFTypes.h',
'../include/pdf/SkPDFUtils.h',
+ '../src/pdf/SkBitSet.cpp',
'../src/pdf/SkPDFCatalog.cpp',
'../src/pdf/SkPDFDevice.cpp',
'../src/pdf/SkPDFDocument.cpp',
diff --git a/gyp/tests.gyp b/gyp/tests.gyp
index d4cafd2548..95dc9c585b 100644
--- a/gyp/tests.gyp
+++ b/gyp/tests.gyp
@@ -14,6 +14,7 @@
'sources': [
'../tests/BitmapCopyTest.cpp',
'../tests/BitmapGetColorTest.cpp',
+ '../tests/BitSetTest.cpp',
'../tests/BlitRowTest.cpp',
'../tests/ClampRangeTest.cpp',
'../tests/ClipCubicTest.cpp',
diff --git a/include/pdf/SkBitSet.h b/include/pdf/SkBitSet.h
new file mode 100755
index 0000000000..84d52e547c
--- /dev/null
+++ b/include/pdf/SkBitSet.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 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 SkBitSet_DEFINED
+#define SkBitSet_DEFINED
+
+#include "SkTypes.h"
+
+class SkBitSet {
+public:
+ /** NumberOfBits must be greater than zero.
+ */
+ explicit SkBitSet(int numberOfBits);
+ explicit SkBitSet(const SkBitSet& source);
+
+ const SkBitSet& operator=(const SkBitSet& rhs);
+ bool operator==(const SkBitSet& rhs);
+ bool operator!=(const SkBitSet& rhs);
+
+ /** Clear all data.
+ */
+ void clearAll();
+
+ /** Set the value of the index-th bit.
+ */
+ void setBit(int index, bool value);
+
+ /** Test if bit index is set.
+ */
+ bool isBitSet(int index);
+
+ /** Or bits from source. false is returned if this doesn't have the same
+ * bit count as source.
+ */
+ bool orBits(SkBitSet& source);
+
+private:
+ SkAutoFree fBitData;
+ // Dword (32-bit) count of the bitset.
+ size_t fDwordCount;
+ size_t fBitCount;
+
+ uint32_t* internalGet(int index) {
+ SkASSERT((size_t)index < fBitCount);
+ size_t internalIndex = index / 32;
+ SkASSERT(internalIndex < fDwordCount);
+ return (uint32_t*)fBitData.get() + internalIndex;
+ }
+};
+
+
+#endif
diff --git a/src/pdf/SkBitSet.cpp b/src/pdf/SkBitSet.cpp
new file mode 100755
index 0000000000..f19dd69a51
--- /dev/null
+++ b/src/pdf/SkBitSet.cpp
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 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.
+ */
+
+#include <string.h>
+#include "SkBitSet.h"
+
+SkBitSet::SkBitSet(int numberOfBits)
+ : fBitData(NULL), fDwordCount(0), fBitCount(numberOfBits) {
+ SkASSERT(numberOfBits > 0);
+ // Round up size to 32-bit boundary.
+ fDwordCount = (numberOfBits + 31) / 32;
+ fBitData.set(malloc(fDwordCount * sizeof(uint32_t)));
+ clearAll();
+}
+
+SkBitSet::SkBitSet(const SkBitSet& source)
+ : fBitData(NULL), fDwordCount(0), fBitCount(0) {
+ *this = source;
+}
+
+const SkBitSet& SkBitSet::operator=(const SkBitSet& rhs) {
+ if (this == (SkBitSet*)&rhs) {
+ return *this;
+ }
+ fBitCount = rhs.fBitCount;
+ fBitData.free();
+ fDwordCount = rhs.fDwordCount;
+ fBitData.set(malloc(fDwordCount * sizeof(uint32_t)));
+ memcpy(fBitData.get(), rhs.fBitData.get(), fDwordCount * sizeof(uint32_t));
+ return *this;
+}
+
+bool SkBitSet::operator==(const SkBitSet& rhs) {
+ if (fBitCount == rhs.fBitCount) {
+ if (fBitData.get() != NULL) {
+ return (memcmp(fBitData.get(), rhs.fBitData.get(),
+ fDwordCount * sizeof(uint32_t)) == 0);
+ }
+ return true;
+ }
+ return false;
+}
+
+bool SkBitSet::operator!=(const SkBitSet& rhs) {
+ return !(*this == rhs);
+}
+
+void SkBitSet::clearAll() {
+ if (fBitData.get() != NULL) {
+ sk_bzero(fBitData.get(), fDwordCount * sizeof(uint32_t));
+ }
+}
+
+void SkBitSet::setBit(int index, bool value) {
+ uint32_t mask = 1 << (index % 32);
+ if (value) {
+ *(internalGet(index)) |= mask;
+ } else {
+ *(internalGet(index)) &= ~mask;
+ }
+}
+
+bool SkBitSet::isBitSet(int index) {
+ uint32_t mask = 1 << (index % 32);
+ return (*internalGet(index) & mask);
+}
+
+bool SkBitSet::orBits(SkBitSet& source) {
+ if (fBitCount != source.fBitCount) {
+ return false;
+ }
+ uint32_t* targetBitmap = internalGet(0);
+ uint32_t* sourceBitmap = source.internalGet(0);
+ for (size_t i = 0; i < fDwordCount; ++i) {
+ targetBitmap[i] |= sourceBitmap[i];
+ }
+ return true;
+}
diff --git a/tests/BitSetTest.cpp b/tests/BitSetTest.cpp
new file mode 100644
index 0000000000..96bf80f9b1
--- /dev/null
+++ b/tests/BitSetTest.cpp
@@ -0,0 +1,66 @@
+#include "Test.h"
+#include "SkBitSet.h"
+
+static void TestBitSet(skiatest::Reporter* reporter) {
+ SkBitSet set0(65536);
+ REPORTER_ASSERT(reporter, set0.isBitSet(0) == false);
+ REPORTER_ASSERT(reporter, set0.isBitSet(32767) == false);
+ REPORTER_ASSERT(reporter, set0.isBitSet(65535) == false);
+
+ SkBitSet set1(65536);
+ REPORTER_ASSERT(reporter, set0 == set1);
+
+ set0.setBit(22, true);
+ REPORTER_ASSERT(reporter, set0.isBitSet(22) == true);
+ set0.setBit(24, true);
+ REPORTER_ASSERT(reporter, set0.isBitSet(24) == true);
+ set0.setBit(35, true); // on a different DWORD
+ REPORTER_ASSERT(reporter, set0.isBitSet(35) == true);
+ set0.setBit(22, false);
+ REPORTER_ASSERT(reporter, set0.isBitSet(22) == false);
+ REPORTER_ASSERT(reporter, set0.isBitSet(24) == true);
+ REPORTER_ASSERT(reporter, set0.isBitSet(35) == true);
+
+ set1.setBit(12345, true);
+ set1.orBits(set0);
+ REPORTER_ASSERT(reporter, set0.isBitSet(12345) == false);
+ REPORTER_ASSERT(reporter, set1.isBitSet(12345) == true);
+ REPORTER_ASSERT(reporter, set1.isBitSet(22) == false);
+ REPORTER_ASSERT(reporter, set1.isBitSet(24) == true);
+ REPORTER_ASSERT(reporter, set0.isBitSet(35) == true);
+ REPORTER_ASSERT(reporter, set1 != set0);
+
+ set1.clearAll();
+ REPORTER_ASSERT(reporter, set0.isBitSet(12345) == false);
+ REPORTER_ASSERT(reporter, set1.isBitSet(12345) == false);
+ REPORTER_ASSERT(reporter, set1.isBitSet(22) == false);
+ REPORTER_ASSERT(reporter, set1.isBitSet(24) == false);
+ REPORTER_ASSERT(reporter, set1.isBitSet(35) == false);
+
+ set1.orBits(set0);
+ REPORTER_ASSERT(reporter, set1 == set0);
+
+ SkBitSet set2(1);
+ SkBitSet set3(1);
+ SkBitSet set4(4);
+ SkBitSet set5(33);
+
+ REPORTER_ASSERT(reporter, set2 == set3);
+ REPORTER_ASSERT(reporter, set2 != set4);
+ REPORTER_ASSERT(reporter, set2 != set5);
+
+ set2.setBit(0, true);
+ REPORTER_ASSERT(reporter, set2 != set5);
+ set5.setBit(0, true);
+ REPORTER_ASSERT(reporter, set2 != set5);
+ REPORTER_ASSERT(reporter, set2 != set3);
+ set3.setBit(0, true);
+ REPORTER_ASSERT(reporter, set2 == set3);
+ set3.clearAll();
+ set3 = set2;
+ set2 = set2;
+ REPORTER_ASSERT(reporter, set2 == set3);
+}
+
+#include "TestClassDef.h"
+DEFINE_TESTCLASS("BitSet", BitSetTest, TestBitSet)