From 67907b5423e2c88b70579b7b06f361610ade7c3b Mon Sep 17 00:00:00 2001 From: rachytski Date: Sun, 9 Dec 2012 00:17:23 +0300 Subject: [PATCH] refactored ResourceStyle and lot of *Info classes into consistent Resource and Resource::Info system. --- graphics/area_renderer.cpp | 48 ++-- graphics/area_renderer.hpp | 4 +- graphics/brush.cpp | 76 +++++ graphics/brush.hpp | 33 +++ graphics/circle.cpp | 177 ++++++++++-- graphics/circle.hpp | 46 +-- graphics/circle_element.cpp | 16 +- graphics/circle_element.hpp | 6 +- graphics/display_list.cpp | 2 +- graphics/display_list.hpp | 2 +- graphics/display_list_renderer.cpp | 10 +- graphics/display_list_renderer.hpp | 6 +- graphics/geometry_batcher.cpp | 26 +- graphics/geometry_batcher.hpp | 8 +- graphics/glyph.cpp | 96 +++++-- graphics/glyph.hpp | 38 +++ graphics/glyph_cache.cpp | 46 ++- graphics/glyph_cache.hpp | 33 +-- graphics/glyph_cache_impl.cpp | 123 +++----- graphics/glyph_cache_impl.hpp | 9 +- graphics/glyph_layout.cpp | 2 +- graphics/graphics.pro | 9 +- graphics/graphics_tests/glyph_cache_test.cpp | 4 +- graphics/graphics_tests/screengl_test.cpp | 95 +++---- .../graphics_tests/screenglglobal_test.cpp | 4 +- graphics/graphics_tests/skin_test.cpp | 2 +- graphics/icon.cpp | 55 ++++ graphics/icon.hpp | 33 +++ graphics/image.cpp | 88 +++++- graphics/image.hpp | 41 ++- graphics/image_renderer.cpp | 18 +- graphics/image_renderer.hpp | 2 +- graphics/opengl/geometry_renderer.cpp | 24 +- graphics/opengl/geometry_renderer.hpp | 12 +- graphics/opengl/texture.hpp | 2 +- graphics/overlay_renderer.cpp | 6 +- graphics/overlay_renderer.hpp | 6 +- graphics/path_renderer.cpp | 93 ++++--- graphics/path_renderer.hpp | 4 +- graphics/pen.cpp | 258 +++++++++++++++-- graphics/pen.hpp | 68 +++-- graphics/resource.cpp | 91 +----- graphics/resource.hpp | 127 +++------ graphics/resource_cache.cpp | 263 +++--------------- graphics/resource_cache.hpp | 75 ++--- graphics/shape_renderer.cpp | 47 ++-- graphics/skin.cpp | 94 +------ graphics/skin.hpp | 44 +-- graphics/skin_loader.cpp | 67 ++--- graphics/skin_loader.hpp | 31 +-- graphics/symbol_element.cpp | 33 +-- graphics/symbol_element.hpp | 9 +- graphics/text_element.cpp | 11 +- graphics/text_renderer.cpp | 14 +- graphics/text_renderer.hpp | 6 +- map/compass_arrow.cpp | 5 +- map/drawer.cpp | 35 ++- map/information_display.cpp | 2 +- map/location_state.cpp | 8 +- map/proto_to_styles.cpp | 18 +- map/proto_to_styles.hpp | 16 +- map/ruler.cpp | 3 +- qt_tstfrm/tstwidgets.cpp | 5 +- 63 files changed, 1460 insertions(+), 1175 deletions(-) create mode 100644 graphics/brush.cpp create mode 100644 graphics/brush.hpp create mode 100644 graphics/glyph.hpp create mode 100644 graphics/icon.cpp create mode 100644 graphics/icon.hpp diff --git a/graphics/area_renderer.cpp b/graphics/area_renderer.cpp index d4498769af..8a60fd3871 100644 --- a/graphics/area_renderer.cpp +++ b/graphics/area_renderer.cpp @@ -1,5 +1,5 @@ #include "area_renderer.hpp" -#include "resource_style.hpp" +#include "brush.hpp" #include "skin.hpp" #include "resource_cache.hpp" @@ -37,7 +37,7 @@ namespace graphics void AreaRenderer::drawTrianglesFan(m2::PointF const * points, size_t pointsCount, - uint32_t styleID, + uint32_t resID, double depth) { ++m_areasCount; @@ -46,20 +46,22 @@ namespace graphics if (!m_drawAreas) return; - ResourceStyle const * style = skin()->fromID(styleID); + Resource const * res = skin()->fromID(resID); - if (style == 0) + ASSERT(res->m_cat == Resource::EBrush, ("triangleFan should be rendered with Brush resource")); + + if (res == 0) { - LOG(LINFO, ("drawTrianglesFan: styleID=", styleID, " wasn't found on current skin.")); + LOG(LINFO, ("drawTrianglesFan: resID=", resID, " wasn't found on current skin.")); return; } ASSERT_GREATER_OR_EQUAL(pointsCount, 2, ()); - float texX = style->m_texRect.minX() + 1.0f; - float texY = style->m_texRect.minY() + 1.0f; + float texX = res->m_texRect.minX() + 1.0f; + float texY = res->m_texRect.minY() + 1.0f; - shared_ptr texture = skin()->page(style->m_pipelineID)->texture(); + shared_ptr texture = skin()->page(res->m_pipelineID)->texture(); if (!texture) { @@ -77,10 +79,10 @@ namespace graphics &texCoord, 0, pointsCount, depth, - style->m_pipelineID); + res->m_pipelineID); } - void AreaRenderer::drawTrianglesList(m2::PointD const * points, size_t pointsCount, uint32_t styleID, double depth) + void AreaRenderer::drawTrianglesList(m2::PointD const * points, size_t pointsCount, uint32_t resID, double depth) { ++m_areasCount; m_trianglesCount += pointsCount / 3; @@ -88,23 +90,25 @@ namespace graphics if (!m_drawAreas) return; - ResourceStyle const * style = skin()->fromID(styleID); + Resource const * res = skin()->fromID(resID); - if (style == 0) + ASSERT(res->m_cat == Resource::EBrush, ("area should be rendered with Brush resource")); + + if (res == 0) { - LOG(LINFO, ("drawArea: styleID=", styleID, " wasn't found on current skin.")); + LOG(LINFO, ("drawArea: resID=", resID, " wasn't found on current skin.")); return; } - if (!hasRoom(pointsCount, pointsCount, style->m_pipelineID)) - flush(style->m_pipelineID); + if (!hasRoom(pointsCount, pointsCount, res->m_pipelineID)) + flush(res->m_pipelineID); ASSERT_GREATER_OR_EQUAL(pointsCount, 2, ()); - float texX = style->m_texRect.minX() + 1.0f; - float texY = style->m_texRect.minY() + 1.0f; + float texX = res->m_texRect.minX() + 1.0f; + float texY = res->m_texRect.minY() + 1.0f; - shared_ptr texture = skin()->page(style->m_pipelineID)->texture(); + shared_ptr texture = skin()->page(res->m_pipelineID)->texture(); if (!texture) { @@ -121,8 +125,8 @@ namespace graphics { size_t batchSize = pointsLeft; - int vLeft = verticesLeft(style->m_pipelineID); - int iLeft = indicesLeft(style->m_pipelineID); + int vLeft = verticesLeft(res->m_pipelineID); + int iLeft = indicesLeft(res->m_pipelineID); if ((vLeft == -1) || (iLeft == -1)) return; @@ -144,13 +148,13 @@ namespace graphics &texCoord, 0, batchSize, depth, - style->m_pipelineID); + res->m_pipelineID); batchOffset += batchSize; pointsLeft -= batchSize; if (needToFlush) - flush(style->m_pipelineID); + flush(res->m_pipelineID); if (pointsLeft == 0) break; diff --git a/graphics/area_renderer.hpp b/graphics/area_renderer.hpp index 4323935e21..3321535e14 100644 --- a/graphics/area_renderer.hpp +++ b/graphics/area_renderer.hpp @@ -27,12 +27,12 @@ namespace graphics /// drawing triangles list. assuming that each 3 points compose a triangle void drawTrianglesList(m2::PointD const * points, size_t pointsCount, - uint32_t styleID, + uint32_t resID, double depth); void drawTrianglesFan(m2::PointF const * points, size_t pointsCount, - uint32_t styleID, + uint32_t resID, double depth); void beginFrame(); diff --git a/graphics/brush.cpp b/graphics/brush.cpp new file mode 100644 index 0000000000..085e30969c --- /dev/null +++ b/graphics/brush.cpp @@ -0,0 +1,76 @@ +#include "brush.hpp" +#include "opengl/data_traits.hpp" + +namespace graphics +{ + Brush::Info::Info() + : Resource::Info(Resource::EBrush) + {} + + Brush::Info::Info(Color const & color) + : Resource::Info(Resource::EBrush), + m_color(color) + {} + + m2::PointU const Brush::Info::resourceSize() const + { + return m2::PointU(2, 2); + } + + Resource * Brush::Info::createResource(m2::RectU const & texRect, + uint8_t pipelineID) const + { + return new Brush(texRect, + pipelineID, + *this); + } + + bool Brush::Info::lessThan(Resource::Info const * r) const + { + if (m_category != r->m_category) + return m_category < r->m_category; + + Brush::Info const * br = static_cast(r); + + if (m_color != br->m_color) + return m_color < br->m_color; + + return false; + } + + Brush::Brush(m2::RectU const & texRect, + uint8_t pipelineID, + Info const & info) + : Resource(EBrush, texRect, pipelineID), + m_info(info) + { + } + + void Brush::render(void *dst) + { + graphics::Color c = m_info.m_color; + m2::RectU const & r = m_texRect; + + DATA_TRAITS::pixel_t px; + + gil::get_color(px, gil::red_t()) = c.r / DATA_TRAITS::channelScaleFactor; + gil::get_color(px, gil::green_t()) = c.g / DATA_TRAITS::channelScaleFactor; + gil::get_color(px, gil::blue_t()) = c.b / DATA_TRAITS::channelScaleFactor; + gil::get_color(px, gil::alpha_t()) = c.a / DATA_TRAITS::channelScaleFactor; + + DATA_TRAITS::view_t v = gil::interleaved_view( + r.SizeX(), r.SizeY(), + (DATA_TRAITS::pixel_t*)dst, + sizeof(DATA_TRAITS::pixel_t) * r.SizeX() + ); + + for (size_t y = 0; y < r.SizeY(); ++y) + for (size_t x = 0; x < r.SizeX(); ++x) + v(x, y) = px; + } + + Resource::Info const * Brush::info() const + { + return &m_info; + } +} diff --git a/graphics/brush.hpp b/graphics/brush.hpp new file mode 100644 index 0000000000..f4a0bc8a67 --- /dev/null +++ b/graphics/brush.hpp @@ -0,0 +1,33 @@ +#pragma once + +#include "resource.hpp" +#include "color.hpp" + +namespace graphics +{ + struct Brush : public Resource + { + struct Info : public Resource::Info + { + Color m_color; + + Info(); + explicit Info(Color const & color); + + m2::PointU const resourceSize() const; + Resource * createResource(m2::RectU const & texRect, + uint8_t pipelineID) const; + + bool lessThan(Resource::Info const * r) const; + }; + + Info m_info; + + Brush(m2::RectU const & texRect, + uint8_t pipelineID, + Info const & info); + + void render(void * dst); + Resource::Info const * info() const; + }; +} diff --git a/graphics/circle.cpp b/graphics/circle.cpp index ab5ae7b0eb..3cd7ea9174 100644 --- a/graphics/circle.cpp +++ b/graphics/circle.cpp @@ -1,18 +1,20 @@ #include "../base/SRC_FIRST.hpp" -#include "circle_info.hpp" +#include "circle.hpp" +#include "opengl/data_traits.hpp" +#include "agg_traits.hpp" #include "../base/math.hpp" - namespace graphics { - CircleInfo::CircleInfo(double radius, - Color const & color, - bool isOutlined, - double outlineWidth, - Color const & outlineColor) - : m_radius(my::rounds(radius)), + Circle::Info::Info(double radius, + Color const & color, + bool isOutlined, + double outlineWidth, + Color const & outlineColor) + : Resource::Info(Resource::ECircle), + m_radius(my::rounds(radius)), m_color(color), m_isOutlined(isOutlined), m_outlineWidth(my::rounds(outlineWidth)), @@ -25,25 +27,160 @@ namespace graphics } } - CircleInfo::CircleInfo() + Circle::Info::Info() + : Resource::Info(Resource::ECircle) {} - bool operator< (CircleInfo const & l, CircleInfo const & r) + bool Circle::Info::lessThan(Resource::Info const * r) const { - if (l.m_radius != r.m_radius) - return l.m_radius < r.m_radius; - if (l.m_color != r.m_color) - return l.m_color < r.m_color; - if (l.m_isOutlined != r.m_isOutlined) - return l.m_isOutlined < r.m_isOutlined; - if (l.m_outlineWidth != r.m_outlineWidth) - return l.m_outlineWidth < r.m_outlineWidth; - return l.m_outlineColor < r.m_outlineColor; + if (m_category != r->m_category) + return m_category < r->m_category; + + Circle::Info const * ci = static_cast(r); + + if (m_radius != ci->m_radius) + return m_radius < ci->m_radius; + if (m_color != ci->m_color) + return m_color < ci->m_color; + if (m_isOutlined != ci->m_isOutlined) + return m_isOutlined < ci->m_isOutlined; + if (m_outlineWidth != ci->m_outlineWidth) + return m_outlineWidth < ci->m_outlineWidth; + if (m_outlineColor != ci->m_outlineColor) + return m_outlineColor < ci->m_outlineColor; + + return false; } - m2::PointU const CircleInfo::patternSize() const + m2::PointU const Circle::Info::resourceSize() const { unsigned r = m_isOutlined ? m_radius + m_outlineWidth : m_radius; return m2::PointU(r * 2 + 4, r * 2 + 4); } + + Resource * Circle::Info::createResource(m2::RectU const & texRect, + uint8_t pipelineID) const + { + return new Circle(texRect, + pipelineID, + *this); + } + + Circle::Circle(m2::RectU const & texRect, + int pipelineID, + Info const & info) + : Resource(ECircle, texRect, pipelineID), + m_info(info) + {} + + void Circle::render(void * dst) + { + m2::RectU const & rect = m_texRect; + + DATA_TRAITS::view_t v = gil::interleaved_view( + rect.SizeX(), rect.SizeY(), + (DATA_TRAITS::pixel_t*)dst, + sizeof(DATA_TRAITS::pixel_t) * rect.SizeX() + ); + + Circle::Info info = m_info; + + agg::rgba8 aggColor(info.m_color.r, + info.m_color.g, + info.m_color.b, + info.m_color.a); + + agg::rgba8 aggOutlineColor(info.m_outlineColor.r, + info.m_outlineColor.g, + info.m_outlineColor.b, + info.m_outlineColor.a); + + info.m_color /= DATA_TRAITS::channelScaleFactor; + + DATA_TRAITS::pixel_t gilColorTranslucent; + + gil::get_color(gilColorTranslucent, gil::red_t()) = info.m_color.r; + gil::get_color(gilColorTranslucent, gil::green_t()) = info.m_color.g; + gil::get_color(gilColorTranslucent, gil::blue_t()) = info.m_color.b; + gil::get_color(gilColorTranslucent, gil::alpha_t()) = 0; + + info.m_outlineColor /= DATA_TRAITS::channelScaleFactor; + + DATA_TRAITS::pixel_t gilOutlineColorTranslucent; + + gil::get_color(gilOutlineColorTranslucent, gil::red_t()) = info.m_outlineColor.r; + gil::get_color(gilOutlineColorTranslucent, gil::green_t()) = info.m_outlineColor.g; + gil::get_color(gilOutlineColorTranslucent, gil::blue_t()) = info.m_outlineColor.b; + gil::get_color(gilOutlineColorTranslucent, gil::alpha_t()) = 0; + + DATA_TRAITS::pixel_t gilColor = gilColorTranslucent; + gil::get_color(gilColor, gil::alpha_t()) = info.m_color.a; + + DATA_TRAITS::pixel_t gilOutlineColor = gilOutlineColorTranslucent; + gil::get_color(gilOutlineColor, gil::alpha_t()) = info.m_outlineColor.a; + + /// draw circle + agg::rendering_buffer buf( + (unsigned char *)&v(0, 0), + rect.SizeX(), + rect.SizeY(), + rect.SizeX() * sizeof(DATA_TRAITS::pixel_t) + ); + + typedef AggTraits::pixfmt_t agg_pixfmt_t; + + agg_pixfmt_t pixfmt(buf); + agg::renderer_base rbase(pixfmt); + + if (info.m_isOutlined) + gil::fill_pixels(v, gilOutlineColorTranslucent); + else + gil::fill_pixels(v, gilColorTranslucent); + + m2::PointD center(info.resourceSize()); + center *= 0.5; + + agg::scanline_u8 s; + agg::rasterizer_scanline_aa<> rasterizer; + + agg::ellipse ell; + + ell.init(center.x, + center.y, + info.m_isOutlined ? info.m_radius + info.m_outlineWidth : info.m_radius, + info.m_isOutlined ? info.m_radius + info.m_outlineWidth : info.m_radius, + 100); + + rasterizer.add_path(ell); + + agg::render_scanlines_aa_solid(rasterizer, + s, + rbase, + info.m_isOutlined ? aggOutlineColor : aggColor); + + if (info.m_isOutlined) + { + /// drawing inner circle + ell.init(center.x, + center.y, + info.m_radius, + info.m_radius, + 100); + + rasterizer.reset(); + rasterizer.add_path(ell); + + agg::render_scanlines_aa_solid(rasterizer, + s, + rbase, + aggColor); + + } + } + + Resource::Info const * Circle::info() const + { + return &m_info; + } } + diff --git a/graphics/circle.hpp b/graphics/circle.hpp index 11fa9c7147..5634a36a9d 100644 --- a/graphics/circle.hpp +++ b/graphics/circle.hpp @@ -1,29 +1,43 @@ #pragma once #include "color.hpp" +#include "resource.hpp" #include "../geometry/point2d.hpp" namespace graphics { - struct CircleInfo + struct Circle : public Resource { - unsigned m_radius; - Color m_color; - bool m_isOutlined; - unsigned m_outlineWidth; - Color m_outlineColor; + struct Info : public Resource::Info + { + unsigned m_radius; + Color m_color; + bool m_isOutlined; + unsigned m_outlineWidth; + Color m_outlineColor; - CircleInfo(); - CircleInfo( - double radius, - Color const & color = Color(0, 0, 0, 255), - bool isOutlined = false, - double outlineWidth = 1, - Color const & outlineColor = Color(255, 255, 255, 255)); + Info(); + Info(double radius, + Color const & color = Color(0, 0, 0, 255), + bool isOutlined = false, + double outlineWidth = 1, + Color const & outlineColor = Color(255, 255, 255, 255)); - m2::PointU const patternSize() const; + m2::PointU const resourceSize() const; + Resource * createResource(m2::RectU const & texRect, + uint8_t pipelineID) const; + + bool lessThan(Resource::Info const * r) const; + }; + + Info m_info; + + Circle(m2::RectU const & texRect, + int pipelineID, + Info const & info); + + void render(void * dst); + Resource::Info const * info() const; }; - - bool operator< (CircleInfo const & l, CircleInfo const & r); } diff --git a/graphics/circle_element.cpp b/graphics/circle_element.cpp index a0fd5a0b58..8e6998fc32 100644 --- a/graphics/circle_element.cpp +++ b/graphics/circle_element.cpp @@ -1,7 +1,6 @@ #include "circle_element.hpp" #include "overlay_renderer.hpp" -#include "resource_style.hpp" #include "skin.hpp" namespace graphics @@ -11,7 +10,6 @@ namespace graphics m_ci(p.m_ci) {} - CircleElement::CircleElement(CircleElement const & ce, math::Matrix const & m) : base_t(ce), m_ci(ce.m_ci) @@ -33,7 +31,9 @@ namespace graphics m2::AnyRectD const CircleElement::boundRect() const { - m2::RectI texRect(m2::PointI(0, 0), m2::PointI(m_ci.patternSize())); + m2::RectI texRect(m2::PointI(0, 0), + m2::PointI(m_ci.resourceSize())); + texRect.Inflate(-1, -1); m2::PointD posPt = tieRect(m2::RectD(texRect), math::Identity()); @@ -46,12 +46,12 @@ namespace graphics if (!isNeedRedraw()) return; - uint32_t styleID = r->skin()->mapCircleInfo(m_ci); + uint32_t resID = r->skin()->map(m_ci); - ResourceStyle const * style = r->skin()->fromID(styleID); - ASSERT_NOT_EQUAL ( style, 0, () ); + Resource const * res = r->skin()->fromID(resID); + ASSERT_NOT_EQUAL ( res, 0, () ); - m2::RectI texRect(style->m_texRect); + m2::RectI texRect(res->m_texRect); texRect.Inflate(-1, -1); m2::PointD posPt = tieRect(m2::RectD(texRect), m); @@ -60,7 +60,7 @@ namespace graphics texRect.minX(), texRect.minY(), texRect.maxX(), texRect.maxY(), posPt.x, posPt.y, posPt.x + texRect.SizeX(), posPt.y + texRect.SizeY(), graphics::maxDepth, - style->m_pipelineID); + res->m_pipelineID); } int CircleElement::visualRank() const diff --git a/graphics/circle_element.hpp b/graphics/circle_element.hpp index 49fbde0e0e..974486b608 100644 --- a/graphics/circle_element.hpp +++ b/graphics/circle_element.hpp @@ -1,7 +1,7 @@ #pragma once #include "overlay_element.hpp" -#include "circle_info.hpp" +#include "circle.hpp" namespace graphics { @@ -9,7 +9,7 @@ namespace graphics { private: - graphics::CircleInfo m_ci; + Circle::Info m_ci; mutable vector m_boundRects; @@ -21,7 +21,7 @@ namespace graphics struct Params : public base_t::Params { - graphics::CircleInfo m_ci; + Circle::Info m_ci; }; CircleElement(Params const & p); diff --git a/graphics/display_list.cpp b/graphics/display_list.cpp index 4206be5c70..11f37a46d8 100644 --- a/graphics/display_list.cpp +++ b/graphics/display_list.cpp @@ -82,7 +82,7 @@ namespace graphics m_discardStorageCmd.push_back(cmd); } - void DisplayList::uploadStyles(shared_ptr const & cmd) + void DisplayList::uploadResources(shared_ptr const & cmd) { cmd->setIsDebugging(m_isDebugging); m_parent->processCommand(cmd); diff --git a/graphics/display_list.hpp b/graphics/display_list.hpp index b4c9b5c9b9..54042177b0 100644 --- a/graphics/display_list.hpp +++ b/graphics/display_list.hpp @@ -44,7 +44,7 @@ namespace graphics void discardStorage(shared_ptr const & cmd); void freeTexture(shared_ptr const & cmd); void freeStorage(shared_ptr const & cmd); - void uploadStyles(shared_ptr const & cmd); + void uploadResources(shared_ptr const & cmd); void addCheckPoint(); void draw(DisplayListRenderer * r, diff --git a/graphics/display_list_renderer.cpp b/graphics/display_list_renderer.cpp index ca8b519d04..f894fc3281 100644 --- a/graphics/display_list_renderer.cpp +++ b/graphics/display_list_renderer.cpp @@ -60,17 +60,17 @@ namespace graphics } - void DisplayListRenderer::uploadStyles(shared_ptr const * styles, - size_t count, - shared_ptr const & texture) + void DisplayListRenderer::uploadResources(shared_ptr const * resources, + size_t count, + shared_ptr const & texture) { if (isCancelled()) return; if (m_displayList) - m_displayList->uploadStyles(make_shared_ptr(new UploadData(styles, count, texture))); + m_displayList->uploadResources(make_shared_ptr(new UploadData(resources, count, texture))); else - base_t::uploadStyles(styles, count, texture); + base_t::uploadResources(resources, count, texture); } void DisplayListRenderer::freeTexture(shared_ptr const & texture, diff --git a/graphics/display_list_renderer.hpp b/graphics/display_list_renderer.hpp index c0036dc679..8c9a9138e4 100644 --- a/graphics/display_list_renderer.hpp +++ b/graphics/display_list_renderer.hpp @@ -40,9 +40,9 @@ namespace graphics size_t indicesOffs, EPrimitives primType); /// upload ResourceStyle's on texture - void uploadStyles(shared_ptr const * styles, - size_t count, - shared_ptr const & texture); + void uploadResources(shared_ptr const * resources, + size_t count, + shared_ptr const & texture); /// free texture void freeTexture(shared_ptr const & texture, TTexturePool * texturePool); diff --git a/graphics/geometry_batcher.cpp b/graphics/geometry_batcher.cpp index 3ef9577aab..1eda38e1a5 100644 --- a/graphics/geometry_batcher.cpp +++ b/graphics/geometry_batcher.cpp @@ -3,7 +3,6 @@ #include "color.hpp" #include "resource_manager.hpp" #include "resource_cache.hpp" -#include "resource_style.hpp" #include "opengl/base_texture.hpp" #include "opengl/utils.hpp" @@ -207,12 +206,6 @@ namespace graphics base_t::clear(c, clearRT, depth, clearDepth); } - void GeometryBatcher::setRenderTarget(shared_ptr const & rt) - { - flush(-1); - base_t::setRenderTarget(rt); - } - void GeometryBatcher::endFrame() { flush(-1); @@ -349,7 +342,9 @@ namespace graphics { if (resourceCache->hasData()) { - uploadStyles(&resourceCache->uploadQueue()[0], resourceCache->uploadQueue().size(), resourceCache->texture()); + uploadResources(&resourceCache->uploadQueue()[0], + resourceCache->uploadQueue().size(), + resourceCache->texture()); resourceCache->clearUploadQueue(); } @@ -386,6 +381,7 @@ namespace graphics return false; } + void GeometryBatcher::drawTexturedPolygon( m2::PointD const & ptShift, ang::AngleD const & angle, @@ -799,9 +795,9 @@ namespace graphics base_t::drawDisplayList(dl, m); } - void GeometryBatcher::uploadStyles(shared_ptr const * styles, - size_t count, - shared_ptr const & texture) + void GeometryBatcher::uploadResources(shared_ptr const * resources, + size_t count, + shared_ptr const & texture) { /// splitting the whole queue of commands into the chunks no more /// than 64KB of uploadable data each @@ -812,13 +808,13 @@ namespace graphics for (size_t i = 0; i < count; ++i) { - shared_ptr const & style = styles[i]; + shared_ptr const & res = resources[i]; - bytesUploaded += style->m_texRect.SizeX() * style->m_texRect.SizeY() * bytesPerPixel; + bytesUploaded += res->m_texRect.SizeX() * res->m_texRect.SizeY() * bytesPerPixel; if (bytesUploaded > 64 * 1024) { - base_t::uploadStyles(styles + prev, i + 1 - prev, texture); + base_t::uploadResources(resources + prev, i + 1 - prev, texture); if (i + 1 < count) addCheckPoint(); @@ -829,7 +825,7 @@ namespace graphics if (count != 0) { - base_t::uploadStyles(styles, count, texture); + base_t::uploadResources(resources, count, texture); bytesUploaded = 0; } } diff --git a/graphics/geometry_batcher.hpp b/graphics/geometry_batcher.hpp index 77cee2a8f1..3e7614659a 100644 --- a/graphics/geometry_batcher.hpp +++ b/graphics/geometry_batcher.hpp @@ -124,8 +124,6 @@ namespace graphics void clear(Color const & c, bool clearRT = true, float depth = 1.0, bool clearDepth = true); /// @} - void setRenderTarget(shared_ptr const & rt); - void addTexturedFan(m2::PointF const * coords, m2::PointF const * normals, m2::PointF const * texCoords, @@ -214,9 +212,9 @@ namespace graphics void setDisplayList(DisplayList * dl); void drawDisplayList(DisplayList * dl, math::Matrix const & m); - void uploadStyles(shared_ptr const * styles, - size_t count, - shared_ptr const & texture); + void uploadResources(shared_ptr const * resources, + size_t count, + shared_ptr const & texture); void applyStates(); void applyBlitStates(); diff --git a/graphics/glyph.cpp b/graphics/glyph.cpp index fa3d7b9001..ded3cf8225 100644 --- a/graphics/glyph.cpp +++ b/graphics/glyph.cpp @@ -1,4 +1,4 @@ -#include "resource_style.hpp" +#include "glyph.hpp" #include "glyph_cache.hpp" #include "agg_traits.hpp" @@ -6,13 +6,59 @@ namespace graphics { - GlyphStyle::GlyphStyle(m2::RectU const & texRect, int pipelineID, shared_ptr const & gi) - : ResourceStyle(EGlyphStyle, texRect, pipelineID), m_gi(gi) + Glyph::Info::Info() + : Resource::Info(Resource::EGlyph) {} - void GlyphStyle::render(void * dst) + Glyph::Info::Info(GlyphKey const & key, + GlyphCache * cache) + : Resource::Info(Resource::EGlyph), + m_key(key), + m_cache(cache) + { + m_metrics = m_cache->getGlyphMetrics(m_key); + } + + m2::PointU const Glyph::Info::resourceSize() const + { + return m2::PointU(m_metrics.m_width + 4, + m_metrics.m_height + 4); + } + + Resource * Glyph::Info::createResource(m2::RectU const & texRect, + uint8_t pipelineID) const + { + return new Glyph(*this, + texRect, + pipelineID); + } + + bool Glyph::Info::lessThan(Resource::Info const * r) const + { + if (m_category != r->m_category) + return m_category < r->m_category; + + Glyph::Info const * ri = static_cast(r); + + if (m_key != ri->m_key) + return m_key < ri->m_key; + + return false; + } + + Glyph::Glyph(Info const & info, + m2::RectU const & texRect, + int pipelineID) + : Resource(EGlyph, + texRect, + pipelineID), + m_info(info) + { + m_bitmap = m_info.m_cache->getGlyphBitmap(m_info.m_key); + } + + void Glyph::render(void * dst) { - shared_ptr const & gi = m_gi; m2::RectU const & rect = m_texRect; DATA_TRAITS::view_t v = gil::interleaved_view( @@ -22,9 +68,10 @@ namespace graphics ); DATA_TRAITS::pixel_t pxTranslucent; - gil::get_color(pxTranslucent, gil::red_t()) = gi->m_color.r / DATA_TRAITS::channelScaleFactor; - gil::get_color(pxTranslucent, gil::green_t()) = gi->m_color.g / DATA_TRAITS::channelScaleFactor; - gil::get_color(pxTranslucent, gil::blue_t()) = gi->m_color.b / DATA_TRAITS::channelScaleFactor; + + gil::get_color(pxTranslucent, gil::red_t()) = m_info.m_key.m_color.r / DATA_TRAITS::channelScaleFactor; + gil::get_color(pxTranslucent, gil::green_t()) = m_info.m_key.m_color.g / DATA_TRAITS::channelScaleFactor; + gil::get_color(pxTranslucent, gil::blue_t()) = m_info.m_key.m_color.b / DATA_TRAITS::channelScaleFactor; gil::get_color(pxTranslucent, gil::alpha_t()) = 0; for (size_t y = 0; y < 2; ++y) @@ -43,36 +90,35 @@ namespace graphics v(rect.SizeX() - 1, y) = pxTranslucent; } - if ((gi->m_metrics.m_width != 0) && (gi->m_metrics.m_height != 0)) + if ((m_info.m_metrics.m_width != 0) + && (m_info.m_metrics.m_height != 0)) { gil::gray8c_view_t srcView = gil::interleaved_view( - gi->m_metrics.m_width, - gi->m_metrics.m_height, - (gil::gray8_pixel_t*)gi->m_bitmapData, - gi->m_bitmapPitch + m_info.m_metrics.m_width, + m_info.m_metrics.m_height, + (gil::gray8_pixel_t*)&m_bitmap->m_data[0], + m_bitmap->m_pitch ); -/* DATA_TRAITS::const_view_t srcView = gil::interleaved_view( - gi->m_metrics.m_width, - gi->m_metrics.m_height, - (TDynamicTexture::pixel_t*)&gi->m_bitmap[0], - gi->m_metrics.m_width * sizeof(TDynamicTexture::pixel_t) - );*/ - DATA_TRAITS::pixel_t c; - gil::get_color(c, gil::red_t()) = gi->m_color.r / DATA_TRAITS::channelScaleFactor; - gil::get_color(c, gil::green_t()) = gi->m_color.g / DATA_TRAITS::channelScaleFactor; - gil::get_color(c, gil::blue_t()) = gi->m_color.b / DATA_TRAITS::channelScaleFactor; - gil::get_color(c, gil::alpha_t()) = gi->m_color.a / DATA_TRAITS::channelScaleFactor; + gil::get_color(c, gil::red_t()) = m_info.m_key.m_color.r / DATA_TRAITS::channelScaleFactor; + gil::get_color(c, gil::green_t()) = m_info.m_key.m_color.g / DATA_TRAITS::channelScaleFactor; + gil::get_color(c, gil::blue_t()) = m_info.m_key.m_color.b / DATA_TRAITS::channelScaleFactor; + gil::get_color(c, gil::alpha_t()) = m_info.m_key.m_color.a / DATA_TRAITS::channelScaleFactor; for (size_t y = 2; y < rect.SizeY() - 2; ++y) for (size_t x = 2; x < rect.SizeX() - 2; ++x) { gil::get_color(c, gil::alpha_t()) = srcView(x - 2, y - 2) / DATA_TRAITS::channelScaleFactor; v(x, y) = c; - gil::get_color(c, gil::alpha_t()) *= gi->m_color.a / 255.0f; + gil::get_color(c, gil::alpha_t()) *= m_info.m_key.m_color.a / 255.0f; } } } + + Resource::Info const * Glyph::info() const + { + return &m_info; + } } diff --git a/graphics/glyph.hpp b/graphics/glyph.hpp new file mode 100644 index 0000000000..f9882bcbe3 --- /dev/null +++ b/graphics/glyph.hpp @@ -0,0 +1,38 @@ +#pragma once + +#include "resource.hpp" +#include "glyph_cache.hpp" + +namespace graphics +{ + struct Glyph : public Resource + { + struct Info : public Resource::Info + { + GlyphKey m_key; + GlyphMetrics m_metrics; + GlyphCache * m_cache; + + Info(); + Info(GlyphKey const & key, + GlyphCache * cache); + + m2::PointU const resourceSize() const; + Resource * createResource(m2::RectU const & texRect, + uint8_t pipelineID) const; + + bool lessThan(Resource::Info const * r) const; + }; + + Info m_info; + + shared_ptr m_bitmap; + + Glyph(Info const & info, + m2::RectU const & texRect, + int pipelineID); + + void render(void * dst); + Resource::Info const * info() const; + }; +} diff --git a/graphics/glyph_cache.cpp b/graphics/glyph_cache.cpp index aa7df2aa4d..547829a936 100644 --- a/graphics/glyph_cache.cpp +++ b/graphics/glyph_cache.cpp @@ -24,8 +24,21 @@ namespace gil = boost::gil; namespace graphics { - GlyphKey::GlyphKey(strings::UniChar symbolCode, int fontSize, bool isMask, graphics::Color const & color) - : m_symbolCode(symbolCode), m_fontSize(fontSize), m_isMask(isMask), m_color(color) + GlyphKey::GlyphKey(strings::UniChar symbolCode, + int fontSize, + bool isMask, + Color const & color) + : m_symbolCode(symbolCode), + m_fontSize(fontSize), + m_isMask(isMask), + m_color(color) + {} + + GlyphKey::GlyphKey() + : m_symbolCode(0), + m_fontSize(), + m_isMask(), + m_color() {} uint32_t GlyphKey::toUInt32() const @@ -46,29 +59,14 @@ namespace graphics return l.m_color < r.m_color; } - GlyphInfo::GlyphInfo() + bool operator!=(GlyphKey const & l, GlyphKey const & r) { + return (l.m_symbolCode != r.m_symbolCode) + || (l.m_fontSize != r.m_fontSize) + || (l.m_isMask != r.m_isMask) + || (l.m_color != r.m_color); } - GlyphInfo::~GlyphInfo() - { - } - - struct FTGlyphInfo : public GlyphInfo - { - FTC_Node m_node; - FTC_Manager m_manager; - - FTGlyphInfo(FTC_Node node, FTC_Manager manager) - : m_node(node), m_manager(manager) - {} - - ~FTGlyphInfo() - { - FTC_Node_Unref(m_node, m_manager); - } - }; - GlyphCache::Params::Params(string const & blocksFile, string const & whiteListFile, string const & blackListFile, size_t maxSize, bool isDebugging) : m_blocksFile(blocksFile), m_whiteListFile(whiteListFile), m_blackListFile(blackListFile), m_maxSize(maxSize), m_isDebugging(isDebugging) {} @@ -100,9 +98,9 @@ namespace graphics return m_impl->getGlyphMetrics(key); } - shared_ptr const GlyphCache::getGlyphInfo(GlyphKey const & key) + shared_ptr const GlyphCache::getGlyphBitmap(GlyphKey const & key) { - return m_impl->getGlyphInfo(key); + return m_impl->getGlyphBitmap(key); } double GlyphCache::getTextLength(double fontSize, string const & text) diff --git a/graphics/glyph_cache.hpp b/graphics/glyph_cache.hpp index d18f3e340a..87235a3517 100644 --- a/graphics/glyph_cache.hpp +++ b/graphics/glyph_cache.hpp @@ -22,26 +22,12 @@ namespace graphics int m_height; }; - /// full info about single glyph - struct GlyphInfo + struct GlyphBitmap { - private: - - /// copying is prohibited - GlyphInfo(GlyphInfo const &); - GlyphInfo & operator=(GlyphInfo const &); - - public: - - GlyphMetrics m_metrics; - graphics::Color m_color; - - /// glyph bitmap in 8bpp grayscale format - unsigned char * m_bitmapData; - int m_bitmapPitch; - - GlyphInfo(); - virtual ~GlyphInfo(); + unsigned m_width; + unsigned m_height; + unsigned m_pitch; + vector m_data; }; struct GlyphKey @@ -53,12 +39,17 @@ namespace graphics /// as it's used for fixed fonts only, the color doesn't matter /// @TODO REMOVE IT!!! All chars are already 32bit uint32_t toUInt32() const; - GlyphKey(strings::UniChar symbolCode, int fontSize, bool isMask, graphics::Color const & color); + GlyphKey(strings::UniChar symbolCode, + int fontSize, + bool isMask, + Color const & color); + GlyphKey(); }; struct Font; bool operator<(GlyphKey const & l, GlyphKey const & r); + bool operator!=(GlyphKey const & l, GlyphKey const & r); struct GlyphCacheImpl; @@ -93,7 +84,7 @@ namespace graphics pair getCharIDX(GlyphKey const & key); - shared_ptr const getGlyphInfo(GlyphKey const & key); + shared_ptr const getGlyphBitmap(GlyphKey const & key); /// return control box(could be slightly larger than the precise bound box). GlyphMetrics const getGlyphMetrics(GlyphKey const & key); diff --git a/graphics/glyph_cache_impl.cpp b/graphics/glyph_cache_impl.cpp index 81921fc188..98a3dc0e2a 100644 --- a/graphics/glyph_cache_impl.cpp +++ b/graphics/glyph_cache_impl.cpp @@ -12,14 +12,6 @@ namespace graphics { - struct RawGlyphInfo : public GlyphInfo - { - ~RawGlyphInfo() - { - delete m_bitmapData; - } - }; - UnicodeBlock::UnicodeBlock(string const & name, strings::UniChar start, strings::UniChar end) : m_name(name), m_start(start), m_end(end) {} @@ -425,11 +417,16 @@ namespace graphics FTCHECK(FTC_ImageCache_New(m_manager, &m_normalGlyphCache)); FTCHECK(FTC_StrokedImageCache_New(m_manager, &m_strokedGlyphCache)); - FTCHECK(FTC_ImageCache_New(m_manager, &m_glyphMetricsCache)); + + FTCHECK(FTC_ImageCache_New(m_manager, &m_normalMetricsCache)); + FTCHECK(FTC_StrokedImageCache_New(m_manager, &m_strokedMetricsCache)); /// Initializing stroker - FTCHECK(FT_Stroker_New(m_lib, &m_stroker)); - FT_Stroker_Set(m_stroker, 2 * 64, FT_STROKER_LINECAP_ROUND, FT_STROKER_LINEJOIN_ROUND, 0); + FTCHECK(FT_Stroker_New(m_lib, &m_metricsStroker)); + FT_Stroker_Set(m_metricsStroker, 2 * 64, FT_STROKER_LINECAP_ROUND, FT_STROKER_LINEJOIN_ROUND, 0); + + FTCHECK(FT_Stroker_New(m_lib, &m_glyphStroker)); + FT_Stroker_Set(m_glyphStroker, 2 * 64, FT_STROKER_LINECAP_ROUND, FT_STROKER_LINEJOIN_ROUND, 0); FTCHECK(FTC_CMapCache_New(m_manager, &m_charMapCache)); } @@ -444,7 +441,8 @@ namespace graphics if (!m_isDebugging) { FTC_Manager_Done(m_manager); - FT_Stroker_Done(m_stroker); + FT_Stroker_Done(m_metricsStroker); + FT_Stroker_Done(m_glyphStroker); FT_Done_FreeType(m_lib); } } @@ -508,18 +506,6 @@ namespace graphics GlyphMetrics const GlyphCacheImpl::getGlyphMetrics(GlyphKey const & key) { - if (m_isDebugging) - { - GlyphMetrics m = - { - 10, - 0, - 0, 0, - 10, 20 - }; - return m; - } - pair charIDX = getCharIDX(key); FTC_ScalerRec fontScaler = @@ -534,13 +520,27 @@ namespace graphics FT_Glyph glyph = 0; - FTCHECK(FTC_ImageCache_LookupScaler( - m_glyphMetricsCache, - &fontScaler, - FT_LOAD_DEFAULT, - charIDX.second, - &glyph, - 0)); + if (key.m_isMask) + { + FTCHECK(FTC_StrokedImageCache_LookupScaler( + m_strokedMetricsCache, + &fontScaler, + m_metricsStroker, + FT_LOAD_DEFAULT, + charIDX.second, + &glyph, + 0)); + } + else + { + FTCHECK(FTC_ImageCache_LookupScaler( + m_normalMetricsCache, + &fontScaler, + FT_LOAD_DEFAULT, + charIDX.second, + &glyph, + 0)); + } FT_BBox cbox; FT_Glyph_Get_CBox(glyph, FT_GLYPH_BBOX_PIXELS, &cbox); @@ -556,29 +556,8 @@ namespace graphics return m; } - shared_ptr const GlyphCacheImpl::getGlyphInfo(GlyphKey const & key) + shared_ptr const GlyphCacheImpl::getGlyphBitmap(GlyphKey const & key) { - if (m_isDebugging) - { - static bool hasFakeSymbol = false; - static shared_ptr fakeSymbol; - - if (!hasFakeSymbol) - { - fakeSymbol.reset(new RawGlyphInfo()); - fakeSymbol->m_metrics = getGlyphMetrics(key); - fakeSymbol->m_color = graphics::Color(0, 0, 255, 255); - fakeSymbol->m_bitmapPitch = (fakeSymbol->m_metrics.m_width + 7) / 8 * 8; - fakeSymbol->m_bitmapData = new unsigned char[fakeSymbol->m_bitmapPitch * fakeSymbol->m_metrics.m_height]; - for (unsigned i = 0; i < fakeSymbol->m_bitmapPitch * fakeSymbol->m_metrics.m_height; ++i) - fakeSymbol->m_bitmapData[i] = 0xFF; - - hasFakeSymbol = true; - } - - return fakeSymbol; - } - pair charIDX = getCharIDX(key); FTC_ScalerRec fontScaler = @@ -594,21 +573,17 @@ namespace graphics FT_Glyph glyph = 0; FTC_Node node; - GlyphInfo * info = 0; - if (key.m_isMask) { FTCHECK(FTC_StrokedImageCache_LookupScaler( m_strokedGlyphCache, &fontScaler, - m_stroker, + m_glyphStroker, FT_LOAD_DEFAULT, charIDX.second, &glyph, &node )); - -// info = new FTGlyphInfo(node, m_manager); } else { @@ -620,39 +595,27 @@ namespace graphics &glyph, &node )); - -// info = new FTGlyphInfo(node, m_manager); } - info = new RawGlyphInfo(); + GlyphBitmap * bitmap = new GlyphBitmap(); FT_BitmapGlyph bitmapGlyph = (FT_BitmapGlyph)glyph; - info->m_metrics.m_height = bitmapGlyph ? bitmapGlyph->bitmap.rows : 0; - info->m_metrics.m_width = bitmapGlyph ? bitmapGlyph->bitmap.width : 0; - info->m_metrics.m_xOffset = bitmapGlyph ? bitmapGlyph->left : 0; - info->m_metrics.m_yOffset = bitmapGlyph ? bitmapGlyph->top - info->m_metrics.m_height : 0; - info->m_metrics.m_xAdvance = bitmapGlyph ? int(bitmapGlyph->root.advance.x >> 16) : 0; - info->m_metrics.m_yAdvance = bitmapGlyph ? int(bitmapGlyph->root.advance.y >> 16) : 0; - info->m_color = key.m_color; + bitmap->m_width = bitmapGlyph ? bitmapGlyph->bitmap.width : 0; + bitmap->m_height = bitmapGlyph ? bitmapGlyph->bitmap.rows : 0; + bitmap->m_pitch = bitmapGlyph ? bitmapGlyph->bitmap.pitch : 0; - info->m_bitmapData = 0; - info->m_bitmapPitch = 0; - - if ((info->m_metrics.m_width != 0) && (info->m_metrics.m_height != 0)) + if (bitmap->m_width * bitmap->m_height != 0) { -// info->m_bitmapData = bitmapGlyph->bitmap.buffer; -// info->m_bitmapPitch = bitmapGlyph->bitmap.pitch; - - info->m_bitmapPitch = bitmapGlyph->bitmap.pitch; - info->m_bitmapData = new unsigned char[info->m_bitmapPitch * info->m_metrics.m_height]; - - memcpy(info->m_bitmapData, bitmapGlyph->bitmap.buffer, info->m_bitmapPitch * info->m_metrics.m_height); + bitmap->m_data.resize(bitmap->m_pitch * bitmap->m_height); + memcpy(&bitmap->m_data[0], + bitmapGlyph->bitmap.buffer, + bitmap->m_pitch * bitmap->m_height); } FTC_Node_Unref(node, m_manager); - return make_shared_ptr(info); + return make_shared_ptr(bitmap); } FT_Error GlyphCacheImpl::RequestFace(FTC_FaceID faceID, FT_Library library, FT_Pointer /*requestData*/, FT_Face * face) diff --git a/graphics/glyph_cache_impl.hpp b/graphics/glyph_cache_impl.hpp index fa8bab6e35..938e95929b 100644 --- a/graphics/glyph_cache_impl.hpp +++ b/graphics/glyph_cache_impl.hpp @@ -56,11 +56,14 @@ namespace graphics struct GlyphCacheImpl { FT_Library m_lib; - FT_Stroker m_stroker; //< stroker, used to produce stroked glyph outlines + FT_Stroker m_glyphStroker; //< stroker, used to produce stroked glyph outlines + FT_Stroker m_metricsStroker; FTC_Manager m_manager; //< freetype cache manager for all caches - FTC_ImageCache m_glyphMetricsCache; //< glyph metrics cache + FTC_ImageCache m_normalMetricsCache; //< cache of normal glyph metrics + FTC_ImageCache m_strokedMetricsCache; //< cache of stroked glyph metrics + FTC_ImageCache m_normalGlyphCache; //< cache of normal glyph images FTC_ImageCache m_strokedGlyphCache; //< cache of stroked glyph images @@ -86,7 +89,7 @@ namespace graphics int getCharIDX(shared_ptr const & font, strings::UniChar symbolCode); pair const getCharIDX(GlyphKey const & key); GlyphMetrics const getGlyphMetrics(GlyphKey const & key); - shared_ptr const getGlyphInfo(GlyphKey const & key); + shared_ptr const getGlyphBitmap(GlyphKey const & key); GlyphCacheImpl(GlyphCache::Params const & params); ~GlyphCacheImpl(); diff --git a/graphics/glyph_layout.cpp b/graphics/glyph_layout.cpp index 4f727a79d1..1f2b263d20 100644 --- a/graphics/glyph_layout.cpp +++ b/graphics/glyph_layout.cpp @@ -1,6 +1,6 @@ #include "glyph_layout.hpp" #include "font_desc.hpp" -#include "resource_style.hpp" +#include "resource.hpp" #include "../base/logging.hpp" #include "../base/math.hpp" diff --git a/graphics/graphics.pro b/graphics/graphics.pro index da1f9fc9aa..bebb20c842 100644 --- a/graphics/graphics.pro +++ b/graphics/graphics.pro @@ -57,9 +57,7 @@ SOURCES += \ composite_overlay_element.cpp \ path_text_element.cpp \ straight_text_element.cpp \ - line_style.cpp \ - circle_style.cpp \ - glyph_style.cpp \ + glyph.cpp \ circle_element.cpp \ packets_queue.cpp \ display_list.cpp \ @@ -72,6 +70,8 @@ SOURCES += \ coordinates.cpp \ render_target.cpp \ defines.cpp + icon.cpp \ + brush.cpp HEADERS += \ opengl/opengl.hpp \ @@ -135,6 +135,9 @@ HEADERS += \ vertex_decl.hpp \ render_context.hpp \ coordinates.hpp \ + icon.hpp \ + glyph.hpp \ + brush.hpp win32* { SOURCES += opengl/opengl_win32.cpp diff --git a/graphics/graphics_tests/glyph_cache_test.cpp b/graphics/graphics_tests/glyph_cache_test.cpp index c4e2cf4a62..91d3814555 100644 --- a/graphics/graphics_tests/glyph_cache_test.cpp +++ b/graphics/graphics_tests/glyph_cache_test.cpp @@ -15,8 +15,8 @@ UNIT_TEST(GlyphCacheTest_Main) string const path = GetPlatform().WritableDir(); cache.addFont((path + "01_dejavusans.ttf").c_str()); - shared_ptr g1 = cache.getGlyphInfo(graphics::GlyphKey('#', 40, true, graphics::Color(255, 255, 255, 255))); + shared_ptr g1 = cache.getGlyphBitmap(graphics::GlyphKey('#', 40, true, graphics::Color(255, 255, 255, 255))); //g1->dump(GetPlatform().WritablePathForFile("#_mask.png").c_str()); - shared_ptr g2 = cache.getGlyphInfo(graphics::GlyphKey('#', 40, false, graphics::Color(0, 0, 0, 0))); + shared_ptr g2 = cache.getGlyphBitmap(graphics::GlyphKey('#', 40, false, graphics::Color(0, 0, 0, 0))); //g2->dump(GetPlatform().WritablePathForFile("#.png").c_str()); } diff --git a/graphics/graphics_tests/screengl_test.cpp b/graphics/graphics_tests/screengl_test.cpp index 44473d53aa..7b2806e21c 100644 --- a/graphics/graphics_tests/screengl_test.cpp +++ b/graphics/graphics_tests/screengl_test.cpp @@ -5,8 +5,9 @@ #include "../../graphics/screen.hpp" #include "../../graphics/skin.hpp" -#include "../../graphics/pen_info.hpp" -#include "../../graphics/circle_info.hpp" +#include "../../graphics/pen.hpp" +#include "../../graphics/circle.hpp" +#include "../../graphics/brush.hpp" #include "../../graphics/text_element.hpp" #include "../../graphics/straight_text_element.hpp" #include "../../graphics/path_text_element.hpp" @@ -56,7 +57,7 @@ namespace // double pat [] = {7, 7, 10, 10}; double pat1 [] = {1, 1}; - p->drawPath(pts, 3, 0, p->skin()->mapPenInfo(graphics::PenInfo(graphics::Color(0xFF, 0xFF, 0xFF, 0xFF), 2, pat1, 2, 0)), 0); + p->drawPath(pts, 3, 0, p->skin()->map(graphics::Pen::Info(graphics::Color(0xFF, 0xFF, 0xFF, 0xFF), 2, pat1, 2, 0)), 0); } }; @@ -65,11 +66,11 @@ namespace std::vector > m_pathes; std::vector m_pathOffsets; //std::vector > m_patterns; - std::vector m_penInfos; + std::vector m_penInfos; std::vector m_depthes; std::vector m_axisPattern; - graphics::PenInfo m_axisPenInfo; + graphics::Pen::Info m_axisPenInfo; bool m_drawAxis; void Init() @@ -78,7 +79,7 @@ namespace m_axisPattern.push_back(2); m_axisPattern.push_back(2); - m_axisPenInfo = graphics::PenInfo(graphics::Color(0xFF, 0, 0, 0xFF), 2, &m_axisPattern[0], m_axisPattern.size(), 0); + m_axisPenInfo = graphics::Pen::Info(graphics::Color(0xFF, 0, 0, 0xFF), 2, &m_axisPattern[0], m_axisPattern.size(), 0); } void AddTest(std::vector const & points, @@ -92,7 +93,7 @@ namespace m_pathes.push_back(points); m_pathOffsets.push_back(pathOffset); //m_patterns.push_back(pattern); - m_penInfos.push_back(graphics::PenInfo(color, width, pattern.empty() ? 0 : &pattern[0], pattern.size(), penOffset)); + m_penInfos.push_back(graphics::Pen::Info(color, width, pattern.empty() ? 0 : &pattern[0], pattern.size(), penOffset)); m_depthes.push_back(depth); } @@ -105,9 +106,9 @@ namespace { for (size_t i = 0; i < m_pathes.size(); ++i) { - p->drawPath(&m_pathes[i][0], m_pathes[i].size(), m_pathOffsets[i], p->skin()->mapPenInfo(m_penInfos[i]), m_depthes[i]); + p->drawPath(&m_pathes[i][0], m_pathes[i].size(), m_pathOffsets[i], p->skin()->map(m_penInfos[i]), m_depthes[i]); if (m_drawAxis) - p->drawPath(&m_pathes[i][0], m_pathes[i].size(), 0, p->skin()->mapPenInfo(m_axisPenInfo), m_depthes[i]); + p->drawPath(&m_pathes[i][0], m_pathes[i].size(), 0, p->skin()->map(m_axisPenInfo), m_depthes[i]); } } @@ -568,7 +569,7 @@ namespace // p->drawTriangles(ptsFan, 5, graphics::TriangleFan, p->skin()->mapColor(graphics::Color(0, 255, 0, 255))); m2::PointD ptsList[6] = {m2::PointD(20, 80), m2::PointD(50, 120), m2::PointD(80, 80), m2::PointD(110, 80), m2::PointD(140, 120), m2::PointD(80, 120)}; - p->drawTrianglesList(ptsList, 6, /*graphics::TriangleList, */p->skin()->mapColor(graphics::Color(0, 0, 255, 255)), 0); + p->drawTrianglesList(ptsList, 6, /*graphics::TriangleList, */p->skin()->map(graphics::Brush::Info(graphics::Color(0, 0, 255, 255))), 0); } }; @@ -604,7 +605,7 @@ namespace p->drawTrianglesList(&vertices[0], vertices.size(), - p->skin()->mapColor(graphics::Color(0, 0, 255, 255)), 0); + p->skin()->map(graphics::Brush::Info(graphics::Color(0, 0, 255, 255))), 0); } }; @@ -614,7 +615,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), 0, p->skin()->mapPenInfo(graphics::PenInfo(graphics::Color(0, 0, 0, 0xFF), 2, pat, 2, 0)), 0); + p->drawPath(path, sizeof(path) / sizeof(m2::PointD), 0, p->skin()->map(graphics::Pen::Info(graphics::Color(0, 0, 0, 0xFF), 2, pat, 2, 0)), 0); graphics::FontDesc fontDesc(20, graphics::Color(0, 0, 0, 0), true, graphics::Color(255, 255, 255, 255)); @@ -669,13 +670,13 @@ namespace path.push_back(m2::PointD(70, 50)); double pat[] = { 2, 2 }; - graphics::PenInfo penInfo = graphics::PenInfo(graphics::Color(0, 0, 0, 0xFF), 2, &pat[0], ARRAY_SIZE(pat), 0); - graphics::PenInfo solidPenInfo = graphics::PenInfo(graphics::Color(0xFF, 0, 0, 0xFF), 4, 0, 0, 0); + graphics::Pen::Info penInfo = graphics::Pen::Info(graphics::Color(0, 0, 0, 0xFF), 2, &pat[0], ARRAY_SIZE(pat), 0); + graphics::Pen::Info solidPenInfo = graphics::Pen::Info(graphics::Color(0xFF, 0, 0, 0xFF), 4, 0, 0, 0); graphics::FontDesc fontDesc(20, graphics::Color(0, 0, 0, 0), true, graphics::Color(255, 255, 255, 255)); p->drawText(fontDesc, m2::PointD(40, 50), graphics::EPosAboveRight, "S", 0, true); - p->drawPath(&path[0], path.size(), 0, p->skin()->mapPenInfo(solidPenInfo), 0); + p->drawPath(&path[0], path.size(), 0, p->skin()->map(solidPenInfo), 0); } }; @@ -799,7 +800,7 @@ namespace { vector m_path; string m_text; - graphics::PenInfo m_penInfo; + graphics::Pen::Info m_penInfo; void Init() { @@ -810,12 +811,12 @@ namespace m_text = "Syp"; double pat[2] = {2, 2}; - m_penInfo = graphics::PenInfo(graphics::Color(0xFF, 0xFF, 0xFF, 0xFF), 2, &pat[0], ARRAY_SIZE(pat), 0); + m_penInfo = graphics::Pen::Info(graphics::Color(0xFF, 0xFF, 0xFF, 0xFF), 2, &pat[0], ARRAY_SIZE(pat), 0); } void DoDraw(shared_ptr p) { - p->drawPath(&m_path[0], m_path.size(), 0, p->skin()->mapPenInfo(m_penInfo), 1); + p->drawPath(&m_path[0], m_path.size(), 0, p->skin()->map(m_penInfo), 1); graphics::FontDesc fontDesc(30); p->drawPathText(fontDesc, &m_path[0], m_path.size(), m_text, calc_length(m_path), 0.0, graphics::EPosLeft, 0); @@ -862,7 +863,7 @@ namespace void DoDraw(shared_ptr p) { - p->drawPath(&m_testPoints[0], m_testPoints.size(), 0, p->skin()->mapPenInfo(graphics::PenInfo(graphics::Color(255, 255, 255, 255), 2, 0, 0, 0)), 0); + p->drawPath(&m_testPoints[0], m_testPoints.size(), 0, p->skin()->map(graphics::Pen::Info(graphics::Color(255, 255, 255, 255), 2, 0, 0, 0)), 0); graphics::FontDesc fontDesc(20, graphics::Color(0, 0, 0, 255), false); //m_text = "Simplicity is the ultimate sophistication. Leonardo Da Vinci."; m_text = "Vinci"; @@ -874,7 +875,7 @@ namespace { std::vector m_path; std::string m_text; - graphics::PenInfo m_penInfo; + graphics::Pen::Info m_penInfo; TestDrawTextOnPath() { @@ -886,12 +887,12 @@ namespace m_text = "Simplicity is the ultimate sophistication. Leonardo Da Vinci."; double pat[] = { 2, 2 }; - m_penInfo = graphics::PenInfo(graphics::Color(0, 0, 0, 0xFF), 2, &pat[0], ARRAY_SIZE(pat), 0); + m_penInfo = graphics::Pen::Info(graphics::Color(0, 0, 0, 0xFF), 2, &pat[0], ARRAY_SIZE(pat), 0); } void DoDraw(shared_ptr p) { - p->drawPath(&m_path[0], m_path.size(), 0, p->skin()->mapPenInfo(m_penInfo), 0); + p->drawPath(&m_path[0], m_path.size(), 0, p->skin()->map(m_penInfo), 0); graphics::FontDesc fontDesc(20); p->drawPathText(fontDesc, &m_path[0], m_path.size(), m_text, calc_length(m_path), 0.0, graphics::EPosCenter, 0); } @@ -899,14 +900,14 @@ namespace struct TestDrawStraightTextElement { - graphics::PenInfo m_penInfo; + graphics::Pen::Info m_penInfo; vector m_path; TestDrawStraightTextElement() { m_path.push_back(m2::PointD(100, 200)); m_path.push_back(m2::PointD(500, 200)); double pat[] = { 2, 2 }; - m_penInfo = graphics::PenInfo(graphics::Color(0, 0, 0, 0xFF), 2, &pat[0], ARRAY_SIZE(pat), 0); + m_penInfo = graphics::Pen::Info(graphics::Color(0, 0, 0, 0xFF), 2, &pat[0], ARRAY_SIZE(pat), 0); } void DoDraw(shared_ptr p) @@ -922,7 +923,7 @@ namespace graphics::StraightTextElement ste(params); - p->drawPath(&m_path[0], m_path.size(), 0, p->skin()->mapPenInfo(m_penInfo), 0); + p->drawPath(&m_path[0], m_path.size(), 0, p->skin()->map(m_penInfo), 0); ste.draw(p.get(), math::Identity()); } }; @@ -930,7 +931,7 @@ namespace struct TestDrawPathTextElement { vector m_path; - graphics::PenInfo m_penInfo; + graphics::Pen::Info m_penInfo; TestDrawPathTextElement() { @@ -945,7 +946,7 @@ namespace m_path.push_back(m2::PointD(400, 200)); double pat[] = { 2, 2 }; - m_penInfo = graphics::PenInfo(graphics::Color(0, 0, 0, 0xFF), 2, &pat[0], ARRAY_SIZE(pat), 0); + m_penInfo = graphics::Pen::Info(graphics::Color(0, 0, 0, 0xFF), 2, &pat[0], ARRAY_SIZE(pat), 0); } void DoDraw(shared_ptr p) @@ -965,7 +966,7 @@ namespace graphics::PathTextElement pte(params); - p->drawPath(&m_path[0], m_path.size(), 0, p->skin()->mapPenInfo(m_penInfo), 0); + p->drawPath(&m_path[0], m_path.size(), 0, p->skin()->map(m_penInfo), 0); pte.draw(p.get(), math::Identity()); } }; @@ -974,7 +975,7 @@ namespace { std::vector m_path; std::string m_text; - graphics::PenInfo m_penInfo; + graphics::Pen::Info m_penInfo; TestDrawTextOnPathZigZag() { @@ -990,12 +991,12 @@ namespace m_text = "Simplicity is the ultimate sophistication. Leonardo Da Vinci."; double pat[] = { 2, 2 }; - m_penInfo = graphics::PenInfo(graphics::Color(0, 0, 0, 0xFF), 2, &pat[0], ARRAY_SIZE(pat), 0); + m_penInfo = graphics::Pen::Info(graphics::Color(0, 0, 0, 0xFF), 2, &pat[0], ARRAY_SIZE(pat), 0); } void DoDraw(shared_ptr p) { - p->drawPath(&m_path[0], m_path.size(), 0, p->skin()->mapPenInfo(m_penInfo), 0); + p->drawPath(&m_path[0], m_path.size(), 0, p->skin()->map(m_penInfo), 0); // graphics::FontDesc fontDesc(false, 10); graphics::FontDesc fontDesc(20); p->drawPathText(fontDesc, &m_path[0], m_path.size(), m_text, calc_length(m_path), 0.0, graphics::EPosCenter, 0); @@ -1022,8 +1023,8 @@ namespace { TestDrawTextOnPath::DoDraw(p); - p->drawPath(&m_pathAbove[0], m_pathAbove.size(), 0, p->skin()->mapPenInfo(m_penInfo), 0); - p->drawPath(&m_pathUnder[0], m_pathUnder.size(), 0, p->skin()->mapPenInfo(m_penInfo), 0); + p->drawPath(&m_pathAbove[0], m_pathAbove.size(), 0, p->skin()->map(m_penInfo), 0); + p->drawPath(&m_pathUnder[0], m_pathUnder.size(), 0, p->skin()->map(m_penInfo), 0); double const len = calc_length(m_path); graphics::FontDesc fontDesc(20); @@ -1212,25 +1213,25 @@ namespace void DoDraw(shared_ptr p) { double inputDataPat[] = {10, 0}; - graphics::PenInfo inputDataRule(graphics::Color::fromARGB(0xFF000000), 6, inputDataPat, 2, 0); + graphics::Pen::Info inputDataRule(graphics::Color::fromARGB(0xFF000000), 6, inputDataPat, 2, 0); double triangleFanPat[] = {10, 10}; - graphics::PenInfo triangleFanRule(graphics::Color::fromARGB(0xFFFF0000), 5, triangleFanPat, 2, 0); + graphics::Pen::Info triangleFanRule(graphics::Color::fromARGB(0xFFFF0000), 5, triangleFanPat, 2, 0); double triangleStripPat[] = {10, 10}; - graphics::PenInfo triangleStripRule(graphics::Color::fromARGB(0xFF00FF00), 4, triangleStripPat, 2, 0); + graphics::Pen::Info triangleStripRule(graphics::Color::fromARGB(0xFF00FF00), 4, triangleStripPat, 2, 0); double triangleListPat[] = {10, 10}; - graphics::PenInfo triangleListRule(graphics::Color::fromARGB(0xFF0000FF), 3, triangleListPat, 2, 0); + graphics::Pen::Info triangleListRule(graphics::Color::fromARGB(0xFF0000FF), 3, triangleListPat, 2, 0); double lineLoopPat[] = {2, 2}; - graphics::PenInfo lineLoopRule(graphics::Color::fromARGB(0xFF00FFFF), 2, lineLoopPat, 2, 0); + graphics::Pen::Info lineLoopRule(graphics::Color::fromARGB(0xFF00FFFF), 2, lineLoopPat, 2, 0); - uint32_t inputDataID = p->skin()->mapPenInfo(inputDataRule); - uint32_t triangleFanID = p->skin()->mapPenInfo(triangleFanRule); - /*uint32_t triangleStripID = */p->skin()->mapPenInfo(triangleStripRule); - uint32_t triangleListID = p->skin()->mapPenInfo(triangleListRule); - uint32_t lineLoopID = p->skin()->mapPenInfo(lineLoopRule); + uint32_t inputDataID = p->skin()->map(inputDataRule); + uint32_t triangleFanID = p->skin()->map(triangleFanRule); + /*uint32_t triangleStripID = */p->skin()->map(triangleStripRule); + uint32_t triangleListID = p->skin()->map(triangleListRule); + uint32_t lineLoopID = p->skin()->map(lineLoopRule); p->drawPath((m2::PointD const *)&m_vertices[0], m_vertices.size(), 0, inputDataID, 0); @@ -1328,10 +1329,10 @@ namespace { void DoDraw(shared_ptr const & p) { - graphics::CircleInfo ci0(10, graphics::Color(255, 0, 0, 255)); + graphics::Circle::Info ci0(10, graphics::Color(255, 0, 0, 255)); p->drawCircle(m2::PointD(200, 200), ci0, graphics::EPosCenter, 100); - graphics::CircleInfo ci1(10, graphics::Color(255, 0, 0, 255), true, 4, graphics::Color(255, 255, 255, 255)); + graphics::Circle::Info ci1(10, graphics::Color(255, 0, 0, 255), true, 4, graphics::Color(255, 255, 255, 255)); p->drawCircle(m2::PointD(100, 200), ci1, graphics::EPosCenter, 100); } }; @@ -1340,7 +1341,7 @@ namespace { void DoDraw(shared_ptr const & p) { - graphics::ImageInfo ii("test.png"); + graphics::Image::Info ii("test.png"); math::Matrix m = math::Shift( @@ -1350,7 +1351,7 @@ namespace 100, 100); p->drawImage(m, - p->skin()->mapImageInfo(ii), + p->skin()->map(ii), graphics::maxDepth); } }; diff --git a/graphics/graphics_tests/screenglglobal_test.cpp b/graphics/graphics_tests/screenglglobal_test.cpp index 1f0506f9d2..3e6d1d3aad 100644 --- a/graphics/graphics_tests/screenglglobal_test.cpp +++ b/graphics/graphics_tests/screenglglobal_test.cpp @@ -1,7 +1,7 @@ #include "../../base/SRC_FIRST.hpp" #include "../../graphics/screen.hpp" #include "../../graphics/skin.hpp" -#include "../../graphics/pen_info.hpp" +#include "../../graphics/pen.hpp" #include "../../geometry/screenbase.hpp" #include "../../geometry/point2d.hpp" #include "../../std/vector.hpp" @@ -45,7 +45,7 @@ namespace toPixel(pts); - p->drawPath(&pts[0], pts.size(), 0, p->skin()->mapPenInfo(graphics::PenInfo(graphics::Color(255, 0, 0, 255), 2, 0, 0, 0)), 0); + p->drawPath(&pts[0], pts.size(), 0, p->skin()->map(graphics::Pen::Info(graphics::Color(255, 0, 0, 255), 2, 0, 0, 0)), 0); } }; diff --git a/graphics/graphics_tests/skin_test.cpp b/graphics/graphics_tests/skin_test.cpp index 64656f28a8..bceb560b2d 100644 --- a/graphics/graphics_tests/skin_test.cpp +++ b/graphics/graphics_tests/skin_test.cpp @@ -2,7 +2,7 @@ #include "../../qt_tstfrm/macros.hpp" #include "../skin.hpp" #include "../resource_manager.hpp" -#include "../pen_info.hpp" +#include "../pen.hpp" #include "../../std/vector.hpp" #include "../../platform/platform.hpp" diff --git a/graphics/icon.cpp b/graphics/icon.cpp new file mode 100644 index 0000000000..eccbc48e09 --- /dev/null +++ b/graphics/icon.cpp @@ -0,0 +1,55 @@ +#include "icon.hpp" + +namespace graphics +{ + Icon::Info::Info() + : Resource::Info(Resource::EIcon) + {} + + Icon::Info::Info(string const & name) + : Resource::Info(Resource::EIcon), + m_name(name) + {} + + m2::PointU const Icon::Info::resourceSize() const + { + return m2::PointU(0, 0); + } + + Resource * Icon::Info::createResource(m2::RectU const & texRect, + uint8_t pipelineID) const + { + return 0; + } + + bool Icon::Info::lessThan(Resource::Info const * i) const + { + if (m_category != i->m_category) + return m_category < i->m_category; + + Icon::Info const * ii = static_cast(i); + + if (m_name != ii->m_name) + return m_name < ii->m_name; + + return false; + } + + + Icon::Icon(m2::RectU const & texRect, + int pipelineID, + Info const & info) + : Resource(EIcon, + texRect, + pipelineID), + m_info(info) + {} + + void Icon::render(void *) + {} + + Resource::Info const * Icon::info() const + { + return &m_info; + } +} diff --git a/graphics/icon.hpp b/graphics/icon.hpp new file mode 100644 index 0000000000..ef2024e65f --- /dev/null +++ b/graphics/icon.hpp @@ -0,0 +1,33 @@ +#pragma once + +#include "../std/string.hpp" + +#include "resource.hpp" + +namespace graphics +{ + struct Icon : public Resource + { + struct Info : public Resource::Info + { + string m_name; + + Info(); + Info(string const & name); + + m2::PointU const resourceSize() const; + Resource * createResource(m2::RectU const & texRect, + uint8_t pipelineID) const; + bool lessThan(Resource::Info const * r) const; + }; + + Info m_info; + + Icon(m2::RectU const & texRect, + int pipelineID, + Info const & info); + + void render(void * dst); + Resource::Info const * info() const; + }; +} diff --git a/graphics/image.cpp b/graphics/image.cpp index a972e54d50..5d505ba697 100644 --- a/graphics/image.cpp +++ b/graphics/image.cpp @@ -1,4 +1,4 @@ -#include "image_info.hpp" +#include "image.hpp" #include "opengl/data_traits.hpp" @@ -17,7 +17,12 @@ namespace graphics return m2::PointU(size.x, size.y); } - ImageInfo::ImageInfo(char const * resourceName) + Image::Info::Info() + : Resource::Info(Resource::EImage) + {} + + Image::Info::Info(char const * resourceName) + : Resource::Info(Resource::EImage) { m_size = GetDimensions(resourceName); m_data.resize(m_size.x * m_size.y * sizeof(DATA_TRAITS::pixel_t)); @@ -32,23 +37,92 @@ namespace graphics gil::lodepng_read_and_convert_view(reader, v, DATA_TRAITS::color_converter()); } - unsigned ImageInfo::width() const + unsigned Image::Info::width() const { return m_size.x; } - unsigned ImageInfo::height() const + unsigned Image::Info::height() const { return m_size.y; } - unsigned char const * ImageInfo::data() const + unsigned char const * Image::Info::data() const { return &m_data[0]; } - bool operator<(ImageInfo const & l, ImageInfo const & r) + bool Image::Info::lessThan(Resource::Info const * r) const { - return l.m_resourceName < r.m_resourceName; + if (m_category != r->m_category) + return m_category < r->m_category; + + Image::Info const * ri = static_cast(r); + + if (m_resourceName != ri->m_resourceName) + m_resourceName < ri->m_resourceName; + + return false; + } + + m2::PointU const Image::Info::resourceSize() const + { + return m2::PointU(m_size.x + 4, m_size.y + 4); + } + + Resource * Image::Info::createResource(m2::RectU const & texRect, + uint8_t pipelineID) const + { + return new Image(texRect, + pipelineID, + *this); + } + + Image::Image(m2::RectU const & texRect, + int pipelineID, + Info const & info) + : Resource(EImage, texRect, pipelineID), + m_info(info) + { + } + + void Image::render(void * dst) + { + DATA_TRAITS::view_t srcView = gil::interleaved_view( + m_info.m_size.x, m_info.m_size.y, + (DATA_TRAITS::pixel_t*)&m_info.m_data[0], + m_info.m_size.x * sizeof(DATA_TRAITS::pixel_t)); + + DATA_TRAITS::view_t dstView = gil::interleaved_view( + m_info.m_size.x + 4, m_info.m_size.y + 4, + (DATA_TRAITS::pixel_t*)dst, + (m_info.m_size.x + 4) * sizeof(DATA_TRAITS::pixel_t)); + + gil::copy_pixels( + srcView, + gil::subimage_view(dstView, 2, 2, m_info.m_size.x, m_info.m_size.y)); + + DATA_TRAITS::pixel_t pxBorder = DATA_TRAITS::createPixel(Color(0, 0, 0, 0)); + + for (unsigned y = 0; y < 2; ++y) + for (unsigned x = 0; x < m_info.m_size.x + 4; ++x) + dstView(x, y) = pxBorder; + + for (unsigned y = 2; y < m_info.m_size.y + 2; ++y) + { + for (unsigned x = 0; x < 2; ++x) + dstView(x, y) = pxBorder; + for (unsigned x = m_info.m_size.x + 2; x < m_info.m_size.x + 4; ++x) + dstView(x, y) = pxBorder; + } + + for (unsigned y = m_info.m_size.y + 2; y < m_info.m_size.y + 4; ++y) + for (unsigned x = 0; x < m_info.m_size.x + 4; ++x) + dstView(x, y) = pxBorder; + } + + Resource::Info const * Image::info() const + { + return &m_info; } } diff --git a/graphics/image.hpp b/graphics/image.hpp index eba2440964..4aaaec3117 100644 --- a/graphics/image.hpp +++ b/graphics/image.hpp @@ -1,5 +1,7 @@ #pragma once +#include "resource.hpp" + #include "../std/string.hpp" #include "../geometry/point2d.hpp" @@ -9,23 +11,34 @@ namespace graphics /// get dimensions of PNG image specified by it's resourceName. m2::PointU const GetDimensions(string const & resourceName); - class ImageInfo + struct Image : public Resource { - private: - vector m_data; - m2::PointU m_size; - string m_resourceName; - public: - /// create ImageInfo from PNG resource - ImageInfo(char const * resourceName); + struct Info : public Resource::Info + { + string m_resourceName; + m2::PointU m_size; + vector m_data; - unsigned width() const; - unsigned height() const; + Info(); + Info(char const * resName); - unsigned char const * data() const; + unsigned width() const; + unsigned height() const; + unsigned char const * data() const; - friend bool operator < (ImageInfo const & l, ImageInfo const & r); + m2::PointU const resourceSize() const; + Resource * createResource(m2::RectU const & texRect, + uint8_t pipelineID) const; + bool lessThan(Resource::Info const * r) const; + }; + + Info m_info; + + Image(m2::RectU const & texRect, + int pipelineID, + Info const & info); + + void render(void * dst); + Resource::Info const * info() const; }; - - bool operator < (ImageInfo const & l, ImageInfo const & r); } diff --git a/graphics/image_renderer.cpp b/graphics/image_renderer.cpp index c93aa6e20d..99e208f618 100644 --- a/graphics/image_renderer.cpp +++ b/graphics/image_renderer.cpp @@ -1,5 +1,5 @@ #include "image_renderer.hpp" -#include "resource_style.hpp" +#include "resource.hpp" #include "skin.hpp" #include "opengl/base_texture.hpp" @@ -14,20 +14,20 @@ namespace graphics {} void ImageRenderer::drawImage(math::Matrix const & m, - uint32_t styleID, + uint32_t resID, double depth) { - ResourceStyle const * style(skin()->fromID(styleID)); + Resource const * res(skin()->fromID(resID)); - if (style == 0) + if (res == 0) { - LOG(LINFO, ("drawImage: styleID=", styleID, "wasn't found on current skin")); + LOG(LINFO, ("drawImage: resID=", resID, "wasn't found on current skin")); return; } - ASSERT(style->m_cat == ResourceStyle::EImageStyle, ()); + ASSERT(res->m_cat == Resource::EImage, ()); - m2::RectI texRect(style->m_texRect); + m2::RectI texRect(res->m_texRect); texRect.Inflate(-1, -1); m2::PointF pts[6] = @@ -40,7 +40,7 @@ namespace graphics m2::PointF(m2::PointD(-1, -1) * m) }; - shared_ptr const & texture = skin()->page(style->m_pipelineID)->texture(); + shared_ptr const & texture = skin()->page(res->m_pipelineID)->texture(); m2::PointF texPts[6] = { @@ -62,6 +62,6 @@ namespace graphics texPts, sizeof(m2::PointF), 6, depth, - style->m_pipelineID); + res->m_pipelineID); } } diff --git a/graphics/image_renderer.hpp b/graphics/image_renderer.hpp index 8956deeac7..aac47247ad 100644 --- a/graphics/image_renderer.hpp +++ b/graphics/image_renderer.hpp @@ -15,7 +15,7 @@ namespace graphics ImageRenderer(base_t::Params const & p); void drawImage(math::Matrix const & m, - uint32_t styleID, + uint32_t resID, double depth); }; } diff --git a/graphics/opengl/geometry_renderer.cpp b/graphics/opengl/geometry_renderer.cpp index 1ba2a61ee9..a2e97d6f70 100644 --- a/graphics/opengl/geometry_renderer.cpp +++ b/graphics/opengl/geometry_renderer.cpp @@ -1,6 +1,6 @@ #include "../base/SRC_FIRST.hpp" #include "geometry_renderer.hpp" -#include "resource_style.hpp" +#include "resource.hpp" #include "base_texture.hpp" #include "texture.hpp" #include "buffer_object.hpp" @@ -23,13 +23,13 @@ namespace graphics : base_t(params) {} - GeometryRenderer::UploadData::UploadData(shared_ptr const * styles, + GeometryRenderer::UploadData::UploadData(shared_ptr const * resources, size_t count, shared_ptr const & texture) : m_texture(texture) { m_uploadQueue.reserve(count); - copy(styles, styles + count, back_inserter(m_uploadQueue)); + copy(resources, resources + count, back_inserter(m_uploadQueue)); } GeometryRenderer::UploadData::UploadData() @@ -55,14 +55,14 @@ namespace graphics for (size_t i = 0; i < m_uploadQueue.size(); ++i) { - shared_ptr const & style = m_uploadQueue[i]; + shared_ptr const & resource = m_uploadQueue[i]; - TDynamicTexture::view_t v = dynTexture->view(style->m_texRect.SizeX(), - style->m_texRect.SizeY()); + TDynamicTexture::view_t v = dynTexture->view(resource->m_texRect.SizeX(), + resource->m_texRect.SizeY()); - style->render(&v(0, 0)); + resource->render(&v(0, 0)); - dynTexture->upload(&v(0, 0), style->m_texRect); + dynTexture->upload(&v(0, 0), resource->m_texRect); } /// In multithreaded resource usage scenarios the suggested way to see @@ -88,11 +88,11 @@ namespace graphics } - void GeometryRenderer::uploadStyles(shared_ptr const * styles, - size_t count, - shared_ptr const & texture) + void GeometryRenderer::uploadResources(shared_ptr const * resources, + size_t count, + shared_ptr const & texture) { - processCommand(make_shared_ptr(new UploadData(styles, count, texture))); + processCommand(make_shared_ptr(new UploadData(resources, count, texture))); } GeometryRenderer::IMMDrawTexturedRect::IMMDrawTexturedRect( diff --git a/graphics/opengl/geometry_renderer.hpp b/graphics/opengl/geometry_renderer.hpp index fa577cb4ed..ccad9699ff 100644 --- a/graphics/opengl/geometry_renderer.hpp +++ b/graphics/opengl/geometry_renderer.hpp @@ -12,7 +12,7 @@ namespace graphics { - struct ResourceStyle; + struct Resource; namespace gl { @@ -26,11 +26,11 @@ namespace graphics struct UploadData : public Command { - vector > m_uploadQueue; + vector > m_uploadQueue; shared_ptr m_texture; UploadData(); - UploadData(shared_ptr const * styles, + UploadData(shared_ptr const * styles, size_t count, shared_ptr const & texture); @@ -131,9 +131,9 @@ namespace graphics size_t indicesOffs, EPrimitives primType); - void uploadStyles(shared_ptr const * styles, - size_t count, - shared_ptr const & texture); + void uploadResources(shared_ptr const * styles, + size_t count, + shared_ptr const & texture); void freeTexture(shared_ptr const & texture, TTexturePool * texturePool); void freeStorage(Storage const & storage, TStoragePool * storagePool); diff --git a/graphics/opengl/texture.hpp b/graphics/opengl/texture.hpp index 5d04069cbc..c72c04e45a 100644 --- a/graphics/opengl/texture.hpp +++ b/graphics/opengl/texture.hpp @@ -3,7 +3,7 @@ #include "managed_texture.hpp" #include "data_traits.hpp" -#include "../image_info.hpp" +#include "../image.hpp" #include "../../platform/platform.hpp" diff --git a/graphics/overlay_renderer.cpp b/graphics/overlay_renderer.cpp index fa86e4406f..c8c3103970 100644 --- a/graphics/overlay_renderer.cpp +++ b/graphics/overlay_renderer.cpp @@ -43,19 +43,19 @@ namespace graphics m_overlay->processOverlayElement(oe); } - void OverlayRenderer::drawSymbol(m2::PointD const & pt, string const & symbolName, EPosition pos, int depth) + void OverlayRenderer::drawSymbol(m2::PointD const & pt, string const & name, EPosition pos, int depth) { graphics::SymbolElement::Params params; params.m_depth = depth; params.m_position = pos; params.m_pivot = pt; - params.m_symbolName = symbolName; + params.m_info.m_name = name; drawSymbol(params); } void OverlayRenderer::drawCircle(m2::PointD const & pt, - graphics::CircleInfo const & ci, + graphics::Circle::Info const & ci, EPosition pos, int depth) { diff --git a/graphics/overlay_renderer.hpp b/graphics/overlay_renderer.hpp index 4c58834f88..34e2173fd5 100644 --- a/graphics/overlay_renderer.hpp +++ b/graphics/overlay_renderer.hpp @@ -3,6 +3,7 @@ #include "text_renderer.hpp" #include "../std/shared_ptr.hpp" #include "overlay.hpp" +#include "circle.hpp" namespace graphics { @@ -35,7 +36,10 @@ namespace graphics void drawSymbol(m2::PointD const & pt, string const & symbolName, EPosition pos, int depth); /// Drawing circle - void drawCircle(m2::PointD const & pt, graphics::CircleInfo const & ci, EPosition pos, int depth); + void drawCircle(m2::PointD const & pt, + Circle::Info const & ci, + EPosition pos, + int depth); /// drawing straight text void drawText(FontDesc const & fontDesc, diff --git a/graphics/path_renderer.cpp b/graphics/path_renderer.cpp index 24b34bece1..f7e8673ea6 100644 --- a/graphics/path_renderer.cpp +++ b/graphics/path_renderer.cpp @@ -1,5 +1,6 @@ #include "path_renderer.hpp" -#include "resource_style.hpp" +#include "resource.hpp" +#include "pen.hpp" #include "skin.hpp" #include "resource_cache.hpp" @@ -20,7 +21,7 @@ namespace graphics m_fastSolidPath(params.m_fastSolidPath) {} - void PathRenderer::drawPath(m2::PointD const * points, size_t pointsCount, double offset, uint32_t styleID, double depth) + void PathRenderer::drawPath(m2::PointD const * points, size_t pointsCount, double offset, uint32_t resID, double depth) { ++m_pathCount; m_pointsCount += pointsCount; @@ -29,29 +30,29 @@ namespace graphics return; ASSERT_GREATER_OR_EQUAL(pointsCount, 2, ()); - ASSERT_NOT_EQUAL(styleID, uint32_t(-1), ()); + ASSERT_NOT_EQUAL(resID, uint32_t(-1), ()); - ResourceStyle const * style(skin()->fromID(styleID)); - if (style == 0) + Resource const * res(skin()->fromID(resID)); + if (res == 0) { - LOG(LINFO, ("drawPath: styleID=", styleID, " wasn't found on current skin")); + LOG(LINFO, ("drawPath: resID=", resID, " wasn't found on current skin")); return; } - ASSERT(style->m_cat == ResourceStyle::ELineStyle, ()); + ASSERT(res->m_cat == Resource::EPen, ()); - LineStyle const * lineStyle = static_cast(style); - if (m_fastSolidPath && lineStyle->m_isSolid) + Pen const * pen = static_cast(res); + if (m_fastSolidPath && pen->m_isSolid) { - drawFastSolidPath(points, pointsCount, styleID, depth); + drawFastSolidPath(points, pointsCount, resID, depth); return; } float rawTileStartLen = 0; - float rawTileLen = (float)lineStyle->rawTileLen(); + float rawTileLen = (float)pen->rawTileLen(); - if ((offset < 0) && (!lineStyle->m_isWrapped)) + if ((offset < 0) && (!pen->m_isWrapped)) offset = offset - rawTileLen * ceil(offset / rawTileLen); bool skipToOffset = true; @@ -80,7 +81,7 @@ namespace graphics } /// Geometry width. It's 1px wider than the pattern width. - int geomWidth = static_cast(lineStyle->m_penInfo.m_w) + 4 - 2 * aaShift(); + int geomWidth = static_cast(pen->m_info.m_w) + 4 - 2 * aaShift(); float geomHalfWidth = geomWidth / 2.0; /// Starting point of the tiles on this segment @@ -94,7 +95,7 @@ namespace graphics /// Length of the actual pattern data being tiling(without antialiasing zones). rawTileLen = 0; - shared_ptr texture = skin()->page(lineStyle->m_pipelineID)->texture(); + shared_ptr texture = skin()->page(pen->m_pipelineID)->texture(); if (!texture) { @@ -102,25 +103,25 @@ namespace graphics return; } - float texMaxY = lineStyle->m_texRect.maxY() - aaShift(); - float texMinY = lineStyle->m_texRect.minY() + aaShift(); + float texMaxY = pen->m_texRect.maxY() - aaShift(); + float texMinY = pen->m_texRect.minY() + aaShift(); m2::PointF const fNorm = norm * geomHalfWidth; // enough to calc it once while (segLenRemain > 0) { - rawTileLen = lineStyle->m_isWrapped + rawTileLen = pen->m_isWrapped ? segLen - : std::min(((float)lineStyle->rawTileLen() - rawTileStartLen), segLenRemain); + : std::min(((float)pen->rawTileLen() - rawTileStartLen), segLenRemain); - float texMinX = lineStyle->m_isWrapped ? 0 : lineStyle->m_texRect.minX() + 2 + rawTileStartLen; + float texMinX = pen->m_isWrapped ? 0 : pen->m_texRect.minX() + 2 + rawTileStartLen; float texMaxX = texMinX + rawTileLen; rawTileStartLen += rawTileLen; - if (rawTileStartLen >= lineStyle->rawTileLen()) - rawTileStartLen -= lineStyle->rawTileLen(); - ASSERT(rawTileStartLen < lineStyle->rawTileLen(), ()); + if (rawTileStartLen >= pen->rawTileLen()) + rawTileStartLen -= pen->rawTileLen(); + ASSERT(rawTileStartLen < pen->rawTileLen(), ()); m2::PointF rawTileEndPt(rawTileStartPt.x + dir.x * rawTileLen, rawTileStartPt.y + dir.y * rawTileLen); @@ -149,14 +150,19 @@ namespace graphics m2::PointF(0, 0) }; - addTexturedFan(coords, normals, texCoords, 4, depth, lineStyle->m_pipelineID); + addTexturedFan(coords, + normals, + texCoords, + 4, + depth, + pen->m_pipelineID); segLenRemain -= rawTileLen; rawTileStartPt = rawTileEndPt; } - bool isColorJoin = lineStyle->m_isSolid ? true : lineStyle->m_penInfo.atDashOffset(rawTileLen); + bool isColorJoin = pen->m_isSolid ? true : pen->m_info.atDashOffset(rawTileLen); /// Adding geometry for a line join between previous and current segment. if ((i != pointsCount - 2) && (isColorJoin)) @@ -185,7 +191,7 @@ namespace graphics startVec = norm; } - shared_ptr texture = skin()->page(lineStyle->m_pipelineID)->texture(); + shared_ptr texture = skin()->page(pen->m_pipelineID)->texture(); if (!texture) { @@ -195,9 +201,9 @@ namespace graphics m2::PointF joinSegTex[3] = { - texture->mapPixel(lineStyle->m_centerColorPixel), - texture->mapPixel(lineStyle->m_borderColorPixel), - texture->mapPixel(lineStyle->m_borderColorPixel) + texture->mapPixel(pen->m_centerColorPixel), + texture->mapPixel(pen->m_borderColorPixel), + texture->mapPixel(pen->m_borderColorPixel) }; m2::PointD prevStartVec = startVec; @@ -221,7 +227,12 @@ namespace graphics m2::PointF(0, 0) }; - addTexturedFan(joinSeg, joinSegNormals, joinSegTex, 3, depth, lineStyle->m_pipelineID); + addTexturedFan(joinSeg, + joinSegNormals, + joinSegTex, + 3, + depth, + pen->m_pipelineID); prevStartVec = startVec; } @@ -229,15 +240,15 @@ namespace graphics } } - void PathRenderer::drawFastSolidPath(m2::PointD const * points, size_t pointsCount, uint32_t styleID, double depth) + void PathRenderer::drawFastSolidPath(m2::PointD const * points, size_t pointsCount, uint32_t resID, double depth) { ASSERT_GREATER_OR_EQUAL(pointsCount, 2, ()); - ResourceStyle const * style(skin()->fromID(styleID)); + Resource const * res(skin()->fromID(resID)); - ASSERT(style->m_cat == ResourceStyle::ELineStyle, ()); - LineStyle const * lineStyle = static_cast(style); + ASSERT(res->m_cat == Resource::EPen, ()); + Pen const * pen = static_cast(res); - ASSERT(lineStyle->m_isSolid, ()); + ASSERT(pen->m_isSolid, ()); for (size_t i = 0; i < pointsCount - 1; ++i) { @@ -247,13 +258,13 @@ namespace graphics m2::PointD norm(-dir.y, dir.x); m2::PointD const & nextPt = points[i + 1]; - float geomHalfWidth = (lineStyle->m_penInfo.m_w + 4 - aaShift() * 2) / 2.0; + float geomHalfWidth = (pen->m_info.m_w + 4 - aaShift() * 2) / 2.0; - float texMinX = lineStyle->m_texRect.minX() + 1; - float texMaxX = lineStyle->m_texRect.maxX() - 1; + float texMinX = pen->m_texRect.minX() + 1; + float texMaxX = pen->m_texRect.maxX() - 1; - float texMinY = lineStyle->m_texRect.maxY() - aaShift(); - float texMaxY = lineStyle->m_texRect.minY() + aaShift(); + float texMinY = pen->m_texRect.maxY() - aaShift(); + float texMaxY = pen->m_texRect.minY() + aaShift(); float texCenterX = (texMinX + texMaxX) / 2; @@ -275,7 +286,7 @@ namespace graphics nextPt + fDir - fNorm }; - shared_ptr texture = skin()->page(lineStyle->m_pipelineID)->texture(); + shared_ptr texture = skin()->page(pen->m_pipelineID)->texture(); if (!texture) { @@ -302,7 +313,7 @@ namespace graphics texCoords, sizeof(m2::PointF), 8, depth, - lineStyle->m_pipelineID); + pen->m_pipelineID); } } diff --git a/graphics/path_renderer.hpp b/graphics/path_renderer.hpp index 6f2c43be13..aca2e70d08 100644 --- a/graphics/path_renderer.hpp +++ b/graphics/path_renderer.hpp @@ -14,7 +14,7 @@ namespace graphics bool m_drawPathes; bool m_fastSolidPath; - void drawFastSolidPath(m2::PointD const * points, size_t pointsCount, uint32_t styleID, double depth); + void drawFastSolidPath(m2::PointD const * points, size_t pointsCount, uint32_t resID, double depth); public: @@ -29,7 +29,7 @@ namespace graphics PathRenderer(Params const & params); - void drawPath(m2::PointD const * points, size_t pointsCount, double offset, uint32_t styleID, double depth); + void drawPath(m2::PointD const * points, size_t pointsCount, double offset, uint32_t resID, double depth); void beginFrame(); void endFrame(); diff --git a/graphics/pen.cpp b/graphics/pen.cpp index 691124a75d..d598d11094 100644 --- a/graphics/pen.cpp +++ b/graphics/pen.cpp @@ -1,4 +1,4 @@ -#include "pen_info.hpp" +#include "pen.hpp" #include "../base/logging.hpp" @@ -6,13 +6,25 @@ #include "../std/iterator.hpp" #include "../std/numeric.hpp" +#include "opengl/data_traits.hpp" +#include "agg_traits.hpp" + namespace graphics { - PenInfo::PenInfo() + Pen::Info::Info() + : Resource::Info(EPen) {} - PenInfo::PenInfo(Color const & color, double w, double const * pattern, size_t patternSize, double offset) - : m_color(color), m_w(w), m_offset(offset), m_isSolid(false) + Pen::Info::Info(Color const & color, + double w, + double const * pattern, + size_t patternSize, + double offset) + : Resource::Info(EPen), + m_color(color), + m_w(w), + m_offset(offset), + m_isSolid(false) { if (m_w < 1.0) m_w = 1.0; @@ -78,7 +90,7 @@ namespace graphics } } - double PenInfo::firstDashOffset() const + double Pen::Info::firstDashOffset() const { double res = 0; for (size_t i = 0; i < m_pat.size() / 2; ++i) @@ -89,7 +101,7 @@ namespace graphics return res; } - bool PenInfo::atDashOffset(double offset) const + bool Pen::Info::atDashOffset(double offset) const { double nextDashStart = 0; for (size_t i = 0; i < m_pat.size() / 2; ++i) @@ -105,7 +117,7 @@ namespace graphics return false; } - m2::PointU const PenInfo::patternSize() const + m2::PointU const Pen::Info::resourceSize() const { if (m_isSolid) return m2::PointU(static_cast(ceil(m_w / 2)) * 2 + 4, @@ -117,22 +129,226 @@ namespace graphics } } - bool operator < (PenInfo const & l, PenInfo const & r) + Resource * Pen::Info::createResource(m2::RectU const & texRect, + uint8_t pipelineID) const { - if (l.m_isSolid != r.m_isSolid) - return l.m_isSolid < r.m_isSolid; - if (l.m_color != r.m_color) - return l.m_color < r.m_color; - if (l.m_w != r.m_w) - return l.m_w < r.m_w; - if (l.m_offset != r.m_offset) - return l.m_offset < r.m_offset; - if (l.m_pat.size() != r.m_pat.size()) - return l.m_pat.size() < r.m_pat.size(); - for (size_t i = 0; i < l.m_pat.size(); ++i) - if (l.m_pat[i] != r.m_pat[i]) - return l.m_pat[i] < r.m_pat[i]; + return new Pen(false, + texRect, + pipelineID, + *this); + } + + bool Pen::Info::lessThan(Resource::Info const * r) const + { + if (m_category != r->m_category) + return m_category < r->m_category; + + Info const * rp = static_cast(r); + + if (m_isSolid != rp->m_isSolid) + return m_isSolid < rp->m_isSolid; + if (m_color != rp->m_color) + return m_color < rp->m_color; + if (m_w != rp->m_w) + return m_w < rp->m_w; + if (m_offset != rp->m_offset) + return m_offset < rp->m_offset; + if (m_pat.size() != rp->m_pat.size()) + return m_pat.size() < rp->m_pat.size(); + for (size_t i = 0; i < m_pat.size(); ++i) + if (m_pat[i] != rp->m_pat[i]) + return m_pat[i] < rp->m_pat[i]; return false; } + + Pen::Pen(bool isWrapped, + m2::RectU const & texRect, + int pipelineID, + Info const & info) + : Resource(EPen, texRect, pipelineID), + m_info(info), + m_isWrapped(isWrapped), + m_isSolid(info.m_isSolid) + { + if (m_isSolid) + m_borderColorPixel = m_centerColorPixel = m2::PointU(texRect.minX() + 1, texRect.minY() + 1); + else + { + double firstDashOffset = info.firstDashOffset(); + m_centerColorPixel = m2::PointU(static_cast(firstDashOffset + texRect.minX() + 3), + static_cast(texRect.minY() + texRect.SizeY() / 2.0)); + m_borderColorPixel = m2::PointU(static_cast(firstDashOffset + texRect.minX() + 3), + static_cast(texRect.minY() + 1)); + } + } + + double Pen::geometryTileLen() const + { + return m_texRect.SizeX() - 2; + } + + double Pen::geometryTileWidth() const + { + return m_texRect.SizeY() - 2; + } + + double Pen::rawTileLen() const + { + return m_texRect.SizeX() - 4; + } + + double Pen::rawTileWidth() const + { + return m_texRect.SizeY() - 4; + } + + void Pen::render(void * dst) + { + Info const & info = m_info; + m2::RectU const & rect = m_texRect; + + DATA_TRAITS::view_t v = gil::interleaved_view(rect.SizeX(), + rect.SizeY(), + (DATA_TRAITS::pixel_t*)dst, + sizeof(DATA_TRAITS::pixel_t) * rect.SizeX()); + + graphics::Color penColor = info.m_color; + + penColor /= DATA_TRAITS::channelScaleFactor; + + DATA_TRAITS::pixel_t penColorTranslucent; + + gil::get_color(penColorTranslucent, gil::red_t()) = penColor.r; + gil::get_color(penColorTranslucent, gil::green_t()) = penColor.g; + gil::get_color(penColorTranslucent, gil::blue_t()) = penColor.b; + gil::get_color(penColorTranslucent, gil::alpha_t()) = 0; + + DATA_TRAITS::pixel_t pxPenColor = penColorTranslucent; + gil::get_color(pxPenColor, gil::alpha_t()) = penColor.a; + + if (info.m_isSolid) + { + /// draw circle + agg::rendering_buffer buf( + (unsigned char *)&v(0, 0), + rect.SizeX(), + rect.SizeY(), + rect.SizeX() * sizeof(DATA_TRAITS::pixel_t) + ); + + typedef AggTraits::pixfmt_t agg_pixfmt_t; + + agg_pixfmt_t pixfmt(buf); + agg::renderer_base rbase(pixfmt); + + gil::fill_pixels(v, penColorTranslucent); + + agg::scanline_u8 s; + agg::rasterizer_scanline_aa<> rasterizer; + if (info.m_w > 2) + { + agg::ellipse ell; + float r = ceil(info.m_w) / 2.0; + ell.init(r + 2, r + 2, r, r, 100); + rasterizer.add_path(ell); + + agg::render_scanlines_aa_solid(rasterizer, + s, + rbase, + agg::rgba8(info.m_color.r, + info.m_color.g, + info.m_color.b, + info.m_color.a)); + + uint32_t ri = static_cast(r); + + /// pixels that are used to texture inner part of the line should be fully opaque + v(2 + ri - 1, 2) = pxPenColor; + v(2 + ri , 2) = pxPenColor; + v(2 + ri - 1, 2 + ri * 2 - 1) = pxPenColor; + v(2 + ri , 2 + ri * 2 - 1) = pxPenColor; + + /// in non-transparent areas - premultiply color value with alpha and make it opaque + for (size_t x = 2; x < v.width() - 2; ++x) + for (size_t y = 2; y < v.height() - 2; ++y) + { + unsigned char alpha = gil::get_color(v(x, y), gil::alpha_t()); + if (alpha != 0) + v(x, y) = pxPenColor; + } + } + else + { + gil::fill_pixels( + gil::subimage_view(v, 2, 2, rect.SizeX() - 4, rect.SizeY() - 4), + pxPenColor + ); + } + } + else + { + /// First two and last two rows of a pattern are filled + /// with a penColorTranslucent pixel for the antialiasing. + for (size_t y = 0; y < 2; ++y) + for (size_t x = 0; x < rect.SizeX(); ++x) + v(x, y) = penColorTranslucent; + + for (size_t y = rect.SizeY() - 2; y < rect.SizeY(); ++y) + for (size_t x = 0; x < rect.SizeX(); ++x) + v(x, y) = penColorTranslucent; + + /// first and last two pixels filled with penColorTranslucent + for (size_t y = 2; y < rect.SizeY() - 2; ++y) + { + v(0, y) = penColorTranslucent; + v(1, y) = penColorTranslucent; + v(rect.SizeX() - 2, y) = penColorTranslucent; + v(rect.SizeX() - 1, y) = penColorTranslucent; + } + + /// draw pattern + for (size_t y = 2; y < rect.SizeY() - 2; ++y) + { + double curLen = 0; + + DATA_TRAITS::pixel_t px = pxPenColor; + + /// In general case this code is incorrect. + /// TODO : Make a pattern start and end with a dash. + uint32_t curLenI = static_cast(curLen); + + v(curLenI, y) = px; + v(curLenI + 1, y) = px; + + for (size_t i = 0; i < info.m_pat.size(); ++i) + { + for (size_t j = 0; j < info.m_pat[i]; ++j) + { + uint32_t val = (i + 1) % 2; + + if (val == 0) + gil::get_color(px, gil::alpha_t()) = 0; + else + gil::get_color(px, gil::alpha_t()) = penColor.a; + + v(curLenI + j + 2, y) = px; + } + + v(static_cast(curLen + 2 + info.m_pat[i]), y) = px; + v(static_cast(curLen + 2 + info.m_pat[i] + 1), y) = px; + + curLen += info.m_pat[i]; + + curLenI = static_cast(curLen); + } + } + } + } + + Resource::Info const * Pen::info() const + { + return &m_info; + } + } diff --git a/graphics/pen.hpp b/graphics/pen.hpp index 0911011dcc..722b090fb4 100644 --- a/graphics/pen.hpp +++ b/graphics/pen.hpp @@ -1,5 +1,6 @@ #pragma once +#include "resource.hpp" #include "color.hpp" #include "../geometry/point2d.hpp" @@ -8,32 +9,59 @@ namespace graphics { - /// definition of the line style pattern - /// used as a texture-cache-key - struct PenInfo + struct Pen : public Resource { - typedef buffer_vector TPattern; - Color m_color; - double m_w; - TPattern m_pat; - double m_offset; + /// definition of the line style pattern + /// used as a texture-cache-key + struct Info : public Resource::Info + { + typedef buffer_vector TPattern; + Color m_color; + double m_w; + TPattern m_pat; + double m_offset; + bool m_isSolid; + + Info(); + Info(Color const & color, + double width, + double const * pattern, + size_t patternSize, + double offset); + + double firstDashOffset() const; + bool atDashOffset(double offset) const; + + m2::PointU const resourceSize() const; + Resource * createResource(m2::RectU const & texRect, + uint8_t pipelineID) const; + + bool lessThan(Resource::Info const * r) const; + }; + + Info m_info; + + bool m_isWrapped; bool m_isSolid; - PenInfo( - Color const & color, - double width, - double const * pattern, - size_t patternSize, - double offset); + m2::PointU m_centerColorPixel; + m2::PointU m_borderColorPixel; - PenInfo(); + Pen(bool isWrapped, + m2::RectU const & texRect, + int pipelineID, + Info const & info); - double firstDashOffset() const; - bool atDashOffset(double offset) const; + /// with antialiasing zones + double geometryTileLen() const; + double geometryTileWidth() const; - m2::PointU const patternSize() const; + /// without antialiasing zones + double rawTileLen() const; + double rawTileWidth() const; + + void render(void * dst); + Resource::Info const * info() const; }; - - bool operator < (PenInfo const & l, PenInfo const & r); } diff --git a/graphics/resource.cpp b/graphics/resource.cpp index c6d9d62f90..4feaeead43 100644 --- a/graphics/resource.cpp +++ b/graphics/resource.cpp @@ -1,21 +1,22 @@ -#include "resource_style.hpp" +#include "resource.hpp" #include "opengl/data_traits.hpp" namespace graphics { - ResourceStyle::ResourceStyle() + Resource::Info::Info(Category cat) + : m_category(cat) {} - ResourceStyle::ResourceStyle( + Resource::Resource( m2::RectU const & texRect, int pipelineID - ) : m_cat(EUnknownStyle), + ) : m_cat(EUnknown), m_texRect(texRect), m_pipelineID(pipelineID) {} - ResourceStyle::ResourceStyle( + Resource::Resource( Category cat, m2::RectU const & texRect, int pipelineID) @@ -24,84 +25,6 @@ namespace graphics m_pipelineID(pipelineID) {} - ResourceStyle::~ResourceStyle() + Resource::~Resource() {} - - PointStyle::PointStyle(m2::RectU const & texRect, int pipelineID, string const & styleName) - : ResourceStyle(EPointStyle, texRect, pipelineID), m_styleName(styleName) - {} - - void PointStyle::render(void *dst) - {} - - ColorStyle::ColorStyle(m2::RectU const & texRect, int pipelineID, graphics::Color const & c) - : ResourceStyle(EColorStyle, texRect, pipelineID), m_c(c) - {} - - void ColorStyle::render(void * dst) - { - graphics::Color c = m_c; - m2::RectU const & r = m_texRect; - - DATA_TRAITS::pixel_t px; - - gil::get_color(px, gil::red_t()) = c.r / DATA_TRAITS::channelScaleFactor; - gil::get_color(px, gil::green_t()) = c.g / DATA_TRAITS::channelScaleFactor; - gil::get_color(px, gil::blue_t()) = c.b / DATA_TRAITS::channelScaleFactor; - gil::get_color(px, gil::alpha_t()) = c.a / DATA_TRAITS::channelScaleFactor; - - DATA_TRAITS::view_t v = gil::interleaved_view( - r.SizeX(), r.SizeY(), - (DATA_TRAITS::pixel_t*)dst, - sizeof(DATA_TRAITS::pixel_t) * r.SizeX() - ); - - for (size_t y = 0; y < r.SizeY(); ++y) - for (size_t x = 0; x < r.SizeX(); ++x) - v(x, y) = px; - } - - ImageStyle::ImageStyle(m2::RectU const & texRect, - int pipelineID, - ImageInfo const & ii) - : ResourceStyle(EImageStyle, texRect, pipelineID), - m_ii(ii) - {} - - void ImageStyle::render(void * dst) - { - m2::RectU const & r = m_texRect; - - DATA_TRAITS::view_t dstV = gil::interleaved_view( - r.SizeX(), r.SizeY(), - (DATA_TRAITS::pixel_t*)dst, - sizeof(DATA_TRAITS::pixel_t) * r.SizeX() - ); - - DATA_TRAITS::view_t srcV = gil::interleaved_view( - r.SizeX() - 4, r.SizeY() - 4, - (DATA_TRAITS::pixel_t*)m_ii.data(), - sizeof(DATA_TRAITS::pixel_t) * (r.SizeX() - 4) - ); - - DATA_TRAITS::pixel_t borderPixel = DATA_TRAITS::createPixel(Color(255, 0, 0, 255)); - - for (unsigned y = 0; y < 2; ++y) - { - dstV(0, y) = borderPixel; - dstV(1, y) = borderPixel; - dstV(r.SizeX() - 2, y) = borderPixel; - dstV(r.SizeX() - 1, y) = borderPixel; - } - - for (unsigned y = r.SizeY() - 2; y < r.SizeY(); ++y) - { - dstV(0, y) = borderPixel; - dstV(1, y) = borderPixel; - dstV(r.SizeX() - 2, y) = borderPixel; - dstV(r.SizeX() - 1, y) = borderPixel; - } - - gil::copy_pixels(srcV, gil::subimage_view(dstV, 2, 2, r.SizeX() - 4, r.SizeY() - 4)); - } } diff --git a/graphics/resource.hpp b/graphics/resource.hpp index 75e4bade8e..e3c965d356 100644 --- a/graphics/resource.hpp +++ b/graphics/resource.hpp @@ -1,117 +1,56 @@ #pragma once -#include "pen_info.hpp" -#include "circle_info.hpp" -#include "image_info.hpp" - #include "../geometry/rect2d.hpp" #include "../std/shared_ptr.hpp" namespace graphics { - struct GlyphInfo; - - struct ResourceStyle + struct Resource { enum Category { - EColorStyle = 1, - ELineStyle, - EGlyphStyle, - EPointStyle, - ECircleStyle, - EImageStyle, - EUnknownStyle + EBrush = 1, + EPen, + EGlyph, + EIcon, + ECircle, + EImage, + EUnknown + }; + + /// Base class for lighweight Resource description + struct Info + { + Category m_category; + + Info(Category cat); + /// returns the size of this resource info which will + /// be occupied in texture cache. + virtual m2::PointU const resourceSize() const = 0; + /// factory method for Resource object + virtual Resource * createResource(m2::RectU const & texRect, + uint8_t pipelineID) const = 0; + /// comparing for using Info as a key in map. + virtual bool lessThan(Info const * r) const = 0; }; Category m_cat; m2::RectU m_texRect; int m_pipelineID; - ResourceStyle(); - ResourceStyle(m2::RectU const & texRect, - int pipelineID); + Resource(); + Resource(m2::RectU const & texRect, + int pipelineID); - virtual ~ResourceStyle(); + virtual ~Resource(); virtual void render(void * dst) = 0; + /// get key for ResourceCache. + virtual Info const * info() const = 0; protected: - ResourceStyle(Category cat, - m2::RectU const & texRect, - int pipelineID); - }; - - struct LineStyle : public ResourceStyle - { - bool m_isWrapped; - bool m_isSolid; - PenInfo m_penInfo; - m2::PointU m_centerColorPixel; - m2::PointU m_borderColorPixel; - LineStyle(bool isWrapped, - m2::RectU const & texRect, - int pipelineID, - PenInfo const & penInfo); - - /// with antialiasing zones - double geometryTileLen() const; - double geometryTileWidth() const; - - /// without antialiasing zones - double rawTileLen() const; - double rawTileWidth() const; - - void render(void * dst); - }; - - struct GlyphStyle : public ResourceStyle - { - shared_ptr m_gi; - GlyphStyle(m2::RectU const & texRect, - int pipelineID, - shared_ptr const & gi); - - void render(void * dst); - }; - - struct PointStyle : public ResourceStyle - { - string m_styleName; - PointStyle(m2::RectU const & texRect, - int pipelineID, - string const & styleName); - - void render(void * dst); - }; - - struct CircleStyle : public ResourceStyle - { - CircleInfo m_ci; - CircleStyle(m2::RectU const & texRect, - int pipelineID, - CircleInfo const & ci); - - void render(void * dst); - }; - - struct ColorStyle : public ResourceStyle - { - Color m_c; - ColorStyle(m2::RectU const & texRect, - int pipelineID, - Color const & c); - - void render(void * dst); - }; - - struct ImageStyle : public ResourceStyle - { - ImageInfo m_ii; - ImageStyle(m2::RectU const & texRect, - int pipelineID, - ImageInfo const & ii); - - void render(void * dst); + Resource(Category cat, + m2::RectU const & texRect, + int pipelineID); }; } diff --git a/graphics/resource_cache.cpp b/graphics/resource_cache.cpp index 88159c96f9..8da763ae39 100644 --- a/graphics/resource_cache.cpp +++ b/graphics/resource_cache.cpp @@ -3,7 +3,6 @@ #include "opengl/texture.hpp" #include "opengl/data_traits.hpp" -#include "resource_style.hpp" #include "resource_manager.hpp" #include "../base/logging.hpp" @@ -31,8 +30,8 @@ namespace graphics } ResourceCache::ResourceCache(shared_ptr const & resourceManager, - ETextureType type, - uint8_t pipelineID) + ETextureType type, + uint8_t pipelineID) : m_resourceManager(resourceManager), m_textureType(type), m_pipelineID(pipelineID) @@ -45,12 +44,12 @@ namespace graphics void ResourceCache::clearHandles() { - clearPenInfoHandles(); - clearColorHandles(); - clearFontHandles(); - clearCircleInfoHandles(); - clearImageInfoHandles(); + for (TResourceInfos::const_iterator it = m_infos.begin(); + it != m_infos.end(); + ++it) + m_resources.erase(it->second); + m_infos.clear(); m_packer.reset(); } @@ -65,248 +64,47 @@ namespace graphics clearUploadQueue(); } - void ResourceCache::clearColorHandles() + bool ResourceCache::LessThan::operator()(Resource::Info const * l, + Resource::Info const * r) const { - for (TColorMap::const_iterator it = m_colorMap.begin(); it != m_colorMap.end(); ++it) - m_styles.erase(it->second); - - m_colorMap.clear(); + return l->lessThan(r); } - void ResourceCache::clearPenInfoHandles() + uint32_t ResourceCache::findInfo(Resource::Info const & info) const { - for (TPenInfoMap::const_iterator it = m_penInfoMap.begin(); it != m_penInfoMap.end(); ++it) - m_styles.erase(it->second); - - m_penInfoMap.clear(); - } - - void ResourceCache::clearCircleInfoHandles() - { - for (TCircleInfoMap::const_iterator it = m_circleInfoMap.begin(); it != m_circleInfoMap.end(); ++it) - m_styles.erase(it->second); - - m_circleInfoMap.clear(); - } - - void ResourceCache::clearFontHandles() - { - for (TGlyphMap::const_iterator it = m_glyphMap.begin(); it != m_glyphMap.end(); ++it) - m_styles.erase(it->second); - - m_glyphMap.clear(); - } - - void ResourceCache::clearImageInfoHandles() - { - for (TImageInfoMap::const_iterator it = m_imageInfoMap.begin(); - it != m_imageInfoMap.end(); - ++it) - m_styles.erase(it->second); - - m_imageInfoMap.clear(); - } - - uint32_t ResourceCache::findImageInfo(ImageInfo const & ii) const - { - TImageInfoMap::const_iterator it = m_imageInfoMap.find(ii); - if (it == m_imageInfoMap.end()) + TResourceInfos::const_iterator it = m_infos.find(&info); + if (it == m_infos.end()) return m_packer.invalidHandle(); else return it->second; } - uint32_t ResourceCache::mapImageInfo(ImageInfo const & ii) + uint32_t ResourceCache::mapInfo(Resource::Info const & info) { - uint32_t foundHandle = findImageInfo(ii); + uint32_t foundHandle = findInfo(info); if (foundHandle != m_packer.invalidHandle()) return foundHandle; - m2::Packer::handle_t h = m_packer.pack(ii.width() + 4, ii.height() + 4); + m2::PointU sz = info.resourceSize(); - m_imageInfoMap[ii] = h; + m2::Packer::handle_t h = m_packer.pack(sz.x, sz.y); m2::RectU texRect = m_packer.find(h).second; - shared_ptr imageStyle(new ImageStyle(texRect, m_pipelineID, ii)); + shared_ptr resource(info.createResource(texRect, m_pipelineID)); - m_styles[h] = imageStyle; - m_uploadQueue.push_back(imageStyle); + m_resources[h] = resource; + m_infos[resource->info()] = h; + m_uploadQueue.push_back(resource); return h; } - bool ResourceCache::hasRoom(ImageInfo const & ii) const + bool ResourceCache::hasRoom(Resource::Info const & info) const { - return m_packer.hasRoom(ii.width() + 4, ii.height() + 4); - } - - uint32_t ResourceCache::findColor(graphics::Color const & c) const - { - TColorMap::const_iterator it = m_colorMap.find(c); - if (it == m_colorMap.end()) - return m_packer.invalidHandle(); - else - return it->second; - } - - uint32_t ResourceCache::mapColor(graphics::Color const & c) - { - uint32_t foundHandle = findColor(c); - - if (foundHandle != m_packer.invalidHandle()) - return foundHandle; - - m2::Packer::handle_t h = m_packer.pack(2, 2); - - m_colorMap[c] = h; - - m2::RectU texRect = m_packer.find(h).second; - shared_ptr colorStyle(new ColorStyle(texRect, m_pipelineID, c)); - - m_styles[h] = colorStyle; - m_uploadQueue.push_back(colorStyle); - - return h; - } - - bool ResourceCache::hasRoom(Color const & ) const - { - return m_packer.hasRoom(2, 2); - } - - uint32_t ResourceCache::findSymbol(char const * symbolName) const - { - TPointNameMap::const_iterator it = m_pointNameMap.find(symbolName); - if (it == m_pointNameMap.end()) - return m_packer.invalidHandle(); - else - return it->second; - } - - uint32_t ResourceCache::findGlyph(GlyphKey const & g) const - { - TGlyphMap::const_iterator it = m_glyphMap.find(g); - if (it == m_glyphMap.end()) - return m_packer.invalidHandle(); - else - return it->second; - } - - uint32_t ResourceCache::mapGlyph(graphics::GlyphKey const & g, graphics::GlyphCache * glyphCache) - { - uint32_t foundHandle = findGlyph(g); - if (foundHandle != m_packer.invalidHandle()) - return foundHandle; - - shared_ptr gi = glyphCache->getGlyphInfo(g); - - m2::Packer::handle_t handle = m_packer.pack(gi->m_metrics.m_width + 4, - gi->m_metrics.m_height + 4); - - m2::RectU texRect = m_packer.find(handle).second; - m_glyphMap[g] = handle; - - boost::shared_ptr glyphStyle( - new GlyphStyle(texRect, - m_pipelineID, - gi)); - - m_styles[handle] = glyphStyle; - m_uploadQueue.push_back(glyphStyle); - - return m_glyphMap[g]; - } - - bool ResourceCache::hasRoom(GlyphKey const & gk, GlyphCache * glyphCache) const - { - shared_ptr gi = glyphCache->getGlyphInfo(gk); - return m_packer.hasRoom(gi->m_metrics.m_width + 4, gi->m_metrics.m_height + 4); - } - - bool ResourceCache::hasRoom(m2::PointU const * sizes, size_t cnt) const - { - return m_packer.hasRoom(sizes, cnt); - } - - uint32_t ResourceCache::findCircleInfo(CircleInfo const & circleInfo) const - { - TCircleInfoMap::const_iterator it = m_circleInfoMap.find(circleInfo); - if (it == m_circleInfoMap.end()) - return m_packer.invalidHandle(); - else - return it->second; - } - - uint32_t ResourceCache::mapCircleInfo(CircleInfo const & circleInfo) - { - uint32_t foundHandle = findCircleInfo(circleInfo); - - if (foundHandle != m_packer.invalidHandle()) - return foundHandle; - - m2::PointU sz = circleInfo.patternSize(); - m2::Packer::handle_t handle = m_packer.pack(sz.x, sz.y); - - m_circleInfoMap[circleInfo] = handle; - - m2::RectU texRect = m_packer.find(handle).second; - - shared_ptr circleStyle(new CircleStyle(texRect, m_pipelineID, circleInfo)); - - m_styles[handle] = circleStyle; - m_uploadQueue.push_back(circleStyle); - - return m_circleInfoMap[circleInfo]; - } - - bool ResourceCache::hasRoom(CircleInfo const & circleInfo) const - { - m2::PointU sz = circleInfo.patternSize(); + m2::PointU sz = info.resourceSize(); return m_packer.hasRoom(sz.x, sz.y); } - uint32_t ResourceCache::findPenInfo(PenInfo const & penInfo) const - { - TPenInfoMap::const_iterator it = m_penInfoMap.find(penInfo); - if (it == m_penInfoMap.end()) - return m_packer.invalidHandle(); - else - return it->second; - } - - uint32_t ResourceCache::mapPenInfo(PenInfo const & penInfo) - { - uint32_t foundHandle = findPenInfo(penInfo); - - if (foundHandle != m_packer.invalidHandle()) - return foundHandle; - - m2::PointU p = penInfo.patternSize(); - - m2::Packer::handle_t handle = m_packer.pack(p.x, p.y); - - m_penInfoMap[penInfo] = handle; - - m2::RectU texRect = m_packer.find(handle).second; - - boost::shared_ptr lineStyle( - new LineStyle(false, - texRect, - m_pipelineID, - penInfo)); - - m_styles[handle] = lineStyle; - m_uploadQueue.push_back(lineStyle); - - return m_penInfoMap[penInfo]; - } - - bool ResourceCache::hasRoom(const PenInfo &penInfo) const - { - m2::PointU p = penInfo.patternSize(); - return m_packer.hasRoom(p.x, p.y); - } - void ResourceCache::setType(ETextureType textureType) { m_textureType = textureType; @@ -339,15 +137,22 @@ namespace graphics void ResourceCache::setPipelineID(uint8_t pipelineID) { m_pipelineID = pipelineID; - for (TStyles::iterator it = m_styles.begin(); it != m_styles.end(); ++it) + for (TResources::iterator it = m_resources.begin(); + it != m_resources.end(); + ++it) it->second->m_pipelineID = pipelineID; } - ResourceStyle * ResourceCache::fromID(uint32_t idx) const + uint8_t ResourceCache::pipelineID() const { - TStyles::const_iterator it = m_styles.find(idx); + return m_pipelineID; + } - if (it == m_styles.end()) + Resource * ResourceCache::fromID(uint32_t idx) const + { + TResources::const_iterator it = m_resources.find(idx); + + if (it == m_resources.end()) return 0; else return it->second.get(); diff --git a/graphics/resource_cache.hpp b/graphics/resource_cache.hpp index d9f6ea0b92..cd261739ad 100644 --- a/graphics/resource_cache.hpp +++ b/graphics/resource_cache.hpp @@ -1,15 +1,12 @@ #pragma once #include "../std/shared_ptr.hpp" +#include "../std/map.hpp" #include "../geometry/packer.hpp" #include "../geometry/rect2d.hpp" -#include "pen_info.hpp" -#include "circle_info.hpp" -#include "color.hpp" -#include "glyph_cache.hpp" -#include "image_info.hpp" +#include "resource.hpp" #include "packets_queue.hpp" #include "defines.hpp" @@ -20,10 +17,7 @@ namespace graphics class BaseTexture; } - struct GlyphStyle; - struct ResourceStyle; class ResourceManager; - struct GlyphInfo; class ResourceCache { @@ -31,30 +25,21 @@ namespace graphics typedef m2::Packer::overflowFn overflowFn; - typedef vector > TUploadQueue; + typedef vector > TUploadQueue; private: - typedef map > TStyles; - TStyles m_styles; + typedef map > TResources; + TResources m_resources; - typedef map TPointNameMap; - TPointNameMap m_pointNameMap; + struct LessThan + { + bool operator()(Resource::Info const * l, + Resource::Info const * r) const; + }; - typedef map TPenInfoMap; - TPenInfoMap m_penInfoMap; - - typedef map TCircleInfoMap; - TCircleInfoMap m_circleInfoMap; - - typedef map TColorMap; - TColorMap m_colorMap; - - typedef map TGlyphMap; - TGlyphMap m_glyphMap; - - typedef map TImageInfoMap; - TImageInfoMap m_imageInfoMap; + typedef map TResourceInfos; + TResourceInfos m_infos; /// made mutable to implement lazy reservation of texture /// @{ @@ -78,14 +63,7 @@ namespace graphics public: - void clearColorHandles(); - void clearPenInfoHandles(); - void clearFontHandles(); - void clearCircleInfoHandles(); - void clearImageInfoHandles(); - void clearHandles(); - void clear(); bool hasData(); @@ -93,6 +71,8 @@ namespace graphics void clearUploadQueue(); void checkTexture() const; + + uint8_t pipelineID() const; void setPipelineID(uint8_t pipelineID); /// creation of detached page @@ -112,30 +92,11 @@ namespace graphics void resetTexture(); void createPacker(); - uint32_t findImageInfo(ImageInfo const & ii) const; - uint32_t mapImageInfo(ImageInfo const & ii); - bool hasRoom(ImageInfo const & ii) const; + uint32_t findInfo(Resource::Info const & info) const; + uint32_t mapInfo(Resource::Info const & info); + bool hasRoom(Resource::Info const & info) const; - uint32_t findColor(Color const & c) const; - uint32_t mapColor(Color const & c); - bool hasRoom(Color const & c) const; - - uint32_t findPenInfo(PenInfo const & penInfo) const; - uint32_t mapPenInfo(PenInfo const & penInfo); - bool hasRoom(PenInfo const & penInfo) const; - - uint32_t findCircleInfo(CircleInfo const & circleInfo) const; - uint32_t mapCircleInfo(CircleInfo const & circleInfo); - bool hasRoom(CircleInfo const & circleInfo) const; - - uint32_t findGlyph(GlyphKey const & g) const; - uint32_t mapGlyph(GlyphKey const & g, GlyphCache * glyphCache); - bool hasRoom(GlyphKey const & g, GlyphCache * glyphCache) const; - bool hasRoom(m2::PointU const * sizes, size_t cnt) const; - - uint32_t findSymbol(char const * symbolName) const; - - ResourceStyle * fromID(uint32_t idx) const; + Resource * fromID(uint32_t idx) const; void setType(ETextureType textureType); ETextureType type() const; diff --git a/graphics/shape_renderer.cpp b/graphics/shape_renderer.cpp index 99ff3730ae..a30f13b2a0 100644 --- a/graphics/shape_renderer.cpp +++ b/graphics/shape_renderer.cpp @@ -1,7 +1,8 @@ #include "shape_renderer.hpp" #include "skin.hpp" -#include "pen_info.hpp" -#include "resource_style.hpp" +#include "pen.hpp" +#include "brush.hpp" +#include "resource.hpp" #include "resource_cache.hpp" #include "opengl/base_texture.hpp" @@ -18,15 +19,15 @@ namespace graphics void ShapeRenderer::drawConvexPolygon(m2::PointF const * pts, size_t ptsCount, graphics::Color const & color, double depth) { - uint32_t styleID = skin()->mapColor(color); + uint32_t resID = skin()->map(Brush::Info(color)); - if (styleID == skin()->invalidHandle()) + if (resID == skin()->invalidHandle()) { LOG(LINFO, ("cannot map color")); return; } - drawTrianglesFan(pts, ptsCount, styleID, depth); + drawTrianglesFan(pts, ptsCount, resID, depth); } void ShapeRenderer::drawArc(m2::PointD const & center, double startA, double endA, double r, graphics::Color const & c, double depth) @@ -37,7 +38,7 @@ namespace graphics if (pts.size() < 2) return; - drawPath(&pts[0], pts.size(), 0, skin()->mapPenInfo(graphics::PenInfo(c, 3, 0, 0, 0)), depth); + drawPath(&pts[0], pts.size(), 0, skin()->map(graphics::Pen::Info(c, 3, 0, 0, 0)), depth); } void ShapeRenderer::approximateArc(m2::PointD const & center, double startA, double endA, double r, vector & pts) @@ -61,7 +62,7 @@ namespace graphics if (pts.size() < 3) return; - drawPath(&pts[0], pts.size(), 0, skin()->mapPenInfo(graphics::PenInfo(c, 2, 0, 0, 0)), depth); + drawPath(&pts[0], pts.size(), 0, skin()->map(graphics::Pen::Info(c, 2, 0, 0, 0)), depth); } void ShapeRenderer::fillSector(m2::PointD const & center, double startA, double endA, double r, graphics::Color const & c, double depth) @@ -87,14 +88,14 @@ namespace graphics pt1 = arcPts[i]; } - drawTrianglesList(§orPts[0], sectorPts.size(), skin()->mapColor(c), depth); + drawTrianglesList(§orPts[0], sectorPts.size(), skin()->map(Brush::Info(c)), depth); } void ShapeRenderer::drawRectangle(m2::AnyRectD const & r, graphics::Color const & c, double depth) { - ResourceStyle const * style = skin()->fromID(skin()->mapColor(c)); + Resource const * res = skin()->fromID(skin()->map(Brush::Info(c))); - if (style == 0) + if (res == 0) { LOG(LINFO, ("cannot map color")); return; @@ -109,7 +110,7 @@ namespace graphics for (int i = 0; i < 4; ++i) rectPtsF[i] = m2::PointF(rectPts[i].x, rectPts[i].y); - shared_ptr texture = skin()->page(style->m_pipelineID)->texture(); + shared_ptr texture = skin()->page(res->m_pipelineID)->texture(); if (!texture) { @@ -117,7 +118,7 @@ namespace graphics return; } - m2::PointF texPt = texture->mapPixel(m2::RectF(style->m_texRect).Center()); + m2::PointF texPt = texture->mapPixel(m2::RectF(res->m_texRect).Center()); m2::PointF normal(0, 0); @@ -130,14 +131,14 @@ namespace graphics 0, 4, depth, - style->m_pipelineID); + res->m_pipelineID); } void ShapeRenderer::drawRectangle(m2::RectD const & r, graphics::Color const & c, double depth) { - ResourceStyle const * style = skin()->fromID(skin()->mapColor(c)); + Resource const * res = skin()->fromID(skin()->map(Brush::Info(c))); - if (style == 0) + if (res == 0) { LOG(LINFO, ("cannot map color")); return; @@ -150,7 +151,7 @@ namespace graphics m2::PointF(r.maxX(), r.maxY()) }; - shared_ptr texture = skin()->page(style->m_pipelineID)->texture(); + shared_ptr texture = skin()->page(res->m_pipelineID)->texture(); if (!texture) { @@ -158,7 +159,7 @@ namespace graphics return; } - m2::PointF texPt = texture->mapPixel(m2::RectF(style->m_texRect).Center()); + m2::PointF texPt = texture->mapPixel(m2::RectF(res->m_texRect).Center()); m2::PointF normal(0, 0); @@ -171,21 +172,21 @@ namespace graphics 0, 4, depth, - style->m_pipelineID + res->m_pipelineID ); } void ShapeRenderer::drawRoundedRectangle(m2::RectD const & r, double rad, graphics::Color const & c, double depth) { - ResourceStyle const * style = skin()->fromID(skin()->mapColor(c)); + Resource const * res = skin()->fromID(skin()->map(Brush::Info(c))); - if (style == 0) + if (res == 0) { LOG(LINFO, ("cannot map color")); return; } - shared_ptr texture = skin()->page(style->m_pipelineID)->texture(); + shared_ptr texture = skin()->page(res->m_pipelineID)->texture(); if (!texture) { @@ -193,7 +194,7 @@ namespace graphics return; } - m2::PointF texPt = texture->mapPixel(m2::RectF(style->m_texRect).Center()); + m2::PointF texPt = texture->mapPixel(m2::RectF(res->m_texRect).Center()); vector seg00; vector seg10; @@ -249,7 +250,7 @@ namespace graphics 0, pts.size(), depth, - style->m_pipelineID + res->m_pipelineID ); } } diff --git a/graphics/skin.cpp b/graphics/skin.cpp index a64e643e54..85cf4d82d1 100644 --- a/graphics/skin.cpp +++ b/graphics/skin.cpp @@ -1,6 +1,5 @@ #include "skin.hpp" #include "resource_cache.hpp" -#include "resource_style.hpp" #include "resource_manager.hpp" #include "../platform/platform.hpp" @@ -72,7 +71,7 @@ namespace graphics return (uint32_t)(pipelineIDMask | h); } - ResourceStyle const * Skin::fromID(uint32_t id) + Resource const * Skin::fromID(uint32_t id) { if (id == invalidHandle()) return 0; @@ -83,87 +82,38 @@ namespace graphics return m_caches[p.first]->fromID(p.second); } - uint32_t Skin::mapSymbol(char const * symbolName) - { - for (uint8_t i = 0; i < m_caches.size(); ++i) - { - uint32_t res = m_caches[i]->findSymbol(symbolName); - if (res != invalidPageHandle()) - return packID(i, res); - } - - return invalidHandle(); - } - - uint32_t Skin::mapColor(Color const & c) + uint32_t Skin::map(Resource::Info const & info) { uint32_t res = invalidPageHandle(); for (uint8_t i = 0; i < m_caches.size(); ++i) { - res = m_caches[i]->findColor(c); + res = m_caches[i]->findInfo(info); if (res != invalidPageHandle()) return packID(i, res); } - if (!m_caches[m_dynamicPage]->hasRoom(c)) + if (!m_caches[m_dynamicPage]->hasRoom(info)) flushDynamicPage(); - return packID(m_dynamicPage, m_caches[m_dynamicPage]->mapColor(c)); + return packID(m_dynamicPage, m_caches[m_dynamicPage]->mapInfo(info)); } - uint32_t Skin::mapPenInfo(PenInfo const & penInfo) + uint32_t Skin::findInfo(Resource::Info const & info) { uint32_t res = invalidPageHandle(); for (uint8_t i = 0; i < m_caches.size(); ++i) { - res = m_caches[i]->findPenInfo(penInfo); + res = m_caches[i]->findInfo(info); if (res != invalidPageHandle()) return packID(i, res); } - if (!m_caches[m_dynamicPage]->hasRoom(penInfo)) - flushDynamicPage(); - - return packID(m_dynamicPage, m_caches[m_dynamicPage]->mapPenInfo(penInfo)); + return res; } - uint32_t Skin::mapCircleInfo(CircleInfo const & circleInfo) - { - uint32_t res = invalidPageHandle(); - - for (uint8_t i = 0; i < m_caches.size(); ++i) - { - res = m_caches[i]->findCircleInfo(circleInfo); - if (res != invalidPageHandle()) - return packID(i, res); - } - - if (!m_caches[m_dynamicPage]->hasRoom(circleInfo)) - flushDynamicPage(); - - return packID(m_dynamicPage, m_caches[m_dynamicPage]->mapCircleInfo(circleInfo)); - } - - uint32_t Skin::mapImageInfo(ImageInfo const & imageInfo) - { - uint32_t res = invalidPageHandle(); - - for (uint8_t i = 0; i < m_caches.size(); ++i) - { - res = m_caches[i]->findImageInfo(imageInfo); - if (res != invalidPageHandle()) - return packID(i, res); - } - - if (!m_caches[m_dynamicPage]->hasRoom(imageInfo)) - flushDynamicPage(); - - return packID(m_dynamicPage, m_caches[m_dynamicPage]->mapImageInfo(imageInfo)); - } - - bool Skin::mapPenInfo(PenInfo const * penInfos, uint32_t * styleIDS, size_t count) + bool Skin::map(Resource::Info const * const * infos, uint32_t * ids, size_t count) { int startDynamicPage = m_dynamicPage; int cycles = 0; @@ -172,12 +122,13 @@ namespace graphics do { - styleIDS[i] = m_caches[m_dynamicPage]->findPenInfo(penInfos[i]); + ids[i] = m_caches[m_dynamicPage]->findInfo(*infos[i]); - if ((styleIDS[i] == invalidPageHandle()) || (unpackID(styleIDS[i]).first != m_dynamicPage)) + if ((ids[i] == invalidPageHandle()) + || (unpackID(ids[i]).first != m_dynamicPage)) { /// try to pack on the currentDynamicPage - while (!m_caches[m_dynamicPage]->hasRoom(penInfos[i])) + while (!m_caches[m_dynamicPage]->hasRoom(*infos[i])) { /// no room - flush the page flushDynamicPage(); @@ -196,7 +147,7 @@ namespace graphics i = 0; } - styleIDS[i] = packID(m_dynamicPage, m_caches[m_dynamicPage]->mapPenInfo(penInfos[i])); + ids[i] = packID(m_dynamicPage, m_caches[m_dynamicPage]->mapInfo(*infos[i])); } ++i; @@ -206,23 +157,6 @@ namespace graphics return true; } - uint32_t Skin::mapGlyph(GlyphKey const & gk, GlyphCache * glyphCache) - { - uint32_t res = invalidPageHandle(); - - for (uint8_t i = 0; i < m_caches.size(); ++i) - { - res = m_caches[i]->findGlyph(gk); - if (res != invalidPageHandle()) - return packID(i, res); - } - - if (!m_caches[m_textPage]->hasRoom(gk, glyphCache)) - flushTextPage(); - - return packID(m_textPage, m_caches[m_textPage]->mapGlyph(gk, glyphCache)); - } - shared_ptr const & Skin::page(int i) const { ASSERT(i < m_caches.size(), ()); diff --git a/graphics/skin.hpp b/graphics/skin.hpp index 7ea72f3573..7cc3e40be8 100644 --- a/graphics/skin.hpp +++ b/graphics/skin.hpp @@ -7,6 +7,8 @@ #include "../std/vector.hpp" #include "../std/queue.hpp" +#include "resource.hpp" + namespace graphics { template @@ -25,13 +27,6 @@ namespace graphics class ResourceCache; class ResourceManager; - struct ResourceStyle; - struct PenInfo; - struct CircleInfo; - class ImageInfo; - struct Color; - struct GlyphKey; - class GlyphCache; class Skin { @@ -102,34 +97,17 @@ namespace graphics /// clean and destroy ~Skin(); - /// obtain ResourceStyle from id - ResourceStyle const * fromID(uint32_t id); - /// get an identifier from the styleName. - /// return 0xFFFF if this style is not found in Skin. - uint32_t mapSymbol(char const * symbolName); - /// find ruleDef on the texture. + /// obtain Resource from id + Resource const * fromID(uint32_t id); + + /// map Resource::Info on skin /// if found - return id. /// if not - pack and return id. - uint32_t mapPenInfo(PenInfo const & penInfo); - /// map an array of PenInfo on the same skin page - /// returns the completion flag - bool mapPenInfo(PenInfo const * penInfos, uint32_t * styleIDS, size_t count); - /// find brushDef on the texture. - /// if found - return id. - /// if not - pack and return id. - uint32_t mapColor(Color const & c); - /// find glyph identified by GlyphKey on texture - /// if found - return id - /// if not - pack and return id - uint32_t mapGlyph(GlyphKey const & gk, GlyphCache * glyphCache); - /// find circleStyle on texture - /// if found - return id - /// if not - pack and return id - uint32_t mapCircleInfo(CircleInfo const & circleInfo); - /// find imageInfo on texture - /// if found - return id - /// if not - pack and return id - uint32_t mapImageInfo(ImageInfo const & imageInfo); + uint32_t map(Resource::Info const & info); + /// map array of Resource::Info's on skin + bool map(Resource::Info const * const * infos, uint32_t * ids, size_t count); + + uint32_t findInfo(Resource::Info const & info); /// adding function which will be called, when some SkinPage /// is getting cleared. diff --git a/graphics/skin_loader.cpp b/graphics/skin_loader.cpp index f1543c92c1..aa5e62133f 100644 --- a/graphics/skin_loader.cpp +++ b/graphics/skin_loader.cpp @@ -1,8 +1,9 @@ #include "skin.hpp" #include "skin_loader.hpp" #include "resource_manager.hpp" -#include "resource_style.hpp" #include "resource_cache.hpp" +#include "resource.hpp" +#include "icon.hpp" #include "../base/string_utils.hpp" @@ -11,9 +12,6 @@ namespace graphics SkinLoader::SkinLoader(shared_ptr const & resourceManager) : m_id(-1), m_texRect(0, 0, 0, 0), - m_xOffset(0), - m_yOffset(0), - m_xAdvance(0), m_fileName(""), m_resourceManager(resourceManager), m_skin(0) @@ -21,51 +19,60 @@ namespace graphics m_mode.push_back(ERoot); } - void SkinLoader::pushResourceStyle() + void SkinLoader::pushResource() { m_texRect = m2::RectU(0, 0, 0, 0); } - void SkinLoader::popResourceStyle() + void SkinLoader::popResource() { - m_texRect = m2::RectU(m_texX, m_texY, m_texX + m_texWidth, m_texY + m_texHeight); + m_texRect = m2::RectU(m_texX, + m_texY, + m_texX + m_texWidth, + m_texY + m_texHeight); } - void SkinLoader::popPointStyle() + void SkinLoader::popIcon() { - uint32_t id = m_id; - pair > style( - id, shared_ptr(new PointStyle(m_texRect, m_pages.size(), m_styleID))); - m_stylesList.push_back(style); + shared_ptr res( + new Icon(m_texRect, m_caches.size(), Icon::Info(m_resID))); + + pair > p(m_id, res); + m_resourceList.push_back(p); } void SkinLoader::pushPage() { - m_stylesList.clear(); + m_resourceList.clear(); } void SkinLoader::popPage() { - m_pages.push_back(make_shared_ptr(new ResourceCache(m_resourceManager, m_fileName.c_str(), m_pages.size()))); + m_caches.push_back(make_shared_ptr(new ResourceCache(m_resourceManager, m_fileName.c_str(), m_caches.size()))); - TStylesList::iterator prevIt = m_stylesList.end(); + TResourceList::iterator prevIt = m_resourceList.end(); - for (TStylesList::iterator it = m_stylesList.begin(); it != m_stylesList.end(); ++it) + for (TResourceList::iterator it = m_resourceList.begin(); + it != m_resourceList.end(); + ++it) { - m_pages.back()->m_styles[it->first] = it->second; + m_caches.back()->m_resources[it->first] = it->second; - if (it->second->m_cat == ResourceStyle::EPointStyle) - m_pages.back()->m_pointNameMap[static_cast(it->second.get())->m_styleName] = it->first; + if (it->second->m_cat == Resource::EIcon) + { + Icon * icon = static_cast(it->second.get()); + m_caches.back()->m_infos[&icon->m_info] = it->first; + } - if (prevIt != m_stylesList.end()) - m_stylesList.erase(prevIt); + if (prevIt != m_resourceList.end()) + m_resourceList.erase(prevIt); prevIt = it; } } void SkinLoader::popSkin() { - m_skin = new Skin(m_resourceManager, m_pages); + m_skin = new Skin(m_resourceManager, m_caches); } #define PUSH_MODE(mode, name) \ @@ -95,9 +102,8 @@ namespace graphics { PUSH_MODE(ESkin, "skin"); PUSH_MODE_EX(EPage, "page", pushPage); - PUSH_MODE(EPointStyle, "symbolStyle"); - PUSH_MODE(ELineStyle, "lineStyle"); - PUSH_MODE_EX(EResourceStyle, "resourceStyle", pushResourceStyle); + PUSH_MODE(EIcon, "symbolStyle"); + PUSH_MODE_EX(EResource, "resourceStyle", pushResource); return true; } @@ -105,9 +111,8 @@ namespace graphics { POP_MODE_EX(ESkin, "skin", popSkin); POP_MODE_EX(EPage, "page", popPage); - POP_MODE_EX(EPointStyle, "symbolStyle", popPointStyle); - POP_MODE(ELineStyle, "lineStyle"); - POP_MODE_EX(EResourceStyle, "resourceStyle", popResourceStyle); + POP_MODE_EX(EIcon, "symbolStyle", popIcon); + POP_MODE_EX(EResource, "resourceStyle", popResource); } int StrToInt(string const & s) @@ -127,13 +132,13 @@ namespace graphics if (attr == "file") m_fileName = value; break; - case EPointStyle: + case EIcon: if (attr == "id") m_id = StrToInt(value); else if (attr == "name") - m_styleID = value; + m_resID = value; break; - case EResourceStyle: + case EResource: if (attr == "x") m_texX = StrToInt(value); else if (attr == "y") diff --git a/graphics/skin_loader.hpp b/graphics/skin_loader.hpp index e132bff3f0..096d3b9d4f 100644 --- a/graphics/skin_loader.hpp +++ b/graphics/skin_loader.hpp @@ -38,8 +38,7 @@ namespace graphics class ResourceManager; class ResourceCache; - struct ResourceStyle; - struct GlyphStyle; + struct Resource; class SkinLoader { @@ -50,10 +49,8 @@ namespace graphics ERoot, EPage, ESkin, - EFontStyle, - EPointStyle, - ELineStyle, - EResourceStyle + EIcon, + EResource }; list m_mode; @@ -66,27 +63,19 @@ namespace graphics uint32_t m_texHeight; m2::RectU m_texRect; -/// glyphInfo and glyphMaskInfo specific parameters - int8_t m_xOffset; - int8_t m_yOffset; - int8_t m_xAdvance; - - shared_ptr m_glyphInfo; - shared_ptr m_glyphMaskInfo; - /// pointStyle-specific parameters - string m_styleID; + string m_resID; /// skin-specific parameters - vector > m_pages; + vector > m_caches; /// skin-page specific parameters string m_fileName; - typedef list > > TStylesList; + typedef list > > TResourceList; - TStylesList m_stylesList; + TResourceList m_resourceList; shared_ptr m_resourceManager; Skin * m_skin; @@ -100,13 +89,13 @@ namespace graphics void AddAttr(string const & attribute, string const & value); void CharData(string const &) {} - void popPointStyle(); + void popIcon(); void popSkin(); void pushPage(); void popPage(); - void pushResourceStyle(); - void popResourceStyle(); + void pushResource(); + void popResource(); Skin * skin(); }; diff --git a/graphics/symbol_element.cpp b/graphics/symbol_element.cpp index b9a382f20c..b9823a3dce 100644 --- a/graphics/symbol_element.cpp +++ b/graphics/symbol_element.cpp @@ -1,7 +1,8 @@ #include "../base/logging.hpp" #include "symbol_element.hpp" -#include "resource_style.hpp" +#include "resource.hpp" +#include "icon.hpp" #include "overlay_renderer.hpp" #include "skin.hpp" @@ -9,24 +10,24 @@ namespace graphics { SymbolElement::SymbolElement(Params const & p) : base_t(p), - m_symbolName(p.m_symbolName), + m_info(p.m_info), m_symbolRect(0, 0, 0, 0) { - uint32_t styleID = p.m_skin->mapSymbol(m_symbolName.c_str()); - ResourceStyle const * style = p.m_skin->fromID(styleID); + uint32_t resID = p.m_skin->findInfo(m_info); + Resource const * res = p.m_skin->fromID(resID); - if (style == 0) + if (res == 0) { - LOG(LINFO, ("POI ", m_symbolName, " wasn't found on the current skin")); + LOG(LINFO, ("POI ", m_info.m_name, " wasn't found on the current skin")); return; } - m_symbolRect = style->m_texRect; + m_symbolRect = res->m_texRect; } SymbolElement::SymbolElement(SymbolElement const & se, math::Matrix const & m) : base_t(se), - m_symbolName(se.m_symbolName), + m_info(se.m_info), m_symbolRect(se.m_symbolRect) { setPivot(se.pivot() * m); @@ -58,22 +59,22 @@ namespace graphics if (!isNeedRedraw()) return; - uint32_t styleID = r->skin()->mapSymbol(m_symbolName.c_str()); - ResourceStyle const * style = r->skin()->fromID(styleID); + uint32_t resID = r->skin()->findInfo(m_info); + Resource const * res = r->skin()->fromID(resID); - if (style == 0) + if (res == 0) { - LOG(LINFO, ("POI(", m_symbolName, ") wasn't found on the current skin")); + LOG(LINFO, ("POI(", m_info.m_name, ") wasn't found on the current skin")); return; } - if (style->m_texRect != m_symbolRect) + if (res->m_texRect != m_symbolRect) { - LOG(LINFO, ("POI(", m_symbolName, ") rects do not match.")); + LOG(LINFO, ("POI(", m_info.m_name, ") rects do not match.")); return; } - m2::RectI texRect(style->m_texRect); + m2::RectI texRect(res->m_texRect); texRect.Inflate(-1, -1); m2::PointD posPt = tieRect(m2::RectD(texRect), m); @@ -84,7 +85,7 @@ namespace graphics texRect.minX(), texRect.minY(), texRect.maxX(), texRect.maxY(), posPt.x, posPt.y, posPt.x + texRect.SizeX(), posPt.y + texRect.SizeY(), graphics::maxDepth - 2, - style->m_pipelineID); + res->m_pipelineID); } int SymbolElement::visualRank() const diff --git a/graphics/symbol_element.hpp b/graphics/symbol_element.hpp index 11d260f1aa..0e206988bd 100644 --- a/graphics/symbol_element.hpp +++ b/graphics/symbol_element.hpp @@ -1,18 +1,17 @@ #pragma once #include "overlay_element.hpp" +#include "icon.hpp" namespace graphics { - struct ResourceStyle; class Skin; - class ResourceStyleCache; class SymbolElement : public OverlayElement { private: - string m_symbolName; + Icon::Info m_info; m2::RectU m_symbolRect; mutable vector m_boundRects; @@ -26,7 +25,7 @@ namespace graphics struct Params : public base_t::Params { Skin * m_skin; - string m_symbolName; + Icon::Info m_info; }; SymbolElement(Params const & p); @@ -35,7 +34,7 @@ namespace graphics vector const & boundRects() const; void draw(OverlayRenderer * s, math::Matrix const & m) const; - uint32_t styleID() const; + uint32_t resID() const; int visualRank() const; diff --git a/graphics/text_element.cpp b/graphics/text_element.cpp index 5dece92cd4..2c8fdab4e1 100644 --- a/graphics/text_element.cpp +++ b/graphics/text_element.cpp @@ -4,7 +4,8 @@ #include "resource_cache.hpp" #include "resource_manager.hpp" #include "overlay_renderer.hpp" -#include "resource_style.hpp" +#include "glyph.hpp" +#include "resource.hpp" #include "../base/logging.hpp" @@ -106,8 +107,8 @@ namespace graphics fontDesc.m_size, fontDesc.m_isMasked, fontDesc.m_isMasked ? fontDesc.m_maskColor : fontDesc.m_color); - uint32_t const glyphID = skin->mapGlyph(glyphKey, screen->glyphCache()); - GlyphStyle const * glyphStyle = static_cast(skin->fromID(glyphID)); + uint32_t const glyphID = skin->map(Glyph::Info(glyphKey, screen->glyphCache())); + Glyph const * glyph = static_cast(skin->fromID(glyphID)); m2::PointD glyphPt; ang::AngleD glyphAngle; @@ -120,14 +121,14 @@ namespace graphics offsPt.x -= fullPt.x - floor(fullPt.x); offsPt.y -= fullPt.y - floor(fullPt.y); - screen->drawStraightGlyph(pv, offsPt, glyphStyle, depth); + screen->drawStraightGlyph(pv, offsPt, glyph, depth); } else { glyphPt = (pv + offs + elem.m_pt) * m; glyphAngle = ang::AngleD(elem.m_angle.val() + deltaA); - screen->drawGlyph(glyphPt, m2::PointD(0.0, 0.0), glyphAngle, 0, glyphStyle, depth); + screen->drawGlyph(glyphPt, m2::PointD(0.0, 0.0), glyphAngle, 0, glyph, depth); } } } diff --git a/graphics/text_renderer.cpp b/graphics/text_renderer.cpp index d7fba77246..6b6fcdc8bd 100644 --- a/graphics/text_renderer.cpp +++ b/graphics/text_renderer.cpp @@ -1,7 +1,7 @@ #include "text_renderer.hpp" #include "overlay.hpp" -#include "resource_style.hpp" #include "resource_manager.hpp" +#include "glyph.hpp" #include "../geometry/angles.hpp" @@ -23,11 +23,11 @@ namespace graphics void TextRenderer::drawStraightGlyph(m2::PointD const & ptPivot, m2::PointD const & ptOffs, - GlyphStyle const * p, + Glyph const * p, float depth) { - float x0 = ptOffs.x + (p->m_gi->m_metrics.m_xOffset - 1); - float y1 = ptOffs.y - (p->m_gi->m_metrics.m_yOffset - 1); + float x0 = ptOffs.x + (p->m_info.m_metrics.m_xOffset - 1); + float y1 = ptOffs.y - (p->m_info.m_metrics.m_yOffset - 1); float y0 = y1 - (p->m_texRect.SizeY() - 2); float x1 = x0 + (p->m_texRect.SizeX() - 2); @@ -47,11 +47,11 @@ namespace graphics m2::PointD const & ptGlyph, ang::AngleD const & angle, float /*blOffset*/, - GlyphStyle const * p, + Glyph const * p, double depth) { - float x0 = ptGlyph.x + (p->m_gi->m_metrics.m_xOffset - 1); - float y1 = ptGlyph.y - (p->m_gi->m_metrics.m_yOffset - 1); + float x0 = ptGlyph.x + (p->m_info.m_metrics.m_xOffset - 1); + float y1 = ptGlyph.y - (p->m_info.m_metrics.m_yOffset - 1); float y0 = y1 - (p->m_texRect.SizeY() - 2); float x1 = x0 + (p->m_texRect.SizeX() - 2); diff --git a/graphics/text_renderer.hpp b/graphics/text_renderer.hpp index 5d85b531ee..f1a4759f19 100644 --- a/graphics/text_renderer.hpp +++ b/graphics/text_renderer.hpp @@ -12,6 +12,8 @@ namespace graphics { + class Glyph; + class TextRenderer : public ImageRenderer { private: @@ -32,14 +34,14 @@ namespace graphics void drawStraightGlyph(m2::PointD const & ptOrg, m2::PointD const & ptGlyph, - GlyphStyle const * p, + Glyph const * p, float depth); void drawGlyph(m2::PointD const & ptOrg, m2::PointD const & ptGlyph, ang::AngleD const & angle, float blOffset, - GlyphStyle const * p, + Glyph const * p, double depth); diff --git a/map/compass_arrow.cpp b/map/compass_arrow.cpp index 78aa1743fd..7cf6a49070 100644 --- a/map/compass_arrow.cpp +++ b/map/compass_arrow.cpp @@ -12,6 +12,7 @@ #include "../graphics/display_list.hpp" #include "../graphics/screen.hpp" #include "../graphics/skin.hpp" +#include "../graphics/pen.hpp" CompassArrow::CompassArrow(Params const & p) : base_t(p), @@ -121,9 +122,9 @@ void CompassArrow::cache() m2::PointD(halfW, 0) }; - graphics::PenInfo const outlinePenInfo(graphics::Color(0x66, 0x66, 0x66, 0xcc), 1, 0, 0, 0); + graphics::Pen::Info const outlinePenInfo(graphics::Color(0x66, 0x66, 0x66, 0xcc), 1, 0, 0, 0); - cacheScreen->drawPath(outlinePts, sizeof(outlinePts) / sizeof(m2::PointD), 0, cacheScreen->skin()->mapPenInfo(outlinePenInfo), depth()); + cacheScreen->drawPath(outlinePts, sizeof(outlinePts) / sizeof(m2::PointD), 0, cacheScreen->skin()->map(outlinePenInfo), depth()); cacheScreen->setDisplayList(0); cacheScreen->endFrame(); diff --git a/map/drawer.cpp b/map/drawer.cpp index 59a508c18b..933ee8b61e 100644 --- a/map/drawer.cpp +++ b/map/drawer.cpp @@ -117,23 +117,26 @@ void Drawer::drawSymbol(m2::PointD const & pt, string const & symbolName, void Drawer::drawCircle(m2::PointD const & pt, rule_ptr_t pRule, graphics::EPosition pos, int depth, FeatureID const & id) { - graphics::CircleInfo ci; + graphics::Circle::Info ci; ConvertStyle(pRule->GetCircle(), m_visualScale, ci); m_pScreen->drawCircle(pt, ci, pos, depth); } -void Drawer::drawSymbol(m2::PointD const & pt, rule_ptr_t pRule, - graphics::EPosition pos, int depth, FeatureID const & id) +void Drawer::drawSymbol(m2::PointD const & pt, + rule_ptr_t pRule, + graphics::EPosition pos, + int depth, + FeatureID const & id) { - string name; - ConvertStyle(pRule->GetSymbol(), name); + graphics::Icon::Info info; + ConvertStyle(pRule->GetSymbol(), info); graphics::SymbolElement::Params params; params.m_depth = depth; params.m_position = pos; params.m_pivot = pt; - params.m_symbolName.swap(name); + params.m_info = info; params.m_userInfo.m_mwmID = id.first; params.m_userInfo.m_offset = id.second; @@ -153,8 +156,9 @@ void Drawer::drawPath(di::PathInfo const & info, di::DrawRule const * rules, siz } } - buffer_vector penInfos(count); - buffer_vector styleIDs(count); + buffer_vector penInfos(count); + buffer_vector infos(count); + buffer_vector resIDs(count); if (flag) { @@ -163,17 +167,19 @@ void Drawer::drawPath(di::PathInfo const & info, di::DrawRule const * rules, siz { ConvertStyle(rules[i].m_rule->GetLine(), m_visualScale, penInfos[i]); + infos[i] = &penInfos[i]; + if (rules[i].m_transparent) penInfos[i].m_color.a = 100; - styleIDs[i] = m_pSkin->invalidHandle(); + resIDs[i] = m_pSkin->invalidHandle(); } // map array of pens - if (m_pSkin->mapPenInfo(&penInfos[0], &styleIDs[0], count)) + if (m_pSkin->map(&infos[0], &resIDs[0], count)) { for (size_t i = 0; i < count; ++i) - rules[i].SetID(ThreadSlot(), styleIDs[i]); + rules[i].SetID(ThreadSlot(), resIDs[i]); } else { @@ -192,9 +198,10 @@ void Drawer::drawArea(vector const & pts, rule_ptr_t pRule, int dept // DO NOT cache 'id' in pRule, because one rule can use in drawPath and drawArea. // Leave CBaseRule::m_id for drawPath. mapColor working fast enough. - graphics::Color color; - ConvertStyle(pRule->GetArea(), color); - uint32_t const id = m_pSkin->mapColor(color); + graphics::Brush::Info info; + ConvertStyle(pRule->GetArea(), info); + + uint32_t const id = m_pSkin->map(info); ASSERT ( id != -1, () ); m_pScreen->drawTrianglesList(&pts[0], pts.size()/*, res*/, id, depth); diff --git a/map/information_display.cpp b/map/information_display.cpp index 04224f3ce2..eeca55f888 100644 --- a/map/information_display.cpp +++ b/map/information_display.cpp @@ -11,7 +11,7 @@ #include "../graphics/defines.hpp" #include "../graphics/skin.hpp" -#include "../graphics/pen_info.hpp" +#include "../graphics/pen.hpp" #include "../graphics/straight_text_element.hpp" #include "../base/string_utils.hpp" diff --git a/map/location_state.cpp b/map/location_state.cpp index 4b976d2186..07bcc8d718 100644 --- a/map/location_state.cpp +++ b/map/location_state.cpp @@ -7,6 +7,8 @@ #include "../graphics/display_list.hpp" #include "../graphics/skin.hpp" +#include "../graphics/brush.hpp" +#include "../graphics/pen.hpp" #include "../anim/controller.hpp" #include "../anim/angle_interpolation.hpp" @@ -240,7 +242,7 @@ namespace location graphics::Color const borderColor = color(state); - uint32_t penStyle = skin->mapPenInfo(graphics::PenInfo(borderColor, 1 * k, 0, 0, 0)); + uint32_t penStyle = skin->map(graphics::Pen::Info(borderColor, 1 * k, 0, 0, 0)); cacheScreen->drawPath(ptsD, ARRAY_SIZE(ptsD), 0, penStyle, depth()); @@ -278,10 +280,10 @@ namespace location min(255, (baseColor.b * 5) >> 2), baseColor.a); cacheScreen->drawTrianglesList(&pts[0], 3, - skin->mapColor(baseColor), + skin->map(graphics::Brush::Info(baseColor)), depth()); cacheScreen->drawTrianglesList(&pts[1], 3, - skin->mapColor(lightColor), + skin->map(graphics::Brush::Info(lightColor)), depth()); cacheScreen->setDisplayList(0); diff --git a/map/proto_to_styles.cpp b/map/proto_to_styles.cpp index 0f64ddfff8..a5054a553f 100644 --- a/map/proto_to_styles.cpp +++ b/map/proto_to_styles.cpp @@ -24,7 +24,7 @@ namespace } -void ConvertStyle(LineDefProto const * pSrc, double scale, graphics::PenInfo & dest) +void ConvertStyle(LineDefProto const * pSrc, double scale, graphics::Pen::Info & dest) { double offset = 0.0; vector v; @@ -42,30 +42,30 @@ void ConvertStyle(LineDefProto const * pSrc, double scale, graphics::PenInfo & d offset = dd.offset() * scale; } - dest = graphics::PenInfo( + dest = graphics::Pen::Info( ConvertColor(pSrc->color()), ConvertWidth(pSrc->width(), scale), v.empty() ? 0 : &v[0], v.size(), offset); } -void ConvertStyle(AreaRuleProto const * pSrc, graphics::Color & dest) +void ConvertStyle(AreaRuleProto const * pSrc, graphics::Brush::Info & dest) { - dest = ConvertColor(pSrc->color()); + dest.m_color = ConvertColor(pSrc->color()); } -void ConvertStyle(SymbolRuleProto const * pSrc, string & dest) +void ConvertStyle(SymbolRuleProto const * pSrc, graphics::Icon::Info & dest) { - dest = pSrc->name(); + dest.m_name = pSrc->name(); } -void ConvertStyle(CircleRuleProto const * pSrc, double scale, graphics::CircleInfo & dest) +void ConvertStyle(CircleRuleProto const * pSrc, double scale, graphics::Circle::Info & dest) { - dest = graphics::CircleInfo(min(max(pSrc->radius(), 3.0), 6.0) * scale, + dest = graphics::Circle::Info(min(max(pSrc->radius(), 3.0), 6.0) * scale, ConvertColor(pSrc->color())); if (pSrc->has_border()) { - graphics::PenInfo pen; + graphics::Pen::Info pen; ConvertStyle(&(pSrc->border()), scale, pen); dest.m_isOutlined = true; diff --git a/map/proto_to_styles.hpp b/map/proto_to_styles.hpp index 7c9f4a1bc0..85f5c3ae42 100644 --- a/map/proto_to_styles.hpp +++ b/map/proto_to_styles.hpp @@ -1,21 +1,21 @@ #pragma once -#include "../graphics/pen_info.hpp" -#include "../graphics/circle_info.hpp" +#include "../graphics/pen.hpp" +#include "../graphics/brush.hpp" +#include "../graphics/icon.hpp" +#include "../graphics/circle.hpp" #include "../graphics/font_desc.hpp" - class LineDefProto; class AreaRuleProto; class SymbolRuleProto; class CaptionDefProto; class CircleRuleProto; - -void ConvertStyle(LineDefProto const * pSrc, double scale, graphics::PenInfo & dest); -void ConvertStyle(AreaRuleProto const * pSrc, graphics::Color & dest); -void ConvertStyle(SymbolRuleProto const * pSrc, string & dest); -void ConvertStyle(CircleRuleProto const * pSrc, double scale, graphics::CircleInfo & dest); +void ConvertStyle(LineDefProto const * pSrc, double scale, graphics::Pen::Info & dest); +void ConvertStyle(AreaRuleProto const * pSrc, graphics::Brush::Info & dest); +void ConvertStyle(SymbolRuleProto const * pSrc, graphics::Icon::Info & dest); +void ConvertStyle(CircleRuleProto const * pSrc, double scale, graphics::Circle::Info & dest); void ConvertStyle(CaptionDefProto const * pSrc, double scale, graphics::FontDesc & dest); uint8_t GetFontSize(CaptionDefProto const * pSrc); diff --git a/map/ruler.cpp b/map/ruler.cpp index be0a1290f1..5c4fd891b9 100644 --- a/map/ruler.cpp +++ b/map/ruler.cpp @@ -5,6 +5,7 @@ #include "../graphics/overlay_renderer.hpp" #include "../graphics/skin.hpp" +#include "../graphics/pen.hpp" #include "../indexer/mercator.hpp" #include "../geometry/distance_on_sphere.hpp" @@ -274,7 +275,7 @@ void Ruler::draw(graphics::OverlayRenderer * s, math::Matrix const { s->drawPath( &m_path[0], m_path.size(), 0, - s->skin()->mapPenInfo(graphics::PenInfo(graphics::Color(0, 0, 0, 0x99), 4 * m_visualScale, 0, 0, 0)), + s->skin()->map(graphics::Pen::Info(graphics::Color(0, 0, 0, 0x99), 4 * m_visualScale, 0, 0, 0)), depth()); if (position() & graphics::EPosLeft) diff --git a/qt_tstfrm/tstwidgets.cpp b/qt_tstfrm/tstwidgets.cpp index 283b4a4b87..5120ca837a 100644 --- a/qt_tstfrm/tstwidgets.cpp +++ b/qt_tstfrm/tstwidgets.cpp @@ -40,8 +40,6 @@ void GLDrawWidget::initializeGL() m_primaryContext = make_shared_ptr(new qt::gl::RenderContext(this)); - m_primaryContext->startThreadDrawing(0); - graphics::ResourceManager::Params rmp; rmp.m_rtFormat = graphics::Data8Bpp; @@ -112,6 +110,9 @@ void GLDrawWidget::initializeGL() m_resourceManager.reset(new graphics::ResourceManager(rmp)); + m_primaryContext->setResourceManager(m_resourceManager); + m_primaryContext->startThreadDrawing(0); + Platform::FilesList fonts; GetPlatform().GetFontNames(fonts); m_resourceManager->addFonts(fonts);