mapnik/include/mapnik/text/glyph_positions.hpp
2017-05-05 13:02:01 +02:00

137 lines
4.1 KiB
C++

/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2017 Artem Pavlenko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*****************************************************************************/
#ifndef MAPNIK_TEXT_GLYPH_POSITIONS_HPP
#define MAPNIK_TEXT_GLYPH_POSITIONS_HPP
//mapnik
#include <mapnik/geometry/box2d.hpp>
#include <mapnik/pixel_position.hpp>
#include <mapnik/text/rotation.hpp>
#include <mapnik/marker_cache.hpp>
#include <mapnik/text/glyph_info.hpp>
#pragma GCC diagnostic push
#include <mapnik/warning_ignore_agg.hpp>
#include "agg_trans_affine.h"
#pragma GCC diagnostic pop
//stl
#include <vector>
#include <list>
namespace mapnik
{
struct glyph_position
{
glyph_position(glyph_info const& _glyph, pixel_position const& _pos, rotation const& _rot)
: glyph(_glyph), pos(_pos), rot(_rot) { }
glyph_info const& glyph;
pixel_position pos;
rotation rot;
};
struct marker_info
{
//marker_info() : marker(), transform() {}
marker_info(std::shared_ptr<marker const> _marker, agg::trans_affine const& _transform) :
marker_(_marker), transform_(_transform) {}
std::shared_ptr<marker const> marker_;
agg::trans_affine transform_;
};
using marker_info_ptr = std::shared_ptr<marker_info>;
/** Stores positions of glphys.
*
* The actual glyphs and their format are stored in text_layout.
*/
class glyph_positions
{
public:
using const_iterator = std::vector<glyph_position>::const_iterator;
glyph_positions();
std::size_t size() const { return data_.size(); };
const_iterator begin() const;
const_iterator end() const;
void emplace_back(glyph_info const& glyph, pixel_position offset, rotation const& rot);
void reserve(unsigned count);
pixel_position const& get_base_point() const;
void set_base_point(pixel_position const& base_point);
void set_marker(marker_info_ptr marker, pixel_position const& marker_pos);
marker_info_ptr const& get_marker() const;
pixel_position const& marker_pos() const;
private:
std::vector<glyph_position> data_;
pixel_position base_point_;
marker_info_ptr marker_info_;
pixel_position marker_pos_;
box2d<double> bbox_;
};
using glyph_positions_ptr = std::unique_ptr<glyph_positions>;
using placements_list = std::list<glyph_positions_ptr>;
struct scoped_glyph_positions_offset
{
scoped_glyph_positions_offset(glyph_positions & glyphs, pixel_position const& offset)
: glyphs_(glyphs)
, base_point_(glyphs.get_base_point())
, marker_pos_(glyphs.marker_pos())
{
// move the glyphs to the correct offset
glyphs_.set_base_point(base_point_ + offset);
// update the position of any marker
if (auto const& marker_info = glyphs_.get_marker())
{
glyphs_.set_marker(marker_info, marker_pos_ + offset);
}
}
~scoped_glyph_positions_offset()
{
// set the base_point back how it was
glyphs_.set_base_point(base_point_);
// restore marker as well, if there is any
if (auto const& marker_info = glyphs_.get_marker())
{
glyphs_.set_marker(marker_info, marker_pos_);
}
}
private:
glyph_positions & glyphs_;
pixel_position base_point_;
pixel_position marker_pos_;
};
} // namespace mapnik
#endif // MAPNIK_TEXT_GLYPH_POSITIONS_HPP