correct handling of pathOffset and penInfo.m_offset parameters in drawPath() function.

This commit is contained in:
rachytski 2011-05-01 21:50:43 +03:00 committed by Alex Zolotarev
parent c113fe9b32
commit 8fa6b56fff
11 changed files with 137 additions and 66 deletions

View file

@ -58,7 +58,7 @@ namespace
std::vector<m2::PointD> pts;
for (size_t j = 0; j < m_lines[i].size(); ++j)
pts.push_back(m_screenBase.GtoP(m2::PointD(m_lines[i][j].first, m_lines[i][j].second)));
pScreen->drawPath(&pts[0], pts.size(), m_skin->mapPenInfo(yg::PenInfo(yg::Color(0, 255, 0, 255), 2, 0, 0, 0)), 0);
pScreen->drawPath(&pts[0], pts.size(), 0, m_skin->mapPenInfo(yg::PenInfo(yg::Color(0, 255, 0, 255), 2, 0, 0, 0)), 0);
}
}

View file

@ -187,7 +187,7 @@ void DrawerYG::drawPath(vector<m2::PointD> const & pts, di::DrawRule const * rul
// draw path with array of rules
for (size_t i = 0; i < count; ++i)
m_pScreen->drawPath(&pts[0], pts.size(), rules[i].m_rule->GetID(), rules[i].m_depth);
m_pScreen->drawPath(&pts[0], pts.size(), 0, rules[i].m_rule->GetID(), rules[i].m_depth);
}
void DrawerYG::drawArea(vector<m2::PointD> const & pts, rule_ptr_t pRule, int depth)

View file

@ -152,7 +152,7 @@ void InformationDisplay::drawRuler(DrawerYG * pDrawer)
scalerPts[3] = scalerPts[2] + m2::PointD(0, -14 * m_visualScale);
pDrawer->screen()->drawPath(
scalerPts, 4,
scalerPts, 4, 0,
pDrawer->screen()->skin()->mapPenInfo(yg::PenInfo(yg::Color(0, 0, 0, 255), 2, 0, 0, 0)),
yg::maxDepth);
@ -174,7 +174,7 @@ void InformationDisplay::drawRuler(DrawerYG * pDrawer)
minPixPath[3] = minPixPath[2] + m2::PointD(0, -14);
pDrawer->screen()->drawPath(
minPixPath, 4,
minPixPath, 4, 0,
pDrawer->screen()->skin()->mapPenInfo(yg::PenInfo(yg::Color(255, 0, 0, 255), 4, 0, 0, 0)),
yg::maxDepth);
*/

View file

