forked from organicmaps/organicmaps
introduced CircleElement. fixes #363.
This commit is contained in:
parent
dcfef49bae
commit
93d0eb1570
24 changed files with 759 additions and 716 deletions
|
@ -102,30 +102,17 @@ void DrawerYG::drawSymbol(m2::PointD const & pt, string const & symbolName, yg::
|
|||
|
||||
void DrawerYG::drawCircle(m2::PointD const & pt, rule_ptr_t pRule, yg::EPosition pos, int depth)
|
||||
{
|
||||
uint32_t id = pRule->GetID(m_threadID);
|
||||
if (id == drule::BaseRule::empty_id)
|
||||
{
|
||||
double const radius = min(max(pRule->GetRadius() * m_scale, 3.0), 6.0) * m_visualScale;
|
||||
unsigned char const alpha = pRule->GetAlpha();
|
||||
int const lineC = pRule->GetColor();
|
||||
double const radius = min(max(pRule->GetRadius() * m_scale, 3.0), 6.0) * m_visualScale;
|
||||
unsigned char const alpha = pRule->GetAlpha();
|
||||
int const lineC = pRule->GetColor();
|
||||
|
||||
id = m_pSkin->mapCircleInfo(yg::CircleInfo(
|
||||
radius,
|
||||
yg::Color::fromXRGB(pRule->GetFillColor(), alpha),
|
||||
lineC != -1,
|
||||
(lineC != -1) ? min(max(pRule->GetWidth() * m_scale * m_visualScale, 1.0), 3.0) : 1.0,
|
||||
yg::Color::fromXRGB(lineC, alpha)));
|
||||
yg::CircleInfo ci(radius,
|
||||
yg::Color::fromXRGB(pRule->GetFillColor(), alpha),
|
||||
lineC != -1,
|
||||
(lineC != -1) ? min(max(pRule->GetWidth() * m_scale * m_visualScale, 1.0), 3.0) : 1.0,
|
||||
yg::Color::fromXRGB(lineC, alpha));
|
||||
|
||||
if (id != drule::BaseRule::empty_id)
|
||||
pRule->SetID(m_threadID, id);
|
||||
else
|
||||
{
|
||||
//ASSERT ( false, ("Can't find symbol by id = ", (name)) );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
m_pScreen->drawCircle(pt, id, pos, depth);
|
||||
m_pScreen->drawCircle(pt, ci, pos, depth);
|
||||
}
|
||||
|
||||
void DrawerYG::drawSymbol(m2::PointD const & pt, rule_ptr_t pRule, yg::EPosition pos, int depth)
|
||||
|
|
27
yg/agg_traits.hpp
Normal file
27
yg/agg_traits.hpp
Normal file
|
@ -0,0 +1,27 @@
|
|||
#pragma once
|
||||
|
||||
#include <agg_pixfmt_rgba.h>
|
||||
#include <agg_pixfmt_rgb_packed.h>
|
||||
#include <agg_renderer_scanline.h>
|
||||
#include <agg_rasterizer_scanline_aa.h>
|
||||
#include <agg_scanline_u.h>
|
||||
#include <agg_ellipse.h>
|
||||
|
||||
#include "data_formats.hpp"
|
||||
|
||||
template <typename Traits>
|
||||
struct AggTraits
|
||||
{
|
||||
};
|
||||
|
||||
template <>
|
||||
struct AggTraits<yg::RGBA8Traits>
|
||||
{
|
||||
typedef agg::pixfmt_rgba32 pixfmt_t;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct AggTraits<yg::RGBA4Traits>
|
||||
{
|
||||
typedef agg::pixfmt_rgb4444 pixfmt_t;
|
||||
};
|
99
yg/circle_element.cpp
Normal file
99
yg/circle_element.cpp
Normal file
|
@ -0,0 +1,99 @@
|
|||
#include "circle_element.hpp"
|
||||
|
||||
#include "styles_cache.hpp"
|
||||
#include "overlay_renderer.hpp"
|
||||
#include "resource_style.hpp"
|
||||
#include "skin.hpp"
|
||||
|
||||
namespace yg
|
||||
{
|
||||
CircleElement::CircleElement(Params const & p)
|
||||
: base_t(p),
|
||||
m_ci(p.m_ci)
|
||||
{}
|
||||
|
||||
|
||||
CircleElement::CircleElement(CircleElement const & ce, math::Matrix<double, 3, 3> const & m)
|
||||
: base_t(ce),
|
||||
m_ci(ce.m_ci)
|
||||
{
|
||||
setPivot(ce.pivot() * m);
|
||||
}
|
||||
|
||||
vector<m2::AnyRectD> const & CircleElement::boundRects() const
|
||||
{
|
||||
if (isDirtyRect())
|
||||
{
|
||||
m_boundRects.clear();
|
||||
m_boundRects.push_back(boundRect());
|
||||
setIsDirtyRect(false);
|
||||
}
|
||||
|
||||
return m_boundRects;
|
||||
}
|
||||
|
||||
m2::AnyRectD const CircleElement::boundRect() const
|
||||
{
|
||||
m2::RectI texRect(m2::PointI(0, 0), m2::PointI(m_ci.patternSize()));
|
||||
texRect.Inflate(-1, -1);
|
||||
|
||||
m2::PointD posPt = tieRect(m2::RectD(texRect), math::Identity<double, 3>());
|
||||
|
||||
return m2::AnyRectD(m2::RectD(posPt, posPt + m2::PointD(texRect.SizeX(), texRect.SizeY())));
|
||||
}
|
||||
|
||||
void CircleElement::draw(gl::OverlayRenderer * r, math::Matrix<double, 3, 3> const & m) const
|
||||
{
|
||||
if (!isNeedRedraw())
|
||||
return;
|
||||
|
||||
uint32_t styleID = r->skin()->mapCircleInfo(m_ci);
|
||||
|
||||
ResourceStyle const * style = r->skin()->fromID(styleID);
|
||||
|
||||
m2::RectI texRect(style->m_texRect);
|
||||
texRect.Inflate(-1, -1);
|
||||
|
||||
m2::PointD posPt = tieRect(m2::RectD(texRect), m);
|
||||
|
||||
r->drawTexturedPolygon(m2::PointD(0.0, 0.0), 0.0,
|
||||
texRect.minX(), texRect.minY(), texRect.maxX(), texRect.maxY(),
|
||||
posPt.x, posPt.y, posPt.x + texRect.SizeX(), posPt.y + texRect.SizeY(),
|
||||
yg::maxDepth,
|
||||
style->m_pipelineID);
|
||||
}
|
||||
|
||||
int CircleElement::visualRank() const
|
||||
{
|
||||
return 500;
|
||||
}
|
||||
|
||||
void CircleElement::map(StylesCache * stylesCache) const
|
||||
{
|
||||
shared_ptr<SkinPage> const & skinPage = stylesCache->cachePage();
|
||||
|
||||
ASSERT(skinPage->hasRoom(m_ci), ());
|
||||
|
||||
skinPage->mapCircleInfo(m_ci);
|
||||
}
|
||||
|
||||
bool CircleElement::find(StylesCache * stylesCache) const
|
||||
{
|
||||
shared_ptr<SkinPage> const & skinPage = stylesCache->cachePage();
|
||||
|
||||
return skinPage->findCircleInfo(m_ci) != 0x00FFFFFF;
|
||||
}
|
||||
|
||||
void CircleElement::fillUnpacked(StylesCache * stylesCache, vector<m2::PointU> & v) const
|
||||
{
|
||||
shared_ptr<SkinPage> const & skinPage = stylesCache->cachePage();
|
||||
|
||||
if (skinPage->findCircleInfo(m_ci) == 0x00FFFFFF)
|
||||
v.push_back(m_ci.patternSize());
|
||||
}
|
||||
|
||||
OverlayElement * CircleElement::clone(math::Matrix<double, 3, 3> const & m) const
|
||||
{
|
||||
return new CircleElement(*this, m);
|
||||
}
|
||||
}
|
42
yg/circle_element.hpp
Normal file
42
yg/circle_element.hpp
Normal file
|
@ -0,0 +1,42 @@
|
|||
#pragma once
|
||||
|
||||
#include "overlay_element.hpp"
|
||||
#include "circle_info.hpp"
|
||||
|
||||
namespace yg
|
||||
{
|
||||
class CircleElement : public OverlayElement
|
||||
{
|
||||
private:
|
||||
|
||||
yg::CircleInfo m_ci;
|
||||
|
||||
mutable vector<m2::AnyRectD> m_boundRects;
|
||||
|
||||
m2::AnyRectD const boundRect() const;
|
||||
|
||||
public:
|
||||
|
||||
typedef OverlayElement base_t;
|
||||
|
||||
struct Params : public base_t::Params
|
||||
{
|
||||
yg::CircleInfo m_ci;
|
||||
};
|
||||
|
||||
CircleElement(Params const & p);
|
||||
CircleElement(CircleElement const & ce, math::Matrix<double, 3, 3> const & m);
|
||||
|
||||
vector<m2::AnyRectD> const & boundRects() const;
|
||||
|
||||
void draw(gl::OverlayRenderer * s, math::Matrix<double, 3, 3> const & m) const;
|
||||
|
||||
void map(StylesCache * stylesCache) const;
|
||||
void fillUnpacked(StylesCache * stylesCache, vector<m2::PointU> & v) const;
|
||||
bool find(StylesCache * stylesCache) const;
|
||||
|
||||
int visualRank() const;
|
||||
|
||||
OverlayElement * clone(math::Matrix<double, 3, 3> const & m) const;
|
||||
};
|
||||
}
|
|
@ -34,4 +34,10 @@ namespace yg
|
|||
return l.m_outlineWidth < r.m_outlineWidth;
|
||||
return l.m_outlineColor < r.m_outlineColor;
|
||||
}
|
||||
|
||||
m2::PointU const CircleInfo::patternSize() const
|
||||
{
|
||||
unsigned r = m_isOutlined ? m_radius + m_outlineWidth : m_radius;
|
||||
return m2::PointU(r * 2 + 4, r * 2 + 4);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
#include "color.hpp"
|
||||
|
||||
#include "../geometry/point2d.hpp"
|
||||
|
||||
namespace yg
|
||||
{
|
||||
struct CircleInfo
|
||||
|
@ -19,6 +21,8 @@ namespace yg
|
|||
bool isOutlined = false,
|
||||
double outlineWidth = 1,
|
||||
Color const & outlineColor = Color(255, 255, 255, 255));
|
||||
|
||||
m2::PointU const patternSize() const;
|
||||
};
|
||||
|
||||
bool operator< (CircleInfo const & l, CircleInfo const & r);
|
||||
|
|
149
yg/circle_style.cpp
Normal file
149
yg/circle_style.cpp
Normal file
|
@ -0,0 +1,149 @@
|
|||
#include "resource_style.hpp"
|
||||
|
||||
#include "agg_traits.hpp"
|
||||
#include "data_formats.hpp"
|
||||
|
||||
namespace yg
|
||||
{
|
||||
CircleStyle::CircleStyle(m2::RectU const & texRect, int pipelineID, yg::CircleInfo const & ci)
|
||||
: ResourceStyle(ECircleStyle, texRect, pipelineID),
|
||||
m_ci(ci)
|
||||
{}
|
||||
|
||||
void CircleStyle::render(void * dst)
|
||||
{
|
||||
yg::CircleInfo & circleInfo = m_ci;
|
||||
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()
|
||||
);
|
||||
|
||||
agg::rgba8 aggColor(circleInfo.m_color.r,
|
||||
circleInfo.m_color.g,
|
||||
circleInfo.m_color.b,
|
||||
circleInfo.m_color.a);
|
||||
|
||||
agg::rgba8 aggOutlineColor(circleInfo.m_outlineColor.r,
|
||||
circleInfo.m_outlineColor.g,
|
||||
circleInfo.m_outlineColor.b,
|
||||
circleInfo.m_outlineColor.a);
|
||||
|
||||
circleInfo.m_color /= DATA_TRAITS::channelScaleFactor;
|
||||
|
||||
DATA_TRAITS::pixel_t gilColorTranslucent;
|
||||
|
||||
gil::get_color(gilColorTranslucent, gil::red_t()) = circleInfo.m_color.r;
|
||||
gil::get_color(gilColorTranslucent, gil::green_t()) = circleInfo.m_color.g;
|
||||
gil::get_color(gilColorTranslucent, gil::blue_t()) = circleInfo.m_color.b;
|
||||
gil::get_color(gilColorTranslucent, gil::alpha_t()) = 0;
|
||||
|
||||
circleInfo.m_outlineColor /= DATA_TRAITS::channelScaleFactor;
|
||||
|
||||
DATA_TRAITS::pixel_t gilOutlineColorTranslucent;
|
||||
|
||||
gil::get_color(gilOutlineColorTranslucent, gil::red_t()) = circleInfo.m_outlineColor.r;
|
||||
gil::get_color(gilOutlineColorTranslucent, gil::green_t()) = circleInfo.m_outlineColor.g;
|
||||
gil::get_color(gilOutlineColorTranslucent, gil::blue_t()) = circleInfo.m_outlineColor.b;
|
||||
gil::get_color(gilOutlineColorTranslucent, gil::alpha_t()) = 0;
|
||||
|
||||
DATA_TRAITS::pixel_t gilColor = gilColorTranslucent;
|
||||
gil::get_color(gilColor, gil::alpha_t()) = circleInfo.m_color.a;
|
||||
|
||||
DATA_TRAITS::pixel_t gilOutlineColor = gilOutlineColorTranslucent;
|
||||
gil::get_color(gilOutlineColor, gil::alpha_t()) = circleInfo.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<DATA_TRAITS>::pixfmt_t agg_pixfmt_t;
|
||||
|
||||
agg_pixfmt_t pixfmt(buf);
|
||||
agg::renderer_base<agg_pixfmt_t> rbase(pixfmt);
|
||||
|
||||
if (circleInfo.m_isOutlined)
|
||||
gil::fill_pixels(v, gilOutlineColorTranslucent);
|
||||
else
|
||||
gil::fill_pixels(v, gilColorTranslucent);
|
||||
|
||||
m2::PointD center(circleInfo.patternSize());
|
||||
center *= 0.5;
|
||||
|
||||
agg::scanline_u8 s;
|
||||
agg::rasterizer_scanline_aa<> rasterizer;
|
||||
|
||||
agg::ellipse ell;
|
||||
|
||||
ell.init(center.x,
|
||||
center.y,
|
||||
circleInfo.m_isOutlined ? circleInfo.m_radius + circleInfo.m_outlineWidth : circleInfo.m_radius,
|
||||
circleInfo.m_isOutlined ? circleInfo.m_radius + circleInfo.m_outlineWidth : circleInfo.m_radius,
|
||||
100);
|
||||
|
||||
rasterizer.add_path(ell);
|
||||
|
||||
agg::render_scanlines_aa_solid(rasterizer,
|
||||
s,
|
||||
rbase,
|
||||
circleInfo.m_isOutlined ? aggOutlineColor : aggColor);
|
||||
|
||||
DATA_TRAITS::pixel_t px = circleInfo.m_isOutlined ? gilOutlineColor : gilColor;
|
||||
|
||||
/// making alpha channel 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());
|
||||
|
||||
float fAlpha = alpha / (float)DATA_TRAITS::maxChannelVal;
|
||||
|
||||
if (alpha != 0)
|
||||
{
|
||||
gil::get_color(v(x, y), gil::red_t()) *= fAlpha;
|
||||
gil::get_color(v(x, y), gil::green_t()) *= fAlpha;
|
||||
gil::get_color(v(x, y), gil::blue_t()) *= fAlpha;
|
||||
|
||||
gil::get_color(v(x, y), gil::alpha_t()) = DATA_TRAITS::maxChannelVal;
|
||||
}
|
||||
}
|
||||
*/
|
||||
if (circleInfo.m_isOutlined)
|
||||
{
|
||||
/// drawing inner circle
|
||||
ell.init(center.x,
|
||||
center.y,
|
||||
circleInfo.m_radius,
|
||||
circleInfo.m_radius,
|
||||
100);
|
||||
|
||||
rasterizer.reset();
|
||||
rasterizer.add_path(ell);
|
||||
|
||||
agg::render_scanlines_aa_solid(rasterizer,
|
||||
s,
|
||||
rbase,
|
||||
aggColor);
|
||||
/* 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());
|
||||
float fAlpha = alpha / (float)DATA_TRAITS::maxChannelVal;
|
||||
// if (alpha != 0)
|
||||
// {
|
||||
gil::get_color(v(x, y), gil::red_t()) *= fAlpha;
|
||||
gil::get_color(v(x, y), gil::green_t()) *= fAlpha;
|
||||
gil::get_color(v(x, y), gil::blue_t()) *= fAlpha;
|
||||
|
||||
// gil::get_color(v(x, y), gil::alpha_t()) = DATA_TRAITS::maxChannelVal;
|
||||
// }
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
|
@ -26,7 +26,6 @@ namespace threads
|
|||
namespace yg
|
||||
{
|
||||
class Skin;
|
||||
struct CharStyle;
|
||||
|
||||
namespace gl
|
||||
{
|
||||
|
|
77
yg/glyph_style.cpp
Normal file
77
yg/glyph_style.cpp
Normal file
|
@ -0,0 +1,77 @@
|
|||
#include "resource_style.hpp"
|
||||
|
||||
#include "glyph_cache.hpp"
|
||||
#include "agg_traits.hpp"
|
||||
#include "data_formats.hpp"
|
||||
|
||||
namespace yg
|
||||
{
|
||||
GlyphStyle::GlyphStyle(m2::RectU const & texRect, int pipelineID, shared_ptr<GlyphInfo> const & gi)
|
||||
: ResourceStyle(EGlyphStyle, texRect, pipelineID), m_gi(gi)
|
||||
{}
|
||||
|
||||
void GlyphStyle::render(void * dst)
|
||||
{
|
||||
shared_ptr<GlyphInfo> const & gi = m_gi;
|
||||
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()
|
||||
);
|
||||
|
||||
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::alpha_t()) = 0;
|
||||
|
||||
for (size_t y = 0; y < 2; ++y)
|
||||
for (size_t x = 0; x < rect.SizeX(); ++x)
|
||||
v(x, y) = pxTranslucent;
|
||||
|
||||
for (size_t y = rect.SizeY() - 2; y < rect.SizeY(); ++y)
|
||||
for (size_t x = 0; x < rect.SizeX(); ++x)
|
||||
v(x, y) = pxTranslucent;
|
||||
|
||||
for (size_t y = 2; y < rect.SizeY() - 2; ++y)
|
||||
{
|
||||
v(0, y) = pxTranslucent;
|
||||
v(1, y) = pxTranslucent;
|
||||
v(rect.SizeX() - 2, y) = pxTranslucent;
|
||||
v(rect.SizeX() - 1, y) = pxTranslucent;
|
||||
}
|
||||
|
||||
if ((gi->m_metrics.m_width != 0) && (gi->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
|
||||
);
|
||||
|
||||
/* 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;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
194
yg/line_style.cpp
Normal file
194
yg/line_style.cpp
Normal file
|
@ -0,0 +1,194 @@
|
|||
#include "resource_style.hpp"
|
||||
|
||||
#include "agg_traits.hpp"
|
||||
#include "data_formats.hpp"
|
||||
|
||||
namespace yg
|
||||
{
|
||||
LineStyle::LineStyle(bool isWrapped, m2::RectU const & texRect, int pipelineID, yg::PenInfo const & penInfo) :
|
||||
ResourceStyle(ELineStyle, texRect, pipelineID),
|
||||
m_isWrapped(isWrapped),
|
||||
m_isSolid(penInfo.m_isSolid),
|
||||
m_penInfo(penInfo)
|
||||
{
|
||||
if (m_isSolid)
|
||||
{
|
||||
m_borderColorPixel = m_centerColorPixel = m2::PointU(texRect.minX() + 1, texRect.minY() + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
double firstDashOffset = penInfo.firstDashOffset();
|
||||
m_centerColorPixel = m2::PointU(static_cast<uint32_t>(firstDashOffset + texRect.minX() + 3),
|
||||
static_cast<uint32_t>(texRect.minY() + texRect.SizeY() / 2.0));
|
||||
m_borderColorPixel = m2::PointU(static_cast<uint32_t>(firstDashOffset + texRect.minX() + 3),
|
||||
static_cast<uint32_t>(texRect.minY() + 1));
|
||||
}
|
||||
}
|
||||
|
||||
double LineStyle::geometryTileLen() const
|
||||
{
|
||||
return m_texRect.SizeX() - 2;
|
||||
}
|
||||
|
||||
double LineStyle::geometryTileWidth() const
|
||||
{
|
||||
return m_texRect.SizeY() - 2;
|
||||
}
|
||||
|
||||
double LineStyle::rawTileLen() const
|
||||
{
|
||||
return m_texRect.SizeX() - 4;
|
||||
}
|
||||
|
||||
double LineStyle::rawTileWidth() const
|
||||
{
|
||||
return m_texRect.SizeY() - 4;
|
||||
}
|
||||
|
||||
void LineStyle::render(void * dst)
|
||||
{
|
||||
yg::PenInfo const & penInfo = m_penInfo;
|
||||
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());
|
||||
|
||||
yg::Color penInfoColor = penInfo.m_color;
|
||||
|
||||
penInfoColor /= DATA_TRAITS::channelScaleFactor;
|
||||
|
||||
DATA_TRAITS::pixel_t penColorTranslucent;
|
||||
|
||||
gil::get_color(penColorTranslucent, gil::red_t()) = penInfoColor.r;
|
||||
gil::get_color(penColorTranslucent, gil::green_t()) = penInfoColor.g;
|
||||
gil::get_color(penColorTranslucent, gil::blue_t()) = penInfoColor.b;
|
||||
gil::get_color(penColorTranslucent, gil::alpha_t()) = 0;
|
||||
|
||||
DATA_TRAITS::pixel_t penColor = penColorTranslucent;
|
||||
gil::get_color(penColor, gil::alpha_t()) = penInfoColor.a;
|
||||
|
||||
if (penInfo.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<DATA_TRAITS>::pixfmt_t agg_pixfmt_t;
|
||||
|
||||
agg_pixfmt_t pixfmt(buf);
|
||||
agg::renderer_base<agg_pixfmt_t> rbase(pixfmt);
|
||||
|
||||
gil::fill_pixels(v, penColorTranslucent);
|
||||
|
||||
agg::scanline_u8 s;
|
||||
agg::rasterizer_scanline_aa<> rasterizer;
|
||||
if (penInfo.m_w > 2)
|
||||
{
|
||||
agg::ellipse ell;
|
||||
float r = ceil(penInfo.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(penInfo.m_color.r,
|
||||
penInfo.m_color.g,
|
||||
penInfo.m_color.b,
|
||||
penInfo.m_color.a));
|
||||
|
||||
uint32_t ri = static_cast<uint32_t>(r);
|
||||
|
||||
/// pixels that are used to texture inner part of the line should be fully opaque
|
||||
v(2 + ri - 1, 2) = penColor;
|
||||
v(2 + ri , 2) = penColor;
|
||||
v(2 + ri - 1, 2 + ri * 2 - 1) = penColor;
|
||||
v(2 + ri , 2 + ri * 2 - 1) = penColor;
|
||||
|
||||
/// 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) = penColor;
|
||||
// if (m_fillAlpha)
|
||||
// gil::get_color(v(x, y), gil::alpha_t()) = alpha;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gil::fill_pixels(
|
||||
gil::subimage_view(v, 2, 2, rect.SizeX() - 4, rect.SizeY() - 4),
|
||||
penColor
|
||||
);
|
||||
}
|
||||
}
|
||||
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 = penColor;
|
||||
|
||||
/// In general case this code is incorrect.
|
||||
/// TODO : Make a pattern start and end with a dash.
|
||||
uint32_t curLenI = static_cast<uint32_t>(curLen);
|
||||
|
||||
v(curLenI, y) = px;
|
||||
v(curLenI + 1, y) = px;
|
||||
|
||||
for (size_t i = 0; i < penInfo.m_pat.size(); ++i)
|
||||
{
|
||||
for (size_t j = 0; j < penInfo.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()) = penInfoColor.a;
|
||||
|
||||
v(curLenI + j + 2, y) = px;
|
||||
}
|
||||
|
||||
v(static_cast<uint32_t>(curLen + 2 + penInfo.m_pat[i]), y) = px;
|
||||
v(static_cast<uint32_t>(curLen + 2 + penInfo.m_pat[i] + 1), y) = px;
|
||||
|
||||
curLen += penInfo.m_pat[i];
|
||||
|
||||
curLenI = static_cast<uint32_t>(curLen);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@
|
|||
#include "straight_text_element.hpp"
|
||||
#include "path_text_element.hpp"
|
||||
#include "symbol_element.hpp"
|
||||
#include "circle_element.hpp"
|
||||
#include "render_state.hpp"
|
||||
#include "info_layer.hpp"
|
||||
#include "resource_manager.hpp"
|
||||
|
@ -75,23 +76,25 @@ namespace yg
|
|||
}
|
||||
|
||||
void OverlayRenderer::drawCircle(m2::PointD const & pt,
|
||||
uint32_t styleID,
|
||||
yg::CircleInfo const & ci,
|
||||
EPosition pos,
|
||||
int depth)
|
||||
{
|
||||
SymbolElement::Params params;
|
||||
CircleElement::Params params;
|
||||
|
||||
params.m_depth = depth;
|
||||
params.m_position = pos;
|
||||
params.m_pivot = pt;
|
||||
params.m_styleID = styleID;
|
||||
params.m_skin = skin().get();
|
||||
params.m_ci = ci;
|
||||
|
||||
SymbolElement se(params);
|
||||
shared_ptr<OverlayElement> oe(new CircleElement(params));
|
||||
|
||||
math::Matrix<double, 3, 3> id = math::Identity<double, 3>();
|
||||
|
||||
se.draw(this, id);
|
||||
if (!m_infoLayer.get())
|
||||
oe->draw(this, id);
|
||||
else
|
||||
m_infoLayer->processOverlayElement(oe);
|
||||
}
|
||||
|
||||
void OverlayRenderer::drawText(FontDesc const & fontDesc,
|
||||
|
|
|
@ -36,7 +36,7 @@ namespace yg
|
|||
void drawSymbol(m2::PointD const & pt, string const & symbolName, EPosition pos, int depth);
|
||||
|
||||
/// Drawing circle
|
||||
void drawCircle(m2::PointD const & pt, uint32_t styleID, EPosition pos, int depth);
|
||||
void drawCircle(m2::PointD const & pt, yg::CircleInfo const & ci, EPosition pos, int depth);
|
||||
|
||||
/// drawing straight text
|
||||
void drawText(FontDesc const & fontDesc,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include "resource_style.hpp"
|
||||
|
||||
#include "../base/start_mem_debug.hpp"
|
||||
#include "data_formats.hpp"
|
||||
|
||||
namespace yg
|
||||
{
|
||||
|
@ -10,7 +10,7 @@ namespace yg
|
|||
ResourceStyle::ResourceStyle(
|
||||
m2::RectU const & texRect,
|
||||
int pipelineID
|
||||
) : m_cat(EGenericStyle),
|
||||
) : m_cat(EUnknownStyle),
|
||||
m_texRect(texRect),
|
||||
m_pipelineID(pipelineID)
|
||||
{}
|
||||
|
@ -24,55 +24,40 @@ namespace yg
|
|||
m_pipelineID(pipelineID)
|
||||
{}
|
||||
|
||||
LineStyle::LineStyle(bool isWrapped, m2::RectU const & texRect, int pipelineID, yg::PenInfo const & penInfo) :
|
||||
ResourceStyle(ELineStyle, texRect, pipelineID),
|
||||
m_isWrapped(isWrapped),
|
||||
m_isSolid(penInfo.m_isSolid),
|
||||
m_penInfo(penInfo)
|
||||
{
|
||||
if (m_isSolid)
|
||||
{
|
||||
m_borderColorPixel = m_centerColorPixel = m2::PointU(texRect.minX() + 1, texRect.minY() + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
double firstDashOffset = penInfo.firstDashOffset();
|
||||
m_centerColorPixel = m2::PointU(static_cast<uint32_t>(firstDashOffset + texRect.minX() + 3),
|
||||
static_cast<uint32_t>(texRect.minY() + texRect.SizeY() / 2.0));
|
||||
m_borderColorPixel = m2::PointU(static_cast<uint32_t>(firstDashOffset + texRect.minX() + 3),
|
||||
static_cast<uint32_t>(texRect.minY() + 1));
|
||||
}
|
||||
}
|
||||
|
||||
double LineStyle::geometryTileLen() const
|
||||
{
|
||||
return m_texRect.SizeX() - 2;
|
||||
}
|
||||
|
||||
double LineStyle::geometryTileWidth() const
|
||||
{
|
||||
return m_texRect.SizeY() - 2;
|
||||
}
|
||||
|
||||
double LineStyle::rawTileLen() const
|
||||
{
|
||||
return m_texRect.SizeX() - 4;
|
||||
}
|
||||
|
||||
double LineStyle::rawTileWidth() const
|
||||
{
|
||||
return m_texRect.SizeY() - 4;
|
||||
}
|
||||
|
||||
CharStyle::CharStyle(m2::RectU const & texRect, int pipelineID, int8_t xOffset, int8_t yOffset, int8_t xAdvance)
|
||||
: ResourceStyle(ECharStyle, texRect, pipelineID), m_xOffset(xOffset), m_yOffset(yOffset), m_xAdvance(xAdvance)
|
||||
ResourceStyle::~ResourceStyle()
|
||||
{}
|
||||
|
||||
PointStyle::PointStyle(m2::RectU const & texRect, int pipelineID, string const & styleName)
|
||||
: ResourceStyle(EPointStyle, texRect, pipelineID), m_styleName(styleName)
|
||||
{}
|
||||
|
||||
GenericStyle::GenericStyle(m2::RectU const & texRect, int pipelineID)
|
||||
: ResourceStyle(EGenericStyle, texRect, pipelineID)
|
||||
void PointStyle::render(void *dst)
|
||||
{}
|
||||
|
||||
ColorStyle::ColorStyle(m2::RectU const & texRect, int pipelineID, yg::Color const & c)
|
||||
: ResourceStyle(EColorStyle, texRect, pipelineID), m_c(c)
|
||||
{}
|
||||
|
||||
void ColorStyle::render(void * dst)
|
||||
{
|
||||
yg::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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,18 +1,26 @@
|
|||
#pragma once
|
||||
|
||||
#include "../geometry/rect2d.hpp"
|
||||
#include "pen_info.hpp"
|
||||
#include "circle_info.hpp"
|
||||
|
||||
#include "../geometry/rect2d.hpp"
|
||||
|
||||
#include "../std/shared_ptr.hpp"
|
||||
|
||||
namespace yg
|
||||
{
|
||||
struct GlyphInfo;
|
||||
|
||||
struct ResourceStyle
|
||||
{
|
||||
enum Category
|
||||
{
|
||||
ELineStyle = 1,
|
||||
ECharStyle,
|
||||
EColorStyle = 1,
|
||||
ELineStyle,
|
||||
EGlyphStyle,
|
||||
EPointStyle,
|
||||
EGenericStyle
|
||||
ECircleStyle,
|
||||
EUnknownStyle
|
||||
};
|
||||
|
||||
Category m_cat;
|
||||
|
@ -22,6 +30,9 @@ namespace yg
|
|||
ResourceStyle();
|
||||
ResourceStyle(m2::RectU const & texRect, int pipelineID);
|
||||
|
||||
virtual ~ResourceStyle();
|
||||
virtual void render(void * dst) = 0;
|
||||
|
||||
protected:
|
||||
ResourceStyle(Category cat, m2::RectU const & texRect, int pipelineID);
|
||||
};
|
||||
|
@ -43,25 +54,38 @@ namespace yg
|
|||
double rawTileLen() const;
|
||||
double rawTileWidth() const;
|
||||
|
||||
void render(void * dst);
|
||||
};
|
||||
|
||||
struct CharStyle : public ResourceStyle
|
||||
struct GlyphStyle : public ResourceStyle
|
||||
{
|
||||
int8_t m_xOffset;
|
||||
int8_t m_yOffset;
|
||||
int8_t m_xAdvance;
|
||||
shared_ptr<GlyphInfo> m_gi;
|
||||
GlyphStyle(m2::RectU const & texRect, int pipelineID, shared_ptr<GlyphInfo> const & gi);
|
||||
|
||||
CharStyle(m2::RectU const & texRect, int pipelineID, int8_t xOffset, int8_t yOffset, int8_t xAdvance);
|
||||
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 GenericStyle : public ResourceStyle
|
||||
struct CircleStyle : public ResourceStyle
|
||||
{
|
||||
GenericStyle(m2::RectU const & texRect, int pipelineID);
|
||||
yg::CircleInfo m_ci;
|
||||
CircleStyle(m2::RectU const & texRect, int pipelineID, yg::CircleInfo const & ci);
|
||||
|
||||
void render(void * dst);
|
||||
};
|
||||
|
||||
struct ColorStyle : public ResourceStyle
|
||||
{
|
||||
yg::Color m_c;
|
||||
ColorStyle(m2::RectU const & texRect, int pipelineID, yg::Color const & c);
|
||||
|
||||
void render(void * dst);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -35,32 +35,6 @@ namespace yg
|
|||
m_texRect = m2::RectU(m_texX, m_texY, m_texX + m_texWidth, m_texY + m_texHeight);
|
||||
}
|
||||
|
||||
void SkinLoader::popCharStyle()
|
||||
{
|
||||
m_chars[m_id] = make_pair(m_glyphInfo, m_glyphMaskInfo);
|
||||
}
|
||||
|
||||
void SkinLoader::popGlyphInfo()
|
||||
{
|
||||
m_glyphInfo = shared_ptr<CharStyle>(new CharStyle(m_texRect, m_pages.size(), m_xOffset, m_yOffset, m_xAdvance));
|
||||
}
|
||||
|
||||
void SkinLoader::popGlyphMaskInfo()
|
||||
{
|
||||
m_glyphMaskInfo = shared_ptr<CharStyle>(new CharStyle(m_texRect, m_pages.size(), m_xOffset, m_yOffset, m_xAdvance));
|
||||
}
|
||||
|
||||
void SkinLoader::pushFontInfo()
|
||||
{
|
||||
m_chars.clear();
|
||||
m_fontSize = 0;
|
||||
}
|
||||
|
||||
void SkinLoader::popFontInfo()
|
||||
{
|
||||
m_fonts[m_fontSize] = m_chars;
|
||||
}
|
||||
|
||||
void SkinLoader::popPointStyle()
|
||||
{
|
||||
uint32_t id = m_id;
|
||||
|
@ -91,16 +65,6 @@ namespace yg
|
|||
m_stylesList.erase(prevIt);
|
||||
prevIt = it;
|
||||
}
|
||||
|
||||
for (TFonts::const_iterator it = m_fonts.begin(); it != m_fonts.end(); ++it)
|
||||
{
|
||||
FontInfo fontInfo;
|
||||
fontInfo.m_fontSize = it->first;
|
||||
fontInfo.m_chars = it->second;
|
||||
m_pages.back()->m_fonts.push_back(fontInfo);
|
||||
}
|
||||
|
||||
m_fonts.clear();
|
||||
}
|
||||
|
||||
void SkinLoader::popSkin()
|
||||
|
@ -135,10 +99,6 @@ namespace yg
|
|||
{
|
||||
PUSH_MODE(ESkin, "skin");
|
||||
PUSH_MODE_EX(EPage, "page", pushPage);
|
||||
PUSH_MODE(ECharStyle, "charStyle");
|
||||
PUSH_MODE(EGlyphInfo, "glyphInfo");
|
||||
PUSH_MODE(EGlyphMaskInfo, "glyphMaskInfo");
|
||||
PUSH_MODE_EX(EFontInfo, "fontInfo", pushFontInfo);
|
||||
PUSH_MODE(EPointStyle, "symbolStyle");
|
||||
PUSH_MODE(ELineStyle, "lineStyle");
|
||||
PUSH_MODE_EX(EResourceStyle, "resourceStyle", pushResourceStyle);
|
||||
|
@ -149,10 +109,6 @@ namespace yg
|
|||
{
|
||||
POP_MODE_EX(ESkin, "skin", popSkin);
|
||||
POP_MODE_EX(EPage, "page", popPage);
|
||||
POP_MODE_EX(ECharStyle, "charStyle", popCharStyle);
|
||||
POP_MODE_EX(EGlyphInfo, "glyphInfo", popGlyphInfo);
|
||||
POP_MODE_EX(EGlyphMaskInfo, "glyphMaskInfo", popGlyphMaskInfo);
|
||||
POP_MODE_EX(EFontInfo, "fontInfo", popFontInfo);
|
||||
POP_MODE_EX(EPointStyle, "symbolStyle", popPointStyle);
|
||||
POP_MODE(ELineStyle, "lineStyle");
|
||||
POP_MODE_EX(EResourceStyle, "resourceStyle", popResourceStyle);
|
||||
|
@ -175,21 +131,6 @@ namespace yg
|
|||
if (attr == "file")
|
||||
m_fileName = value;
|
||||
break;
|
||||
case ECharStyle:
|
||||
if (attr == "id")
|
||||
m_id = StrToInt(value);
|
||||
case EGlyphInfo: case EGlyphMaskInfo:
|
||||
if (attr == "xOffset")
|
||||
m_xOffset = StrToInt(value);
|
||||
else if (attr == "yOffset")
|
||||
m_yOffset = StrToInt(value);
|
||||
else if (attr == "xAdvance")
|
||||
m_xAdvance = StrToInt(value);
|
||||
break;
|
||||
case EFontInfo:
|
||||
if (attr == "size")
|
||||
m_fontSize = StrToInt(value);
|
||||
break;
|
||||
case EPointStyle:
|
||||
if (attr == "id")
|
||||
m_id = StrToInt(value);
|
||||
|
|
|
@ -39,7 +39,7 @@ namespace yg
|
|||
class ResourceManager;
|
||||
class SkinPage;
|
||||
struct ResourceStyle;
|
||||
struct CharStyle;
|
||||
struct GlyphStyle;
|
||||
|
||||
class SkinLoader
|
||||
{
|
||||
|
@ -53,11 +53,7 @@ namespace yg
|
|||
EFontStyle,
|
||||
EPointStyle,
|
||||
ELineStyle,
|
||||
EResourceStyle,
|
||||
ECharStyle,
|
||||
EGlyphInfo,
|
||||
EGlyphMaskInfo,
|
||||
EFontInfo
|
||||
EResourceStyle
|
||||
};
|
||||
|
||||
list<EMode> m_mode;
|
||||
|
@ -70,23 +66,13 @@ namespace yg
|
|||
uint32_t m_texHeight;
|
||||
m2::RectU m_texRect;
|
||||
|
||||
/// fontInfo-specific parameters
|
||||
typedef map<int32_t, pair<shared_ptr<CharStyle>, shared_ptr<CharStyle> > > TChars;
|
||||
TChars m_chars;
|
||||
typedef map<int8_t, TChars> TFonts;
|
||||
TFonts m_fonts;
|
||||
int8_t m_fontSize;
|
||||
|
||||
/// charStyle-specific parameters
|
||||
|
||||
|
||||
/// glyphInfo and glyphMaskInfo specific parameters
|
||||
int8_t m_xOffset;
|
||||
int8_t m_yOffset;
|
||||
int8_t m_xAdvance;
|
||||
|
||||
shared_ptr<CharStyle> m_glyphInfo;
|
||||
shared_ptr<CharStyle> m_glyphMaskInfo;
|
||||
shared_ptr<GlyphStyle> m_glyphInfo;
|
||||
shared_ptr<GlyphStyle> m_glyphMaskInfo;
|
||||
|
||||
/// pointStyle-specific parameters
|
||||
string m_styleID;
|
||||
|
@ -118,10 +104,6 @@ namespace yg
|
|||
void AddAttr(string const & attribute, string const & value);
|
||||
void CharData(string const &) {}
|
||||
|
||||
void popCharStyle();
|
||||
void popGlyphInfo();
|
||||
void popGlyphMaskInfo();
|
||||
void popFontInfo();
|
||||
void popPointStyle();
|
||||
void popSkin();
|
||||
void pushPage();
|
||||
|
@ -129,9 +111,7 @@ namespace yg
|
|||
|
||||
void pushResourceStyle();
|
||||
void popResourceStyle();
|
||||
void pushFontInfo();
|
||||
|
||||
Skin * skin();
|
||||
|
||||
};
|
||||
}
|
||||
|
|
538
yg/skin_page.cpp
538
yg/skin_page.cpp
|
@ -1,13 +1,7 @@
|
|||
#include <agg_pixfmt_rgba.h>
|
||||
#include <agg_pixfmt_rgb_packed.h>
|
||||
#include <agg_renderer_scanline.h>
|
||||
#include <agg_rasterizer_scanline_aa.h>
|
||||
#include <agg_scanline_u.h>
|
||||
#include <agg_ellipse.h>
|
||||
#include "skin_page.hpp"
|
||||
|
||||
#include "texture.hpp"
|
||||
#include "data_formats.hpp"
|
||||
#include "skin_page.hpp"
|
||||
#include "resource_style.hpp"
|
||||
#include "resource_manager.hpp"
|
||||
#include "internal/opengl.hpp"
|
||||
|
@ -17,51 +11,10 @@
|
|||
#include "../std/bind.hpp"
|
||||
#include "../std/numeric.hpp"
|
||||
|
||||
template <typename Traits>
|
||||
struct AggTraits
|
||||
{
|
||||
};
|
||||
|
||||
template <>
|
||||
struct AggTraits<yg::RGBA8Traits>
|
||||
{
|
||||
typedef agg::pixfmt_rgba32 pixfmt_t;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct AggTraits<yg::RGBA4Traits>
|
||||
{
|
||||
typedef agg::pixfmt_rgb4444 pixfmt_t;
|
||||
};
|
||||
|
||||
namespace yg
|
||||
{
|
||||
typedef gl::Texture<DATA_TRAITS, true> TDynamicTexture;
|
||||
|
||||
GlyphUploadCmd::GlyphUploadCmd(){}
|
||||
GlyphUploadCmd::GlyphUploadCmd(shared_ptr<GlyphInfo> const & glyphInfo,
|
||||
m2::RectU const & rect)
|
||||
: m_glyphInfo(glyphInfo),
|
||||
m_rect(rect){}
|
||||
|
||||
ColorUploadCmd::ColorUploadCmd(){}
|
||||
ColorUploadCmd::ColorUploadCmd(yg::Color const & color,
|
||||
m2::RectU const & rect)
|
||||
: m_color(color),
|
||||
m_rect(rect){}
|
||||
|
||||
PenUploadCmd::PenUploadCmd(){}
|
||||
PenUploadCmd::PenUploadCmd(yg::PenInfo const & penInfo,
|
||||
m2::RectU const & rect)
|
||||
: m_penInfo(penInfo),
|
||||
m_rect(rect){}
|
||||
|
||||
CircleUploadCmd::CircleUploadCmd(){}
|
||||
CircleUploadCmd::CircleUploadCmd(yg::CircleInfo const & circleInfo,
|
||||
m2::RectU const & rect)
|
||||
: m_circleInfo(circleInfo),
|
||||
m_rect(rect){}
|
||||
|
||||
ResourceStyle * FontInfo::fromID(uint32_t id, bool isMask) const
|
||||
{
|
||||
TChars::const_iterator it = m_chars.find(id);
|
||||
|
@ -130,18 +83,15 @@ namespace yg
|
|||
m_packer.reset();
|
||||
}
|
||||
|
||||
void SkinPage::clearUploadCommands()
|
||||
void SkinPage::clearUploadQueue()
|
||||
{
|
||||
m_penUploadCommands.clear();
|
||||
m_colorUploadCommands.clear();
|
||||
m_glyphUploadCommands.clear();
|
||||
m_circleUploadCommands.clear();
|
||||
m_uploadQueue.clear();
|
||||
}
|
||||
|
||||
void SkinPage::clear()
|
||||
{
|
||||
clearHandles();
|
||||
clearUploadCommands();
|
||||
clearUploadQueue();
|
||||
}
|
||||
|
||||
void SkinPage::clearColorHandles()
|
||||
|
@ -194,12 +144,13 @@ namespace yg
|
|||
|
||||
m2::Packer::handle_t h = m_packer.pack(2, 2);
|
||||
|
||||
m2::RectU texRect = m_packer.find(h).second;
|
||||
|
||||
m_colorUploadCommands.push_back(ColorUploadCmd(c, texRect));
|
||||
m_colorMap[c] = h;
|
||||
|
||||
m_styles[h] = shared_ptr<ResourceStyle>(new GenericStyle(texRect, m_pipelineID));
|
||||
m2::RectU texRect = m_packer.find(h).second;
|
||||
shared_ptr<ResourceStyle> colorStyle(new ColorStyle(texRect, m_pipelineID, c));
|
||||
|
||||
m_styles[h] = colorStyle;
|
||||
m_uploadQueue.push_back(colorStyle);
|
||||
|
||||
return h;
|
||||
}
|
||||
|
@ -239,15 +190,15 @@ namespace yg
|
|||
gi->m_metrics.m_height + 4);
|
||||
|
||||
m2::RectU texRect = m_packer.find(handle).second;
|
||||
m_glyphUploadCommands.push_back(GlyphUploadCmd(gi, texRect));
|
||||
m_glyphMap[g] = handle;
|
||||
|
||||
m_styles[handle] = boost::shared_ptr<ResourceStyle>(
|
||||
new CharStyle(texRect,
|
||||
boost::shared_ptr<ResourceStyle> glyphStyle(
|
||||
new GlyphStyle(texRect,
|
||||
m_pipelineID,
|
||||
gi->m_metrics.m_xOffset,
|
||||
gi->m_metrics.m_yOffset,
|
||||
gi->m_metrics.m_xAdvance));
|
||||
gi));
|
||||
|
||||
m_styles[handle] = glyphStyle;
|
||||
m_uploadQueue.push_back(glyphStyle);
|
||||
|
||||
return m_glyphMap[g];
|
||||
}
|
||||
|
@ -279,26 +230,25 @@ namespace yg
|
|||
if (foundHandle != m_packer.invalidHandle())
|
||||
return foundHandle;
|
||||
|
||||
unsigned r = circleInfo.m_isOutlined ? circleInfo.m_radius + circleInfo.m_outlineWidth : circleInfo.m_radius;
|
||||
m2::PointU sz = circleInfo.patternSize();
|
||||
m2::Packer::handle_t handle = m_packer.pack(sz.x, sz.y);
|
||||
|
||||
m2::Packer::handle_t handle = m_packer.pack(
|
||||
r * 2 + 4,
|
||||
r * 2 + 4);
|
||||
|
||||
m2::RectU texRect = m_packer.find(handle).second;
|
||||
m_circleUploadCommands.push_back(CircleUploadCmd(circleInfo, texRect));
|
||||
m_circleInfoMap[circleInfo] = handle;
|
||||
|
||||
m_styles[handle] = shared_ptr<ResourceStyle>(new GenericStyle(texRect, m_pipelineID) );
|
||||
m2::RectU texRect = m_packer.find(handle).second;
|
||||
|
||||
shared_ptr<ResourceStyle> circleStyle(new CircleStyle(texRect, m_pipelineID, circleInfo));
|
||||
|
||||
m_styles[handle] = circleStyle;
|
||||
m_uploadQueue.push_back(circleStyle);
|
||||
|
||||
return m_circleInfoMap[circleInfo];
|
||||
}
|
||||
|
||||
bool SkinPage::hasRoom(CircleInfo const & circleInfo) const
|
||||
{
|
||||
unsigned r = circleInfo.m_isOutlined ? circleInfo.m_radius + circleInfo.m_outlineWidth : circleInfo.m_radius;
|
||||
return m_packer.hasRoom(r * 2 + 4,
|
||||
r * 2 + 4);
|
||||
m2::PointU sz = circleInfo.patternSize();
|
||||
return m_packer.hasRoom(sz.x, sz.y);
|
||||
}
|
||||
|
||||
uint32_t SkinPage::findPenInfo(PenInfo const & penInfo) const
|
||||
|
@ -320,15 +270,19 @@ namespace yg
|
|||
m2::PointU p = penInfo.patternSize();
|
||||
|
||||
m2::Packer::handle_t handle = m_packer.pack(p.x, p.y);
|
||||
m2::RectU texRect = m_packer.find(handle).second;
|
||||
m_penUploadCommands.push_back(PenUploadCmd(penInfo, texRect));
|
||||
|
||||
m_penInfoMap[penInfo] = handle;
|
||||
|
||||
m_styles[handle] = boost::shared_ptr<ResourceStyle>(
|
||||
new LineStyle(false,
|
||||
texRect,
|
||||
m_pipelineID,
|
||||
penInfo));
|
||||
m2::RectU texRect = m_packer.find(handle).second;
|
||||
|
||||
boost::shared_ptr<ResourceStyle> lineStyle(
|
||||
new LineStyle(false,
|
||||
texRect,
|
||||
m_pipelineID,
|
||||
penInfo));
|
||||
|
||||
m_styles[handle] = lineStyle;
|
||||
m_uploadQueue.push_back(lineStyle);
|
||||
|
||||
return m_penInfoMap[penInfo];
|
||||
}
|
||||
|
@ -344,406 +298,9 @@ namespace yg
|
|||
return m_usage;
|
||||
}
|
||||
|
||||
void SkinPage::uploadPenInfo()
|
||||
{
|
||||
for (size_t i = 0; i < m_penUploadCommands.size(); ++i)
|
||||
{
|
||||
yg::PenInfo const & penInfo = m_penUploadCommands[i].m_penInfo;
|
||||
m2::RectU const & rect = m_penUploadCommands[i].m_rect;
|
||||
|
||||
TDynamicTexture * dynTexture = static_cast<TDynamicTexture*>(m_texture.get());
|
||||
|
||||
TDynamicTexture::view_t v = dynTexture->view(rect.SizeX(), rect.SizeY());
|
||||
|
||||
yg::Color penInfoColor = penInfo.m_color;
|
||||
|
||||
penInfoColor /= TDynamicTexture::channelScaleFactor;
|
||||
|
||||
TDynamicTexture::pixel_t penColorTranslucent;
|
||||
|
||||
gil::get_color(penColorTranslucent, gil::red_t()) = penInfoColor.r;
|
||||
gil::get_color(penColorTranslucent, gil::green_t()) = penInfoColor.g;
|
||||
gil::get_color(penColorTranslucent, gil::blue_t()) = penInfoColor.b;
|
||||
gil::get_color(penColorTranslucent, gil::alpha_t()) = 0;
|
||||
|
||||
TDynamicTexture::pixel_t penColor = penColorTranslucent;
|
||||
gil::get_color(penColor, gil::alpha_t()) = penInfoColor.a;
|
||||
|
||||
if (penInfo.m_isSolid)
|
||||
{
|
||||
/// draw circle
|
||||
agg::rendering_buffer buf(
|
||||
(unsigned char *)&v(0, 0),
|
||||
rect.SizeX(),
|
||||
rect.SizeY(),
|
||||
rect.SizeX() * sizeof(TDynamicTexture::pixel_t)
|
||||
);
|
||||
|
||||
typedef AggTraits<TDynamicTexture::traits_t>::pixfmt_t agg_pixfmt_t;
|
||||
|
||||
agg_pixfmt_t pixfmt(buf);
|
||||
agg::renderer_base<agg_pixfmt_t> rbase(pixfmt);
|
||||
|
||||
gil::fill_pixels(v, penColorTranslucent);
|
||||
|
||||
agg::scanline_u8 s;
|
||||
agg::rasterizer_scanline_aa<> rasterizer;
|
||||
if (penInfo.m_w > 2)
|
||||
{
|
||||
agg::ellipse ell;
|
||||
float r = ceil(penInfo.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(penInfo.m_color.r,
|
||||
penInfo.m_color.g,
|
||||
penInfo.m_color.b,
|
||||
penInfo.m_color.a));
|
||||
|
||||
uint32_t ri = static_cast<uint32_t>(r);
|
||||
|
||||
/// pixels that are used to texture inner part of the line should be fully opaque
|
||||
v(2 + ri - 1, 2) = penColor;
|
||||
v(2 + ri , 2) = penColor;
|
||||
v(2 + ri - 1, 2 + ri * 2 - 1) = penColor;
|
||||
v(2 + ri , 2 + ri * 2 - 1) = penColor;
|
||||
|
||||
/// 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) = penColor;
|
||||
// if (m_fillAlpha)
|
||||
// gil::get_color(v(x, y), gil::alpha_t()) = alpha;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gil::fill_pixels(
|
||||
gil::subimage_view(v, 2, 2, rect.SizeX() - 4, rect.SizeY() - 4),
|
||||
penColor
|
||||
);
|
||||
}
|
||||
}
|
||||
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;
|
||||
|
||||
TDynamicTexture::pixel_t px = penColor;
|
||||
|
||||
/// In general case this code is incorrect.
|
||||
/// TODO : Make a pattern start and end with a dash.
|
||||
uint32_t curLenI = static_cast<uint32_t>(curLen);
|
||||
|
||||
v(curLenI, y) = px;
|
||||
v(curLenI + 1, y) = px;
|
||||
|
||||
for (size_t i = 0; i < penInfo.m_pat.size(); ++i)
|
||||
{
|
||||
for (size_t j = 0; j < penInfo.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()) = penInfoColor.a;
|
||||
|
||||
v(curLenI + j + 2, y) = px;
|
||||
}
|
||||
|
||||
v(static_cast<uint32_t>(curLen + 2 + penInfo.m_pat[i]), y) = px;
|
||||
v(static_cast<uint32_t>(curLen + 2 + penInfo.m_pat[i] + 1), y) = px;
|
||||
|
||||
curLen += penInfo.m_pat[i];
|
||||
|
||||
curLenI = static_cast<uint32_t>(curLen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dynTexture->upload(&v(0, 0), rect);
|
||||
|
||||
}
|
||||
m_penUploadCommands.clear();
|
||||
}
|
||||
|
||||
void SkinPage::uploadCircleInfo()
|
||||
{
|
||||
for (size_t i = 0; i < m_circleUploadCommands.size(); ++i)
|
||||
{
|
||||
yg::CircleInfo & circleInfo = m_circleUploadCommands[i].m_circleInfo;
|
||||
m2::RectU const & rect = m_circleUploadCommands[i].m_rect;
|
||||
|
||||
TDynamicTexture * dynTexture = static_cast<TDynamicTexture*>(m_texture.get());
|
||||
|
||||
TDynamicTexture::view_t v = dynTexture->view(rect.SizeX(), rect.SizeY());
|
||||
|
||||
agg::rgba8 aggColor(circleInfo.m_color.r,
|
||||
circleInfo.m_color.g,
|
||||
circleInfo.m_color.b,
|
||||
circleInfo.m_color.a);
|
||||
|
||||
agg::rgba8 aggOutlineColor(circleInfo.m_outlineColor.r,
|
||||
circleInfo.m_outlineColor.g,
|
||||
circleInfo.m_outlineColor.b,
|
||||
circleInfo.m_outlineColor.a);
|
||||
|
||||
circleInfo.m_color /= TDynamicTexture::channelScaleFactor;
|
||||
|
||||
TDynamicTexture::pixel_t gilColorTranslucent;
|
||||
|
||||
gil::get_color(gilColorTranslucent, gil::red_t()) = circleInfo.m_color.r;
|
||||
gil::get_color(gilColorTranslucent, gil::green_t()) = circleInfo.m_color.g;
|
||||
gil::get_color(gilColorTranslucent, gil::blue_t()) = circleInfo.m_color.b;
|
||||
gil::get_color(gilColorTranslucent, gil::alpha_t()) = 0;
|
||||
|
||||
circleInfo.m_outlineColor /= TDynamicTexture::channelScaleFactor;
|
||||
|
||||
TDynamicTexture::pixel_t gilOutlineColorTranslucent;
|
||||
|
||||
gil::get_color(gilOutlineColorTranslucent, gil::red_t()) = circleInfo.m_outlineColor.r;
|
||||
gil::get_color(gilOutlineColorTranslucent, gil::green_t()) = circleInfo.m_outlineColor.g;
|
||||
gil::get_color(gilOutlineColorTranslucent, gil::blue_t()) = circleInfo.m_outlineColor.b;
|
||||
gil::get_color(gilOutlineColorTranslucent, gil::alpha_t()) = 0;
|
||||
|
||||
TDynamicTexture::pixel_t gilColor = gilColorTranslucent;
|
||||
gil::get_color(gilColor, gil::alpha_t()) = circleInfo.m_color.a;
|
||||
|
||||
TDynamicTexture::pixel_t gilOutlineColor = gilOutlineColorTranslucent;
|
||||
gil::get_color(gilOutlineColor, gil::alpha_t()) = circleInfo.m_outlineColor.a;
|
||||
|
||||
/// draw circle
|
||||
agg::rendering_buffer buf(
|
||||
(unsigned char *)&v(0, 0),
|
||||
rect.SizeX(),
|
||||
rect.SizeY(),
|
||||
rect.SizeX() * sizeof(TDynamicTexture::pixel_t)
|
||||
);
|
||||
|
||||
typedef AggTraits<TDynamicTexture::traits_t>::pixfmt_t agg_pixfmt_t;
|
||||
|
||||
agg_pixfmt_t pixfmt(buf);
|
||||
agg::renderer_base<agg_pixfmt_t> rbase(pixfmt);
|
||||
|
||||
if (circleInfo.m_isOutlined)
|
||||
gil::fill_pixels(v, gilOutlineColorTranslucent);
|
||||
else
|
||||
gil::fill_pixels(v, gilColorTranslucent);
|
||||
|
||||
m2::PointD center(circleInfo.m_radius + 2, circleInfo.m_radius + 2);
|
||||
|
||||
if (circleInfo.m_isOutlined)
|
||||
center += m2::PointD(circleInfo.m_outlineWidth, circleInfo.m_outlineWidth);
|
||||
|
||||
agg::scanline_u8 s;
|
||||
agg::rasterizer_scanline_aa<> rasterizer;
|
||||
|
||||
agg::ellipse ell;
|
||||
|
||||
ell.init(center.x,
|
||||
center.y,
|
||||
circleInfo.m_isOutlined ? circleInfo.m_radius + circleInfo.m_outlineWidth : circleInfo.m_radius,
|
||||
circleInfo.m_isOutlined ? circleInfo.m_radius + circleInfo.m_outlineWidth : circleInfo.m_radius,
|
||||
100);
|
||||
|
||||
rasterizer.add_path(ell);
|
||||
|
||||
agg::render_scanlines_aa_solid(rasterizer,
|
||||
s,
|
||||
rbase,
|
||||
circleInfo.m_isOutlined ? aggOutlineColor : aggColor);
|
||||
|
||||
TDynamicTexture::pixel_t px = circleInfo.m_isOutlined ? gilOutlineColor : gilColor;
|
||||
|
||||
/// making alpha channel 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());
|
||||
|
||||
float fAlpha = alpha / (float)TDynamicTexture::maxChannelVal;
|
||||
|
||||
if (alpha != 0)
|
||||
{
|
||||
gil::get_color(v(x, y), gil::red_t()) *= fAlpha;
|
||||
gil::get_color(v(x, y), gil::green_t()) *= fAlpha;
|
||||
gil::get_color(v(x, y), gil::blue_t()) *= fAlpha;
|
||||
|
||||
gil::get_color(v(x, y), gil::alpha_t()) = TDynamicTexture::maxChannelVal;
|
||||
}
|
||||
}
|
||||
*/
|
||||
if (circleInfo.m_isOutlined)
|
||||
{
|
||||
/// drawing inner circle
|
||||
ell.init(center.x,
|
||||
center.y,
|
||||
circleInfo.m_radius,
|
||||
circleInfo.m_radius,
|
||||
100);
|
||||
|
||||
rasterizer.reset();
|
||||
rasterizer.add_path(ell);
|
||||
|
||||
agg::render_scanlines_aa_solid(rasterizer,
|
||||
s,
|
||||
rbase,
|
||||
aggColor);
|
||||
/* 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());
|
||||
float fAlpha = alpha / (float)TDynamicTexture::maxChannelVal;
|
||||
// if (alpha != 0)
|
||||
// {
|
||||
gil::get_color(v(x, y), gil::red_t()) *= fAlpha;
|
||||
gil::get_color(v(x, y), gil::green_t()) *= fAlpha;
|
||||
gil::get_color(v(x, y), gil::blue_t()) *= fAlpha;
|
||||
|
||||
// gil::get_color(v(x, y), gil::alpha_t()) = TDynamicTexture::maxChannelVal;
|
||||
// }
|
||||
}*/
|
||||
}
|
||||
|
||||
dynTexture->upload(&v(0, 0), rect);
|
||||
}
|
||||
|
||||
m_circleUploadCommands.clear();
|
||||
}
|
||||
|
||||
void SkinPage::uploadGlyphs()
|
||||
{
|
||||
for (size_t i = 0; i < m_glyphUploadCommands.size(); ++i)
|
||||
{
|
||||
shared_ptr<GlyphInfo> const & gi = m_glyphUploadCommands[i].m_glyphInfo;
|
||||
m2::RectU const & rect = m_glyphUploadCommands[i].m_rect;
|
||||
|
||||
TDynamicTexture * dynTexture = static_cast<TDynamicTexture*>(m_texture.get());
|
||||
|
||||
TDynamicTexture::view_t v = dynTexture->view(rect.SizeX(), rect.SizeY());
|
||||
|
||||
TDynamicTexture::pixel_t pxTranslucent;
|
||||
gil::get_color(pxTranslucent, gil::red_t()) = gi->m_color.r / TDynamicTexture::channelScaleFactor;
|
||||
gil::get_color(pxTranslucent, gil::green_t()) = gi->m_color.g / TDynamicTexture::channelScaleFactor;
|
||||
gil::get_color(pxTranslucent, gil::blue_t()) = gi->m_color.b / TDynamicTexture::channelScaleFactor;
|
||||
gil::get_color(pxTranslucent, gil::alpha_t()) = 0;
|
||||
|
||||
for (size_t y = 0; y < 2; ++y)
|
||||
for (size_t x = 0; x < rect.SizeX(); ++x)
|
||||
v(x, y) = pxTranslucent;
|
||||
|
||||
for (size_t y = rect.SizeY() - 2; y < rect.SizeY(); ++y)
|
||||
for (size_t x = 0; x < rect.SizeX(); ++x)
|
||||
v(x, y) = pxTranslucent;
|
||||
|
||||
for (size_t y = 2; y < rect.SizeY() - 2; ++y)
|
||||
{
|
||||
v(0, y) = pxTranslucent;
|
||||
v(1, y) = pxTranslucent;
|
||||
v(rect.SizeX() - 2, y) = pxTranslucent;
|
||||
v(rect.SizeX() - 1, y) = pxTranslucent;
|
||||
}
|
||||
|
||||
if ((gi->m_metrics.m_width != 0) && (gi->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
|
||||
);
|
||||
|
||||
/* TDynamicTexture::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;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
dynTexture->upload(&v(0, 0), rect);
|
||||
}
|
||||
|
||||
m_glyphUploadCommands.clear();
|
||||
}
|
||||
|
||||
void SkinPage::uploadColors()
|
||||
{
|
||||
for (size_t i = 0; i < m_colorUploadCommands.size(); ++i)
|
||||
{
|
||||
yg::Color c = m_colorUploadCommands[i].m_color;
|
||||
m2::RectU const & r = m_colorUploadCommands[i].m_rect;
|
||||
|
||||
TDynamicTexture::pixel_t px;
|
||||
|
||||
gil::get_color(px, gil::red_t()) = c.r / TDynamicTexture::channelScaleFactor;
|
||||
gil::get_color(px, gil::green_t()) = c.g / TDynamicTexture::channelScaleFactor;
|
||||
gil::get_color(px, gil::blue_t()) = c.b / TDynamicTexture::channelScaleFactor;
|
||||
gil::get_color(px, gil::alpha_t()) = c.a / TDynamicTexture::channelScaleFactor;
|
||||
|
||||
TDynamicTexture * dynTexture = static_cast<TDynamicTexture*>(m_texture.get());
|
||||
|
||||
TDynamicTexture::view_t v = dynTexture->view(r.SizeX(), r.SizeY());
|
||||
|
||||
for (size_t y = 0; y < r.SizeY(); ++y)
|
||||
for (size_t x = 0; x < r.SizeX(); ++x)
|
||||
v(x, y) = px;
|
||||
|
||||
dynTexture->upload(&v(0, 0), r);
|
||||
}
|
||||
m_colorUploadCommands.clear();
|
||||
}
|
||||
|
||||
bool SkinPage::hasData()
|
||||
{
|
||||
return ((!m_colorUploadCommands.empty())
|
||||
|| (!m_penUploadCommands.empty())
|
||||
|| (!m_glyphUploadCommands.empty())
|
||||
|| (!m_circleUploadCommands.empty()));
|
||||
return !m_uploadQueue.empty();
|
||||
}
|
||||
|
||||
void SkinPage::checkTexture() const
|
||||
|
@ -765,10 +322,23 @@ namespace yg
|
|||
{
|
||||
checkTexture();
|
||||
static_cast<gl::ManagedTexture*>(m_texture.get())->lock();
|
||||
uploadColors();
|
||||
uploadPenInfo();
|
||||
uploadGlyphs();
|
||||
uploadCircleInfo();
|
||||
|
||||
TDynamicTexture * dynTexture = static_cast<TDynamicTexture*>(m_texture.get());
|
||||
|
||||
for (size_t i = 0; i < m_uploadQueue.size(); ++i)
|
||||
{
|
||||
shared_ptr<ResourceStyle> const & style = m_uploadQueue[i];
|
||||
|
||||
TDynamicTexture::view_t v = dynTexture->view(style->m_texRect.SizeX(),
|
||||
style->m_texRect.SizeY());
|
||||
|
||||
style->render(&v(0, 0));
|
||||
|
||||
dynTexture->upload(&v(0, 0), style->m_texRect);
|
||||
}
|
||||
|
||||
m_uploadQueue.clear();
|
||||
|
||||
static_cast<gl::ManagedTexture*>(m_texture.get())->unlock();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,47 +17,15 @@ namespace yg
|
|||
class BaseTexture;
|
||||
}
|
||||
|
||||
struct CharStyle;
|
||||
struct GlyphStyle;
|
||||
struct ResourceStyle;
|
||||
class ResourceManager;
|
||||
struct GlyphInfo;
|
||||
|
||||
struct GlyphUploadCmd
|
||||
{
|
||||
shared_ptr<GlyphInfo> m_glyphInfo;
|
||||
m2::RectU m_rect;
|
||||
GlyphUploadCmd(shared_ptr<GlyphInfo> const & glyphInfo, m2::RectU const & rect);
|
||||
GlyphUploadCmd();
|
||||
};
|
||||
|
||||
struct ColorUploadCmd
|
||||
{
|
||||
yg::Color m_color;
|
||||
m2::RectU m_rect;
|
||||
ColorUploadCmd(yg::Color const & color, m2::RectU const & rect);
|
||||
ColorUploadCmd();
|
||||
};
|
||||
|
||||
struct PenUploadCmd
|
||||
{
|
||||
yg::PenInfo m_penInfo;
|
||||
m2::RectU m_rect;
|
||||
PenUploadCmd(yg::PenInfo const & penInfo, m2::RectU const & rect);
|
||||
PenUploadCmd();
|
||||
};
|
||||
|
||||
struct CircleUploadCmd
|
||||
{
|
||||
yg::CircleInfo m_circleInfo;
|
||||
m2::RectU m_rect;
|
||||
CircleUploadCmd(yg::CircleInfo const & circleInfo, m2::RectU const & rect);
|
||||
CircleUploadCmd();
|
||||
};
|
||||
|
||||
struct FontInfo
|
||||
{
|
||||
int8_t m_fontSize;
|
||||
typedef map<int32_t, pair<shared_ptr<CharStyle>, shared_ptr<CharStyle> > > TChars;
|
||||
typedef map<int32_t, pair<shared_ptr<GlyphStyle>, shared_ptr<GlyphStyle> > > TChars;
|
||||
TChars m_chars;
|
||||
|
||||
mutable pair<ResourceStyle *, ResourceStyle *> m_invalidChar;
|
||||
|
@ -106,17 +74,9 @@ namespace yg
|
|||
mutable shared_ptr<ResourceManager> m_resourceManager;
|
||||
/// @}
|
||||
|
||||
vector<ColorUploadCmd> m_colorUploadCommands;
|
||||
vector<PenUploadCmd> m_penUploadCommands;
|
||||
vector<GlyphUploadCmd> m_glyphUploadCommands;
|
||||
vector<CircleUploadCmd> m_circleUploadCommands;
|
||||
vector<shared_ptr<ResourceStyle> > m_uploadQueue;
|
||||
|
||||
void uploadPenInfo();
|
||||
void uploadColors();
|
||||
void uploadGlyphs();
|
||||
void uploadCircleInfo();
|
||||
|
||||
void clearUploadCommands();
|
||||
void clearUploadQueue();
|
||||
|
||||
typedef vector<FontInfo> TFonts;
|
||||
TFonts m_fonts;
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#include "../base/SRC_FIRST.hpp"
|
||||
#include "../base/logging.hpp"
|
||||
|
||||
#include "symbol_element.hpp"
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "overlay_element.hpp"
|
||||
#include "text_element.hpp"
|
||||
|
||||
namespace yg
|
||||
{
|
||||
|
|
|
@ -75,7 +75,7 @@ namespace yg
|
|||
fontDesc.m_isMasked,
|
||||
fontDesc.m_isMasked ? fontDesc.m_maskColor : fontDesc.m_color);
|
||||
uint32_t const glyphID = skin->mapGlyph(glyphKey, screen->glyphCache());
|
||||
CharStyle const * charStyle = static_cast<CharStyle const *>(skin->fromID(glyphID));
|
||||
GlyphStyle const * glyphStyle = static_cast<GlyphStyle const *>(skin->fromID(glyphID));
|
||||
|
||||
m2::PointD glyphPt;
|
||||
ang::AngleD glyphAngle;
|
||||
|
@ -91,7 +91,7 @@ namespace yg
|
|||
glyphAngle = ang::AngleD(elem.m_angle.val() + deltaA);
|
||||
}
|
||||
|
||||
screen->drawGlyph(glyphPt, m2::PointD(0.0, 0.0), glyphAngle, 0, charStyle, depth);
|
||||
screen->drawGlyph(glyphPt, m2::PointD(0.0, 0.0), glyphAngle, 0, glyphStyle, depth);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,10 +28,10 @@ namespace yg
|
|||
{}
|
||||
|
||||
|
||||
void TextRenderer::drawGlyph(m2::PointD const & ptOrg, m2::PointD const & ptGlyph, ang::AngleD const & angle, float /*blOffset*/, CharStyle const * p, double depth)
|
||||
void TextRenderer::drawGlyph(m2::PointD const & ptOrg, m2::PointD const & ptGlyph, ang::AngleD const & angle, float /*blOffset*/, GlyphStyle const * p, double depth)
|
||||
{
|
||||
float x0 = ptGlyph.x + (p->m_xOffset - 1);
|
||||
float y1 = ptGlyph.y - (p->m_yOffset - 1);
|
||||
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 y0 = y1 - (p->m_texRect.SizeY() - 2);
|
||||
float x1 = x0 + (p->m_texRect.SizeX() - 2);
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ namespace yg
|
|||
m2::PointD const & ptGlyph,
|
||||
ang::AngleD const & angle,
|
||||
float blOffset,
|
||||
CharStyle const * p,
|
||||
GlyphStyle const * p,
|
||||
double depth);
|
||||
|
||||
|
||||
|
|
18
yg/yg.pro
18
yg/yg.pro
|
@ -57,7 +57,11 @@ SOURCES += \
|
|||
composite_overlay_element.cpp \
|
||||
path_text_element.cpp \
|
||||
straight_text_element.cpp \
|
||||
rendercontext.cpp
|
||||
rendercontext.cpp \
|
||||
line_style.cpp \
|
||||
circle_style.cpp \
|
||||
glyph_style.cpp \
|
||||
circle_element.cpp
|
||||
|
||||
HEADERS += \
|
||||
internal/opengl.hpp \
|
||||
|
@ -110,17 +114,11 @@ HEADERS += \
|
|||
styles_cache.hpp \
|
||||
composite_overlay_element.hpp \
|
||||
path_text_element.hpp \
|
||||
straight_text_element.hpp
|
||||
straight_text_element.hpp \
|
||||
agg_traits.hpp \
|
||||
circle_element.hpp
|
||||
|
||||
win32 {
|
||||
HEADERS += internal/opengl_win32.hpp
|
||||
SOURCES += internal/opengl_win32.cpp
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue