Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/drape
diff options
context:
space:
mode:
authorExMix <rahuba.youri@mapswithme.com>2014-08-12 16:53:08 +0400
committerAlex Zolotarev <alex@maps.me>2015-09-23 02:24:46 +0300
commit3f76c76d045438a5024a347bf80de2b51fddb9e6 (patch)
treef28803009b5d48293dd37baa1a029e19b992cd91 /drape
parentbe0d98779a2e343e83e570d04798f9b34fa865fc (diff)
[drape] stipple pen dynamic resource and tests
Diffstat (limited to 'drape')
-rw-r--r--drape/drape_common.pri2
-rw-r--r--drape/drape_tests/drape_tests.pro1
-rw-r--r--drape/drape_tests/stipple_pen_tests.cpp82
-rw-r--r--drape/stipple_pen_resource.cpp91
-rw-r--r--drape/stipple_pen_resource.hpp49
5 files changed, 225 insertions, 0 deletions
diff --git a/drape/drape_common.pri b/drape/drape_common.pri
index 3b1d585d09..3f150243c9 100644
--- a/drape/drape_common.pri
+++ b/drape/drape_common.pri
@@ -35,6 +35,7 @@ SOURCES += \
$$DRAPE_DIR/texture_set_holder.cpp \
$$DRAPE_DIR/utils/stb_image.c \
$$DRAPE_DIR/attribute_buffer_mutator.cpp \
+ $$DRAPE_DIR/stipple_pen_resource.cpp
HEADERS += \
$$DRAPE_DIR/data_buffer.hpp \
@@ -76,3 +77,4 @@ HEADERS += \
$$DRAPE_DIR/attribute_buffer_mutator.hpp \
$$DRAPE_DIR/drape_global.hpp \
$$DRAPE_DIR/object_pool.hpp \
+ $$DRAPE_DIR/stipple_pen_resource.hpp
diff --git a/drape/drape_tests/drape_tests.pro b/drape/drape_tests/drape_tests.pro
index 5d5e0c8f02..26e1b79da2 100644
--- a/drape/drape_tests/drape_tests.pro
+++ b/drape/drape_tests/drape_tests.pro
@@ -39,6 +39,7 @@ SOURCES += \
pointers_tests.cpp \
font_texture_tests.cpp \
bingind_info_tests.cpp \
+ stipple_pen_tests.cpp
HEADERS += \
glmock_functions.hpp \
diff --git a/drape/drape_tests/stipple_pen_tests.cpp b/drape/drape_tests/stipple_pen_tests.cpp
new file mode 100644
index 0000000000..53d2fa2bab
--- /dev/null
+++ b/drape/drape_tests/stipple_pen_tests.cpp
@@ -0,0 +1,82 @@
+#include "../../testing/testing.hpp"
+
+#include "../stipple_pen_resource.hpp"
+
+using namespace dp;
+
+namespace
+{
+ void TestPacker(StipplePenPacker & packer, uint32_t width, m2::RectU const & expect)
+ {
+ m2::RectU rect = packer.PackResource(width);
+ TEST_EQUAL(rect, expect, ());
+ }
+}
+
+UNIT_TEST(SimpleStipplePackTest)
+{
+ StipplePenPacker packer(m2::PointU(1024, 8));
+ TestPacker(packer, 30, m2::RectU(1, 1, 31, 2));
+ TestPacker(packer, 254, m2::RectU(1, 3, 255, 4));
+ TestPacker(packer, 1, m2::RectU(1, 5, 2, 6));
+ TestPacker(packer, 250, m2::RectU(256, 1, 506, 2));
+ TestPacker(packer, 249, m2::RectU(256, 3, 505, 4));
+}
+
+UNIT_TEST(SimpleStippleTest)
+{
+ StipplePenKey key;
+ TEST_EQUAL(key.Tag, StipplePenTag, ());
+ key.m_pattern.push_back(12);
+ key.m_pattern.push_back(12);
+ key.m_pattern.push_back(8);
+ key.m_pattern.push_back(9);
+
+ StipplePenResource res(key);
+ TEST_EQUAL(res.GetSize(), 246, ());
+ TEST_EQUAL(res.GetBufferSize(), 246, ());
+
+ uint8_t buffer[250];
+ memset(buffer, 127, ARRAY_SIZE(buffer) * sizeof(uint8_t));
+ res.Rasterize(buffer + 2);
+
+ typedef pair<size_t, size_t> TRange;
+ typedef pair<TRange, uint8_t> TCheckNode;
+
+ TCheckNode nodes[38] =
+ {
+ make_pair(make_pair(0, 2), 127),
+ make_pair(make_pair(2, 14), 255),
+ make_pair(make_pair(14, 26), 0),
+ make_pair(make_pair(26, 34), 255),
+ make_pair(make_pair(34, 43), 0),
+ make_pair(make_pair(43, 55), 255),
+ make_pair(make_pair(55, 67), 0),
+ make_pair(make_pair(67, 75), 255),
+ make_pair(make_pair(75, 84), 0),
+ make_pair(make_pair(84, 96), 255),
+ make_pair(make_pair(96, 108), 0),
+ make_pair(make_pair(108, 116), 255),
+ make_pair(make_pair(116, 125), 0),
+ make_pair(make_pair(125, 137), 255),
+ make_pair(make_pair(137, 149), 0),
+ make_pair(make_pair(149, 157), 255),
+ make_pair(make_pair(157, 166), 0),
+ make_pair(make_pair(166, 178), 255),
+ make_pair(make_pair(178, 190), 0),
+ make_pair(make_pair(190, 198), 255),
+ make_pair(make_pair(198, 207), 0),
+ make_pair(make_pair(207, 219), 255),
+ make_pair(make_pair(219, 231), 0),
+ make_pair(make_pair(231, 239), 255),
+ make_pair(make_pair(239, 248), 0),
+ make_pair(make_pair(248, 250), 127),
+ };
+
+ for (size_t i = 0; i < ARRAY_SIZE(nodes); ++i)
+ {
+ TCheckNode const & node = nodes[i];
+ for (size_t r = node.first.first; r < node.first.second; ++r)
+ TEST_EQUAL(buffer[r], node.second, (r));
+ }
+}
diff --git a/drape/stipple_pen_resource.cpp b/drape/stipple_pen_resource.cpp
new file mode 100644
index 0000000000..266076901d
--- /dev/null
+++ b/drape/stipple_pen_resource.cpp
@@ -0,0 +1,91 @@
+#include "stipple_pen_resource.hpp"
+
+#include "../std/numeric.hpp"
+
+namespace dp
+{
+
+uint32_t const MAX_STIPPLE_PEN_LENGTH = 254;
+uint32_t const COLUMN_WIDTH = MAX_STIPPLE_PEN_LENGTH + 1;
+
+StipplePenPacker::StipplePenPacker(m2::PointU const & canvasSize)
+ : m_canvasSize(canvasSize)
+ , m_currentColumn(0)
+{
+ // canvasSize.x - 1 = we reserve 1 pixel border on left
+ // to reduce problems with bilinear filtration on GPU
+ // MAX_STIPPLE_PEN_LENGTH + 1 = we reserve 1 pixel empty space after pen resource
+ // pen in last column reserve 1 pixel on right size of canvas
+ uint32_t columnCount = floor((canvasSize.x - 1) / MAX_STIPPLE_PEN_LENGTH);
+ m_columns.resize(columnCount, 0);
+}
+
+m2::RectU StipplePenPacker::PackResource(uint32_t width)
+{
+ ASSERT(m_currentColumn < m_columns.size(), ());
+ uint32_t countInColumn = m_columns[m_currentColumn];
+ // on one pattern we reserve 2 pixels. 1 pixel for pattern
+ // and 1 pixel for empty space beetween patterns
+ // also we reserve 1 pixel border on top of canvas
+ uint32_t yOffset = countInColumn * 2 + 1;
+ // ASSERT that ne pattern can be packed in current column
+ ASSERT(yOffset + 2 < m_canvasSize.y, ());
+ ++m_columns[m_currentColumn];
+ // 1 + m_currentColumn = reserve 1 pixel border on left side
+ uint32_t xOffset = 1 + m_currentColumn * COLUMN_WIDTH;
+ // we check if new pattern can be mapped in this column
+ // yOffset + 4 = 2 pixels on current pattern and 2 for new pattern
+ if (yOffset + 4 > m_canvasSize.y)
+ m_currentColumn++;
+
+ // maxY = yOffset + 1 because real height of stipple pattern is 1
+ return m2::RectU(xOffset, yOffset, xOffset + width, yOffset + 1);
+}
+
+StipplePenResource::StipplePenResource(StipplePenKey const & key)
+ : m_key(key)
+{
+ uint32_t fullPattern = accumulate(m_key.m_pattern.begin(), m_key.m_pattern.end(), 0);
+ ASSERT(fullPattern < MAX_STIPPLE_PEN_LENGTH, ());
+ uint32_t count = floor(MAX_STIPPLE_PEN_LENGTH / fullPattern);
+ m_pixelLength = count * fullPattern;
+}
+
+uint32_t StipplePenResource::GetSize() const
+{
+ return m_pixelLength;
+}
+
+uint32_t StipplePenResource::GetBufferSize() const
+{
+ return m_pixelLength;
+}
+
+TextureFormat StipplePenResource::GetExpectedFormat() const
+{
+ return ALPHA;
+}
+
+void StipplePenResource::Rasterize(void * buffer)
+{
+ uint8_t * pixels = static_cast<uint8_t *>(buffer);
+ uint16_t offset = 0;
+ for (size_t i = 0; i < m_key.m_pattern.size(); ++i)
+ {
+ uint8_t value = (i & 0x1) == 0 ? 255 : 0;
+ uint8_t length = m_key.m_pattern[i];
+ memset(pixels + offset, value, length * sizeof(uint8_t));
+ offset += length;
+ }
+
+ uint8_t period = offset;
+
+ while (offset < m_pixelLength)
+ {
+ memcpy(pixels + offset, pixels, period);
+ offset += period;
+ }
+}
+
+}
+
diff --git a/drape/stipple_pen_resource.hpp b/drape/stipple_pen_resource.hpp
new file mode 100644
index 0000000000..e1be5045f3
--- /dev/null
+++ b/drape/stipple_pen_resource.hpp
@@ -0,0 +1,49 @@
+#pragma once
+
+#include "drape_global.hpp"
+
+#include "../base/buffer_vector.hpp"
+
+#include "../geometry/point2d.hpp"
+#include "../geometry/rect2d.hpp"
+
+namespace dp
+{
+
+class StipplePenPacker
+{
+public:
+ StipplePenPacker(m2::PointU const & canvasSize);
+
+ m2::RectU PackResource(uint32_t width);
+
+private:
+ m2::PointU m_canvasSize;
+ buffer_vector<uint32_t, 4> m_columns;
+ uint32_t m_currentColumn;
+};
+
+struct StipplePenKey
+{
+ enum { Tag = StipplePenTag };
+
+ buffer_vector<uint8_t, 8> m_pattern;
+};
+
+class StipplePenResource
+{
+public:
+ StipplePenResource(StipplePenKey const & key);
+
+ uint32_t GetSize() const;
+ uint32_t GetBufferSize() const;
+ TextureFormat GetExpectedFormat() const;
+
+ void Rasterize(void * buffer);
+
+private:
+ StipplePenKey m_key;
+ uint32_t m_pixelLength;
+};
+
+}