@ -17,7 +17,7 @@ namespace yg
: base_t(params), m_drawPathes(params.m_drawPathes)
{}
void PathRenderer::drawPath(m2::PointD const * points, size_t pointsCount, uint32_t styleID, double depth)
void PathRenderer::drawPath(m2::PointD const * points, size_t pointsCount, double offset, uint32_t styleID, double depth)
{
++m_pathCount;
m_pointsCount += pointsCount;
@ -25,14 +25,6 @@ namespace yg
if (!m_drawPathes)
return;
#ifdef PROFILER_YG
prof::block<prof::yg_draw_path> draw_path_block;
#endif
//#ifdef DEBUG_DRAW_PATH
// LineStyle const * lineStyle = reinterpret_cast<LineStyle const*>(styleID);
//#else
ASSERT_GREATER_OR_EQUAL(pointsCount, 2, ());
ResourceStyle const * style(skin()->fromID(styleID));
@ -44,7 +36,6 @@ namespace yg
ASSERT(style->m_cat == ResourceStyle::ELineStyle, ());
LineStyle const * lineStyle = static_cast<LineStyle const *>(style);
//#endif
if (lineStyle->m_isSolid)
{
@ -54,6 +45,8 @@ namespace yg
float rawTileStartLen = 0;
bool skipToOffset = true;
for (size_t i = 0; i < pointsCount - 1; ++i)
{
m2::PointD dir = points[i + 1] - points[i];
@ -65,12 +58,24 @@ namespace yg
/// The remaining length of the segment
float segLenRemain = segLen;
if (skipToOffset)
{
offset -= segLen;
if (offset >= 0)
continue;
else
{
skipToOffset = false;
segLenRemain = -offset;
}
}
/// Geometry width. It's 1px wider than the pattern width.
int geomWidth = lineStyle->m_isSolid ? lineStyle->m_penInfo.m_w : lineStyle->m_penInfo.m_w + 4 - 2 * aaShift();
int geomWidth = lineStyle->m_penInfo.m_w + 4 - 2 * aaShift();
float geomHalfWidth = geomWidth / 2.0;
/// Starting point of the tiles on this segment
m2::PointF rawTileStartPt = points[i];
m2::PointF rawTileStartPt = points[i] + dir * (segLen - segLenRemain);
/// Tiling procedes as following :
/// The leftmost tile goes antialiased at left and non-antialiased at right.
@ -81,15 +86,15 @@ namespace yg
float rawTileLen = 0;
while (segLenRemain > 0)
{
rawTileLen = (lineStyle->m_isWrapped || lineStyle->m_isSolid)
rawTileLen = lineStyle->m_isWrapped
? segLen
: std::min(((float)lineStyle->rawTileLen() - rawTileStartLen), segLenRemain);
float texMaxY = lineStyle->m_isSolid ? lineStyle->m_texRect.minY() + 1 : lineStyle->m_texRect.maxY() - aaShift();
float texMinY = lineStyle->m_isSolid ? lineStyle->m_texRect.minY() + 1 : lineStyle->m_texRect.minY() + aaShift();
float texMaxY = lineStyle->m_texRect.maxY() - aaShift();
float texMinY = lineStyle->m_texRect.minY() + aaShift();
float texMinX = lineStyle->m_isSolid ? lineStyle->m_texRect.minX() + 1 : lineStyle->m_isWrapped ? 0 : lineStyle->m_texRect.minX() + 2 + rawTileStartLen;
float texMaxX = lineStyle->m_isSolid ? lineStyle->m_texRect.minX() + 1 : texMinX + rawTileLen;
float texMinX = lineStyle->m_isWrapped ? 0 : lineStyle->m_texRect.minX() + 2 + rawTileStartLen;
float texMaxX = texMinX + rawTileLen;
rawTileStartLen += rawTileLen;
if (rawTileStartLen >= lineStyle->rawTileLen())

View file

@ -29,7 +29,7 @@ namespace yg
PathRenderer(Params const & params);
void drawPath(m2::PointD const * points, size_t pointsCount, uint32_t styleID, double depth);
void drawPath(m2::PointD const * points, size_t pointsCount, double offset, uint32_t styleID, double depth);
void beginFrame();
void endFrame();

View file

@ -2,6 +2,7 @@
#include "../std/algorithm.hpp"
#include "../std/iterator.hpp"
#include "../std/numeric.hpp"
#include "../base/logging.hpp"
namespace yg
{
@ -19,9 +20,52 @@ namespace yg
m_isSolid = true;
else
{
buffer_vector<double, 4> vec;
copy(pattern, pattern + patternSize, back_inserter(vec));
buffer_vector<double, 4> tmpV;
copy(pattern, pattern + patternSize, back_inserter(tmpV));
if (tmpV.size() % 2)
tmpV.push_back(0);
double length = 0;
length = accumulate(tmpV.begin(), tmpV.end(), 0);
int i = 0;
buffer_vector<double, 4> vec;
if ((offset >= length) || (offset < 0))
offset -= floor(offset / length) * length;
length = 0;
/// shifting pattern
while (true)
{
if (length + tmpV[i] > offset)
{
//we're inside, let's split the pattern
if (i % 2 == 1)
vec.push_back(0);
vec.push_back(length + tmpV[i] - offset);
std::copy(tmpV.data() + i + 1, tmpV.end(), back_inserter(vec));
std::copy(tmpV.begin(), tmpV.data() + i, back_inserter(vec));
vec.push_back(offset - length);
if (i % 2 == 0)
vec.push_back(0);
break;
}
else
length += tmpV[i++];
}
/// ensuring that a minimal element has a length of 2px
length = 0;
for (size_t i = 0; i < vec.size(); ++i)
{
if ((vec[i] < 2) && (vec[i] > 0))
@ -33,16 +77,6 @@ namespace yg
m_pat.reserve(periods * vec.size());
for (int i = 0; i < periods; ++i)
copy(vec.begin(), vec.end(), back_inserter(m_pat));
/* copy(pattern, pattern + patternSize, back_inserter(m_pat));
double length = 0;
for (size_t i = 0; i < m_pat.size(); ++i)
{
if ((m_pat[i] < 2) && (m_pat[i] > 0))
m_pat[i] = 2;
length += m_pat[i];
}
*/
}
}

View file

@ -17,7 +17,7 @@ namespace yg
vector<m2::PointD> pts;
approximateArc(center, startA, endA, r, pts);
drawPath(&pts[0], pts.size(), skin()->mapPenInfo(yg::PenInfo(c, 3, 0, 0, 0)), depth);
drawPath(&pts[0], pts.size(), 0, skin()->mapPenInfo(yg::PenInfo(c, 3, 0, 0, 0)), depth);
}
void ShapeRenderer::approximateArc(m2::PointD const & center, double startA, double endA, double r, vector<m2::PointD> & pts)
@ -38,7 +38,7 @@ namespace yg
approximateArc(center, startA, endA, r, pts);
pts.push_back(center);
drawPath(&pts[0], pts.size(), skin()->mapPenInfo(yg::PenInfo(c, 2, 0, 0, 0)), depth);
drawPath(&pts[0], pts.size(), 0, skin()->mapPenInfo(yg::PenInfo(c, 2, 0, 0, 0)), depth);
}
void ShapeRenderer::fillSector(m2::PointD const & center, double startA, double endA, double r, yg::Color const & c, double depth)

View file

@ -496,11 +496,11 @@ namespace yg
p->m_pageID);
}
void TextRenderer::drawPath(m2::PointD const * points, size_t pointsCount, uint32_t styleID, double depth)
void TextRenderer::drawPath(m2::PointD const * points, size_t pointsCount, double offset, uint32_t styleID, double depth)
{
if (m_useTextTree)
checkTextRedraw();
base_t::drawPath(points, pointsCount, styleID, depth);
base_t::drawPath(points, pointsCount, offset, styleID, depth);
}
}
}

