diff --git a/data/basic.skn b/data/basic.skn index ffab281977..8aea91544f 100644 --- a/data/basic.skn +++ b/data/basic.skn @@ -103,299 +103,302 @@ - - + + - - + + - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + - - + + - - + + - - + + - - + + - + - - + + - - + + - - + + - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + - - + + - - + + - - + + - - + + - - + + - - + + + + + diff --git a/data/basic_highres.skn b/data/basic_highres.skn index b429c69722..13f7f9c9c3 100644 --- a/data/basic_highres.skn +++ b/data/basic_highres.skn @@ -103,299 +103,302 @@ - - + + - - + + - + - - + + - - + + - - + + - - + + - - + + - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + - - + + - - + + - - + + - - + + - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + - - + + - - + + - - + + - + - - + + - - + + - - + + - - - - + - - + + - - + + - - + + - - + + + + + + + + diff --git a/data/styles/symbols/current-position.svg b/data/styles/symbols/current-position.svg new file mode 100644 index 0000000000..64e2550603 --- /dev/null +++ b/data/styles/symbols/current-position.svg @@ -0,0 +1,259 @@ + + + + + + + + image/svg+xml + + + blue cristal ball + + + blue + cristal + ball + round + sphere + spheric + + + a blue cristal bsll + 14 11 2006 + + + molumen + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/symbols_24.png b/data/symbols_24.png index de92837fc9..a7e1d4aab8 100644 Binary files a/data/symbols_24.png and b/data/symbols_24.png differ diff --git a/data/symbols_48.png b/data/symbols_48.png index 2d71cfe044..e7ca9eb1de 100644 Binary files a/data/symbols_48.png and b/data/symbols_48.png differ diff --git a/geometry/point2d.hpp b/geometry/point2d.hpp index 14d4084a2e..5f3fb3a449 100644 --- a/geometry/point2d.hpp +++ b/geometry/point2d.hpp @@ -159,6 +159,14 @@ namespace m2 return a.y * b.x - a.x * b.y; } + template + Point const Rotate(Point const & pt, T a) + { + Point res(pt); + res.Rotate(a); + return res; + } + template bool IsPointStrictlyInsideTriangle(Point const & p, Point const & a, Point const & b, Point const & c) diff --git a/iphone/Maps/Classes/MapViewController.hpp b/iphone/Maps/Classes/MapViewController.hpp index 8a2cf922de..d8016ccd9e 100644 --- a/iphone/Maps/Classes/MapViewController.hpp +++ b/iphone/Maps/Classes/MapViewController.hpp @@ -21,6 +21,8 @@ SCALING } m_CurrentAction; + bool m_isDirtyPosition; + m2::PointD m_Pt1, m_Pt2; } diff --git a/iphone/Maps/Classes/MapViewController.mm b/iphone/Maps/Classes/MapViewController.mm index 280d141dfa..7c6578fb0e 100644 --- a/iphone/Maps/Classes/MapViewController.mm +++ b/iphone/Maps/Classes/MapViewController.mm @@ -22,7 +22,9 @@ typedef FrameWork frame - (void) OnMyPositionClicked: (id)sender { + [m_locationController Stop]; [m_locationController Start]; + m_isDirtyPosition = true; } - (void) OnSettingsClicked: (id)sender @@ -56,7 +58,8 @@ typedef FrameWork frame m_locationController = [[UserLocationController alloc] initWithDelegate:self]; m_CurrentAction = NOTHING; - + m_isDirtyPosition = false; + // initialize with currently active screen orientation [self didRotateFromInterfaceOrientation: self.interfaceOrientation]; @@ -88,8 +91,12 @@ withConfidenceRadius: (double) confidenceRadius [m_locationController Stop]; m_framework->SetPosition(mercatorPoint, confidenceRadius); -// m_framework->SetConfidenceRadius() -// m_framework->SetHeading(headingVector); + + if (m_isDirtyPosition) + { + m_framework->CenterViewport(); + m_isDirtyPosition = false; + } } - (void) OnLocationError: (NSString *) errorDescription diff --git a/iphone/Maps/Classes/UserLocationController.mm b/iphone/Maps/Classes/UserLocationController.mm index aeeb77139b..d74974243d 100644 --- a/iphone/Maps/Classes/UserLocationController.mm +++ b/iphone/Maps/Classes/UserLocationController.mm @@ -32,10 +32,17 @@ - (void) Start { - m_locationManager.headingFilter = 5; + [m_locationManager startUpdatingLocation]; - [m_locationManager startUpdatingHeading]; + if ([m_locationManager headingAvailable]) + { + m_locationManager.headingFilter = 5; + [m_locationManager startUpdatingHeading]; + } + else + NSLog(@"heading information is not available"); + } - (void) Stop @@ -59,7 +66,13 @@ MercatorBounds::LatToY(newLocation.coordinate.latitude)); double confidenceRadius = sqrt(newLocation.horizontalAccuracy * newLocation.horizontalAccuracy - + newLocation.verticalAccuracy * newLocation.verticalAccuracy);*/ + + newLocation.verticalAccuracy * newLocation.verticalAccuracy); + + m2::RectD errorRect = MercatorBounds::ErrorToRadius(newLocation.coordinate.longitude, + newLocation.coordinate.latitude, + confidenceRadius); + + confidenceRadius = sqrt((errorRect.SizeX() * errorRect.SizeX() + errorRect.SizeY() * errorRect.SizeY()) / 4); [self.delegate OnLocation: mercPoint withConfidenceRadius: confidenceRadius withTimestamp: newLocation.timestamp]; } diff --git a/map/drawer_yg.cpp b/map/drawer_yg.cpp index e0d1fac864..bd2cd6c41f 100644 --- a/map/drawer_yg.cpp +++ b/map/drawer_yg.cpp @@ -70,6 +70,11 @@ void DrawerYG::onSize(int w, int h) m_pScreen->onSize(w, h); } +void DrawerYG::drawSymbol(m2::PointD const & pt, string const & symbolName, int depth) +{ + m_pScreen->drawPoint(pt, m_pSkin->mapSymbol(symbolName.c_str()), depth); +} + void DrawerYG::drawSymbol(m2::PointD const & pt, rule_ptr_t pRule, int depth) { // Use BaseRule::m_id to cache for point draw rule. diff --git a/map/drawer_yg.hpp b/map/drawer_yg.hpp index 44e5cf578a..f784572ae9 100644 --- a/map/drawer_yg.hpp +++ b/map/drawer_yg.hpp @@ -70,6 +70,8 @@ public: DrawerYG(shared_ptr const & tm, string const & skinName, bool isAntiAliased); + void drawSymbol(m2::PointD const & pt, string const & symbolName, int depth); + //render_target_t renderTarget() const; void setFrameBuffer(frame_buffer_t frameBuffer); //frame_buffer_t frameBuffer() const; diff --git a/map/framework.hpp b/map/framework.hpp index da923b0b3e..50ec86943e 100644 --- a/map/framework.hpp +++ b/map/framework.hpp @@ -308,13 +308,63 @@ public: m2::PointD const center = m_navigator.Screen().ClipRect().Center(); - if (m_isPositionEnabled) - { + DrawPosition(pDrawer); - /// Drawing position and heading - m2::PointD pxPosition = m_navigator.Screen().GtoP(m_position); - pDrawer->screen()->drawPoint(pxPosition - ptShift, 84, 10000); - if (m_isHeadingEnabled) + OGLCHECK(glPopMatrix()); + + pDrawer->drawStats(state.m_duration, GetCurrentScale(), + MercatorBounds::YToLat(center.y), MercatorBounds::XToLon(center.x)); + } + } + + void DrawPosition(DrawerYG * pDrawer) + { + if (m_isPositionEnabled) + { + m2::PointD ptShift = GetCoordSystemShift(); + /// Drawing position and heading + m2::PointD pxPosition = m_navigator.Screen().GtoP(m_position); + pDrawer->drawSymbol(pxPosition - ptShift, "current-position", 12000); + + double pxConfidenceRadius = pxPosition.Length(m_navigator.Screen().GtoP(m_position + m2::PointD(m_confidenceRadius, 0))); + + size_t sectorsCount = 360; + vector borderPts; + vector areaPts; + m2::PointD prevPt = pxPosition + m2::PointD(pxConfidenceRadius, 0) - ptShift; + + for (size_t i = 0; i < sectorsCount; ++i) + { + m2::PointD curPt = pxPosition + m2::Rotate(m2::PointD(pxConfidenceRadius, 0), i / 180.0 * math::pi) - ptShift; + borderPts.push_back(curPt); + if (prevPt != curPt) + { + areaPts.push_back(pxPosition - ptShift); + areaPts.push_back(prevPt); + areaPts.push_back(curPt); + } + prevPt = curPt; + } + + borderPts.push_back(pxPosition + m2::PointD(pxConfidenceRadius, 0) - ptShift); + areaPts.push_back(pxPosition - ptShift); + areaPts.push_back(prevPt); + areaPts.push_back(pxPosition + m2::PointD(pxConfidenceRadius, 0) - ptShift); + + pDrawer->screen()->drawPath( + &borderPts[0], + borderPts.size(), + pDrawer->screen()->skin()->mapPenInfo(yg::PenInfo(yg::Color(0, 0, 255, 64), 4, 0, 0, 0)), + 11999 + ); + + pDrawer->screen()->drawTriangles( + &areaPts[0], + areaPts.size(), + pDrawer->screen()->skin()->mapColor(yg::Color(0, 0, 255, 32)), + 11998); + +/* if (m_isHeadingEnabled) { LOG(LINFO, ("Drawing Heading", m_heading)); m2::PointD v(0, 1); @@ -322,6 +372,8 @@ public: m2::PointD pts[2] = {m_navigator.Screen().GtoP(m_position), m_navigator.Screen().GtoP(m_position + v)}; + + pDrawer->screen()->drawPath( pts, 2, @@ -329,13 +381,7 @@ public: 12000 ); } - } - - - OGLCHECK(glPopMatrix()); - - pDrawer->drawStats(state.m_duration, GetCurrentScale(), - MercatorBounds::YToLat(center.y), MercatorBounds::XToLon(center.x)); +*/ } } @@ -346,7 +392,12 @@ public: m_position = mercatorPos; m_confidenceRadius = confidenceRadius; - m_navigator.CenterViewport(mercatorPos); + UpdateNow(); + } + + void CenterViewport() + { + m_navigator.CenterViewport(m_position); UpdateNow(); } diff --git a/skin_generator/skin_generator.cpp b/skin_generator/skin_generator.cpp index 013441824b..5869773812 100644 --- a/skin_generator/skin_generator.cpp +++ b/skin_generator/skin_generator.cpp @@ -9,11 +9,45 @@ #include "../std/iterator.hpp" #include "../std/fstream.hpp" #include "../std/iostream.hpp" +#include "../base/logging.hpp" #include + #include FT_FREETYPE_H +#include FT_STROKER_H #include FT_GLYPH_H +#undef __FTERRORS_H__ +#define FT_ERRORDEF( e, v, s ) { e, s }, +#define FT_ERROR_START_LIST { +#define FT_ERROR_END_LIST { 0, 0 } }; + +const struct +{ + int err_code; + const char* err_msg; +} ft_errors[] = + +#include FT_ERRORS_H + +void CheckError(FT_Error error) +{ + if (error != 0) + { + int i = 0; + while (ft_errors[i].err_code != 0) + { + if (ft_errors[i].err_code == error) + { + LOG(LERROR, (ft_errors[i].err_msg)); + break; + } + ++i; + } + } +} + +#define FTCHECK(x) do {FT_Error e = (x); CheckError(e);} while (false) namespace gil = boost::gil; @@ -42,10 +76,16 @@ namespace tools fclose(file); FT_Library lib; - FT_Init_FreeType(&lib); + FT_Error error; + FTCHECK(FT_Init_FreeType(&lib)); FT_Face face; - FT_New_Face(lib, fileName.c_str(), 0, &face); + FTCHECK(FT_New_Face(lib, fileName.c_str(), 0, &face)); + + FT_Stroker stroker; + FTCHECK(FT_Stroker_New(lib, &stroker)); + size_t outlineWidth = 10; + FT_Stroker_Set(stroker, outlineWidth * 64, FT_STROKER_LINECAP_ROUND, FT_STROKER_LINEJOIN_ROUND, 0); FT_Glyph_Metrics glyphMetrics; @@ -59,7 +99,8 @@ namespace tools fontInfo.m_size = fontSizes[i]; - FT_Set_Pixel_Sizes(face, 0, fontSizes[i]); + FTCHECK(FT_Set_Pixel_Sizes(face, 0, fontSizes[i])); +// FTCHECK(FT_Set_Pixel_Sizes(face, 0, 200)); for (size_t j = 0; j < ucs2Symbols.size(); ++j) { unsigned short symbol = ucs2Symbols[j]; @@ -69,7 +110,7 @@ namespace tools if (symbolIdx == 0) continue; - FT_Load_Glyph(face, symbolIdx, FT_LOAD_DEFAULT); + FTCHECK(FT_Load_Glyph(face, symbolIdx, FT_LOAD_DEFAULT)); glyphMetrics = face->glyph->metrics; CharInfo charInfo; @@ -79,13 +120,26 @@ namespace tools charInfo.m_yOffset = int(glyphMetrics.horiBearingY >> 6) - charInfo.m_height; charInfo.m_xAdvance = int(glyphMetrics.horiAdvance >> 6); - FT_GlyphSlot glyphSlot = face->glyph; if ((charInfo.m_width != 0) && (charInfo.m_height != 0)) { - FT_Render_Glyph(glyphSlot, FT_RENDER_MODE_NORMAL); + FT_GlyphSlot glyphSlot = face->glyph; + FTCHECK(FT_Render_Glyph(glyphSlot, FT_RENDER_MODE_NORMAL)); + +/* FT_Glyph strokedGlyph; + FTCHECK(FT_Get_Glyph(face->glyph, &strokedGlyph)); + + FTCHECK(FT_Glyph_Stroke(&strokedGlyph, stroker, 1)); + FTCHECK(FT_Glyph_To_Bitmap(&strokedGlyph, FT_RENDER_MODE_NORMAL, 0, 0)); +*/ typedef gil::gray8_pixel_t pixel_t; +/* gil::gray8c_view_t grayview = gil::interleaved_view( + charInfo.m_width, + charInfo.m_height, + (pixel_t*)((FT_BitmapGlyph)strokedGlyph)->bitmap.buffer, + sizeof(unsigned char) * ((FT_BitmapGlyph)strokedGlyph)->bitmap.width); +*/ gil::gray8c_view_t grayview = gil::interleaved_view( charInfo.m_width, charInfo.m_height, @@ -94,6 +148,13 @@ namespace tools charInfo.m_image.recreate(charInfo.m_width, charInfo.m_height); gil::copy_pixels(grayview, gil::view(charInfo.m_image)); + + /* gil::lodepng_write_view( + "testchar.png", + gil::view(charInfo.m_image)); + + FT_Done_Glyph(strokedGlyph); + */ } fontInfo.m_chars[symbol] = charInfo; diff --git a/yg/texture.hpp b/yg/texture.hpp index 0825c1d88d..04a8eb7a71 100644 --- a/yg/texture.hpp +++ b/yg/texture.hpp @@ -300,7 +300,7 @@ namespace yg } template - void Texture::fill(yg::Color const & c) + void Texture::fill(yg::Color const & /*c*/) { /* makeCurrent(); lock();