View file

@ -146,7 +146,7 @@ namespace yg
/// flush texts upon any function call.
void setNeedTextRedraw(bool flag);
void drawPath(m2::PointD const * points, size_t pointsCount, uint32_t styleID, double depth);
void drawPath(m2::PointD const * points, size_t pointsCount, double offset, uint32_t styleID, double depth);
void updateActualTarget();
};

View file

@ -48,13 +48,14 @@ namespace
// double pat [] = {7, 7, 10, 10};
double pat1 [] = {1, 1};
p->drawPath(pts, 3, p->skin()->mapPenInfo(yg::PenInfo(yg::Color(0xFF, 0xFF, 0xFF, 0xFF), 2, pat1, 2, 0)), 0);
p->drawPath(pts, 3, 0, p->skin()->mapPenInfo(yg::PenInfo(yg::Color(0xFF, 0xFF, 0xFF, 0xFF), 2, pat1, 2, 0)), 0);
}
};
struct TestDrawPathBase
{
std::vector<std::vector<m2::PointD> > m_pathes;
std::vector<double> m_pathOffsets;
//std::vector<std::vector<double> > m_patterns;
std::vector<yg::PenInfo> m_penInfos;
std::vector<double> m_depthes;
@ -77,11 +78,13 @@ namespace
yg::Color const & color = yg::Color(255, 255, 255, 255),
double width = 2,
double depth = 0,
double offset = 0)
double pathOffset = 0,
double penOffset = 0)
{
m_pathes.push_back(points);
m_pathOffsets.push_back(pathOffset);
//m_patterns.push_back(pattern);
m_penInfos.push_back(yg::PenInfo(color, width, pattern.empty() ? 0 : &pattern[0], pattern.size(), offset));
m_penInfos.push_back(yg::PenInfo(color, width, pattern.empty() ? 0 : &pattern[0], pattern.size(), penOffset));
m_depthes.push_back(depth);
}
@ -94,9 +97,9 @@ namespace
{
for (size_t i = 0; i < m_pathes.size(); ++i)
{
p->drawPath(&m_pathes[i][0], m_pathes[i].size(), p->skin()->mapPenInfo(m_penInfos[i]), m_depthes[i]);
p->drawPath(&m_pathes[i][0], m_pathes[i].size(), m_pathOffsets[i], p->skin()->mapPenInfo(m_penInfos[i]), m_depthes[i]);
if (m_drawAxis)
p->drawPath(&m_pathes[i][0], m_pathes[i].size(), p->skin()->mapPenInfo(m_axisPenInfo), m_depthes[i]);
p->drawPath(&m_pathes[i][0], m_pathes[i].size(), 0, p->skin()->mapPenInfo(m_axisPenInfo), m_depthes[i]);
}
}
@ -140,7 +143,7 @@ namespace
}
};
struct PathWithOffset : TestDrawPathBase
struct TestDrawPathWithOffset : TestDrawPathBase
{
typedef TestDrawPathBase base_t;
@ -153,21 +156,50 @@ namespace
vector<m2::PointD> pts;
vector<double> pattern;
pts.push_back(m2::PointD(100, 100));
pts.push_back(m2::PointD(200, 100));
pts.push_back(m2::PointD(400, 100));
pattern.push_back(20);
pattern.push_back(30);
/// The path should start from -10px offset.
// AddTest(pts, pattern, yg::Color(0, 0, 255, 255), 4, 0, -10);
/// The path should start from -10px path offset.
AddTest(pts, pattern, yg::Color(0, 0, 0, 255), 4, 0, -10);
pts.clear();
pts.push_back(m2::PointD(100, 200));
pts.push_back(m2::PointD(200, 200));
pts.push_back(m2::PointD(200, 110));
pts.push_back(m2::PointD(400, 110));
/// The path should start from 0px path offset.
AddTest(pts, pattern, yg::Color(0, 0, 0, 255), 4, 0, 0);
pts.clear();
pts.push_back(m2::PointD(200, 120));
pts.push_back(m2::PointD(400, 120));
/// The path should start from 60px path offset.
AddTest(pts, pattern, yg::Color(0, 0, 0, 255), 4, 0, 60);
pts.clear();
pts.push_back(m2::PointD(200, 130));
pts.push_back(m2::PointD(400, 130));
/// The path should start from 0px path offset.
AddTest(pts, pattern, yg::Color(0, 0, 0, 255), 4, 0, 0, -10);
pts.clear();
pts.push_back(m2::PointD(200, 140));
pts.push_back(m2::PointD(400, 140));
/// The path should start from 60px path offset.
AddTest(pts, pattern, yg::Color(0, 0, 0, 255), 4, 0, 0, 0);
pts.clear();
pts.push_back(m2::PointD(200, 150));
pts.push_back(m2::PointD(400, 150));
/// The path should start from 60px path offset.
AddTest(pts, pattern, yg::Color(0, 0, 0, 255), 4, 0, 0, 60);
/// The path should start from 60px offset.
AddTest(pts, pattern, yg::Color(0, 0, 255, 255), 4, 0, 60);
}
};
@ -561,7 +593,7 @@ namespace
{
m2::PointD path[2] = {m2::PointD(100, 200), m2::PointD(1000, 200)};
double pat[2] = {2, 2};
p->drawPath(path, sizeof(path) / sizeof(m2::PointD), p->skin()->mapPenInfo(yg::PenInfo(yg::Color(0, 0, 0, 0xFF), 2, pat, 2, 0)), 0);
p->drawPath(path, sizeof(path) / sizeof(m2::PointD), 0, p->skin()->mapPenInfo(yg::PenInfo(yg::Color(0, 0, 0, 0xFF), 2, pat, 2, 0)), 0);
yg::FontDesc fontDesc(false, 20, yg::Color(0, 0, 0, 0), true, yg::Color(255, 255, 255, 255));
@ -622,7 +654,7 @@ namespace
yg::FontDesc fontDesc(false, 20, yg::Color(0, 0, 0, 0), true, yg::Color(255, 255, 255, 255));
p->drawText(fontDesc, m2::PointD(40, 50), yg::EPosAboveRight, 0, "S", 0, true);
p->drawPath(&path[0], path.size(), p->skin()->mapPenInfo(solidPenInfo), 0);
p->drawPath(&path[0], path.size(), 0, p->skin()->mapPenInfo(solidPenInfo), 0);
}
};
@ -717,7 +749,7 @@ namespace
void DoDraw(shared_ptr<yg::gl::Screen> p)
{
p->drawPath(&m_path[0], m_path.size(), p->skin()->mapPenInfo(m_penInfo), 0);
p->drawPath(&m_path[0], m_path.size(), 0, p->skin()->mapPenInfo(m_penInfo), 0);
yg::FontDesc fontDesc(false, 10);
p->drawPathText(fontDesc, &m_path[0], m_path.size(), m_text, calc_length(m_path), 0.0, yg::EPosCenter, 0);
}
@ -743,7 +775,7 @@ namespace
void DoDraw(shared_ptr<yg::gl::Screen> p)
{
p->drawPath(&m_path[0], m_path.size(), p->skin()->mapPenInfo(m_penInfo), 0);
p->drawPath(&m_path[0], m_path.size(), 0, p->skin()->mapPenInfo(m_penInfo), 0);
yg::FontDesc fontDesc(false, 10);
p->drawPathText(fontDesc, &m_path[0], m_path.size(), m_text, calc_length(m_path), 0.0, yg::EPosCenter, 0);
}
@ -753,7 +785,7 @@ namespace
{
void DoDraw(shared_ptr<yg::gl::Screen> p)
{
p->drawPath(&m_path[0], m_path.size(), p->skin()->mapPenInfo(m_penInfo), 0);
p->drawPath(&m_path[0], m_path.size(), 0, p->skin()->mapPenInfo(m_penInfo), 0);
double const len = calc_length(m_path);
yg::FontDesc fontDesc(false, 10);
@ -922,7 +954,7 @@ namespace
uint32_t triangleListID = p->skin()->mapPenInfo(triangleListRule);
uint32_t lineLoopID = p->skin()->mapPenInfo(lineLoopRule);
p->drawPath((m2::PointD const *)&m_vertices[0], m_vertices.size(), inputDataID, 0);
p->drawPath((m2::PointD const *)&m_vertices[0], m_vertices.size(), 0, inputDataID, 0);
for (size_t i = 0; i < m_d.indices().size(); ++i)
{
@ -945,7 +977,7 @@ namespace
}
for (size_t j = 0; j < poly.size(); ++j)
p->drawPath(&poly[j][0], poly[j].size(), triangleFanID, 0);
p->drawPath(&poly[j][0], poly[j].size(), 0, triangleFanID, 0);
break;
}
case tess::TrianglesList:
@ -965,7 +997,7 @@ namespace
}
for (size_t j = 0; j < poly.size(); ++j)
p->drawPath(&poly[j][0], poly[j].size(), triangleListID, 0);
p->drawPath(&poly[j][0], poly[j].size(), 0, triangleListID, 0);
break;
}
case tess::TrianglesStrip:
@ -983,7 +1015,7 @@ namespace
}
for (size_t j = 0; j < poly.size(); ++j)
p->drawPath(&poly[j][0], poly[j].size(), triangleFanID, 0);
p->drawPath(&poly[j][0], poly[j].size(), 0, triangleFanID, 0);
break;
}
case tess::LineLoop:
@ -997,7 +1029,7 @@ namespace
poly.back().push_back(poly.back()[0]);
p->drawPath(&poly[0][0], poly[0].size(), lineLoopID, 0);
p->drawPath(&poly[0][0], poly[0].size(), 0, lineLoopID, 0);
break;
}
}
@ -1034,8 +1066,8 @@ namespace
// UNIT_TEST_GL(TestDrawUnicodeSymbols);
// UNIT_TEST_GL(TestDrawTextRectWithFixedFont);
// UNIT_TEST_GL(TestDrawStringOnString);
// UNIT_TEST_GL(TestDrawTextOnPath);
UNIT_TEST_GL(TestDrawTextOnPathZigZag);
// UNIT_TEST_GL(TestDrawTextOnPath);
// UNIT_TEST_GL(TestDrawTextOnPathZigZag);
// UNIT_TEST_GL(TestDrawTextOnPathWithOffset);
// UNIT_TEST_GL(TestDrawTextOverflow);
// UNIT_TEST_GL(TestDrawTextFiltering);
@ -1044,7 +1076,7 @@ namespace
// UNIT_TEST_GL(TestDrawPoly);
// UNIT_TEST_GL(TestDrawSolidRect);
// UNIT_TEST_GL(TestDrawPathWithSkinPageMiss);
// UNIT_TEST_GL(TestDrawPathWithOffset);
UNIT_TEST_GL(TestDrawPathWithOffset);
// UNIT_TEST_GL(TestDrawPathJoin);
// UNIT_TEST_GL(TestDrawPathSolid1PX);
// UNIT_TEST_GL(TestDrawPathSolid2PX);

View file

@ -44,7 +44,7 @@ namespace
toPixel(pts);
p->drawPath(&pts[0], pts.size(), p->skin()->mapPenInfo(yg::PenInfo(yg::Color(255, 0, 0, 255), 2, 0, 0, 0)), 0);
p->drawPath(&pts[0], pts.size(), 0, p->skin()->mapPenInfo(yg::PenInfo(yg::Color(255, 0, 0, 255), 2, 0, 0, 0)), 0);
}
};