Calculate text position the same way as it was done in Mapnik 2.0.
This commit is contained in:
parent
22aeba9bbd
commit
d3c473bbdc
6 changed files with 38 additions and 30 deletions
|
@ -48,8 +48,7 @@ namespace mapnik
|
||||||
class font_face : boost::noncopyable
|
class font_face : boost::noncopyable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
font_face(FT_Face face)
|
font_face(FT_Face face);
|
||||||
: face_(face) {}
|
|
||||||
|
|
||||||
std::string family_name() const
|
std::string family_name() const
|
||||||
{
|
{
|
||||||
|
@ -66,32 +65,18 @@ public:
|
||||||
return face_;
|
return face_;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned get_char(unsigned c) const
|
double get_char_height() const;
|
||||||
{
|
|
||||||
return FT_Get_Char_Index(face_, c);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool set_pixel_sizes(unsigned size)
|
bool set_character_sizes(float size);
|
||||||
{
|
|
||||||
if (! FT_Set_Pixel_Sizes( face_, 0, size ))
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool set_character_sizes(float size)
|
void glyph_dimensions(glyph_info &glyph) const;
|
||||||
{
|
|
||||||
if ( !FT_Set_Char_Size(face_,0,(FT_F26Dot6)(size * (1<<6)),0,0))
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void glyph_dimensions(glyph_info &glyph);
|
|
||||||
|
|
||||||
~font_face();
|
~font_face();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FT_Face face_;
|
FT_Face face_;
|
||||||
std::map<glyph_index_t, glyph_info> dimension_cache_;
|
mutable std::map<glyph_index_t, glyph_info> dimension_cache_;
|
||||||
|
mutable double char_height_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,28 @@ extern "C"
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
{
|
{
|
||||||
|
|
||||||
void font_face::glyph_dimensions(glyph_info &glyph)
|
font_face::font_face(FT_Face face)
|
||||||
|
: face_(face), dimension_cache_(), char_height_(0.)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
double font_face::get_char_height() const
|
||||||
|
{
|
||||||
|
if (char_height_ != 0.0) return char_height_;
|
||||||
|
glyph_info tmp;
|
||||||
|
tmp.glyph_index = FT_Get_Char_Index(face_, 'X');
|
||||||
|
glyph_dimensions(tmp);
|
||||||
|
char_height_ = tmp.height();
|
||||||
|
return char_height_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool font_face::set_character_sizes(float size)
|
||||||
|
{
|
||||||
|
char_height_ = 0.;
|
||||||
|
return !FT_Set_Char_Size(face_,0,(FT_F26Dot6)(size * (1<<6)),0,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void font_face::glyph_dimensions(glyph_info &glyph) const
|
||||||
{
|
{
|
||||||
//TODO
|
//TODO
|
||||||
//Check if char is already in cache
|
//Check if char is already in cache
|
||||||
|
@ -64,8 +85,8 @@ void font_face::glyph_dimensions(glyph_info &glyph)
|
||||||
FT_Glyph_Get_CBox(image, ft_glyph_bbox_pixels, &glyph_bbox);
|
FT_Glyph_Get_CBox(image, ft_glyph_bbox_pixels, &glyph_bbox);
|
||||||
FT_Done_Glyph(image);
|
FT_Done_Glyph(image);
|
||||||
|
|
||||||
glyph.ymin = glyph_bbox.yMin; //TODO: Which data format? 26.6, integer?
|
glyph.ymin = glyph_bbox.yMin; //pixels!
|
||||||
glyph.ymax = glyph_bbox.yMax; //TODO: Which data format? 26.6, integer?
|
glyph.ymax = glyph_bbox.yMax;
|
||||||
glyph.line_height = face_->size->metrics.height/64.0;
|
glyph.line_height = face_->size->metrics.height/64.0;
|
||||||
|
|
||||||
//TODO: dimension_cache_.insert(std::pair<unsigned, char_info>(c, dim));
|
//TODO: dimension_cache_.insert(std::pair<unsigned, char_info>(c, dim));
|
||||||
|
|
|
@ -51,7 +51,6 @@ std::list<text_item> const& text_itemizer::itemize(unsigned start, unsigned end)
|
||||||
// format itemiziation is done by add_text()
|
// format itemiziation is done by add_text()
|
||||||
itemize_direction(start, end);
|
itemize_direction(start, end);
|
||||||
itemize_script();
|
itemize_script();
|
||||||
std::cout << "Itemizer: direction: "<< direction_runs.size() << " script: " << script_runs.size() << "\n";
|
|
||||||
create_item_list();
|
create_item_list();
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,7 +122,8 @@ void text_layout::shape_text(text_line_ptr line, unsigned start, unsigned end)
|
||||||
face_set->set_character_sizes(itr->format->text_size);
|
face_set->set_character_sizes(itr->format->text_size);
|
||||||
face_ptr face = *(face_set->begin()); //TODO: Implement font sets correctly
|
face_ptr face = *(face_set->begin()); //TODO: Implement font sets correctly
|
||||||
text_shaping shaper(face->get_face()); //TODO: Make this more efficient by caching this object in font_face
|
text_shaping shaper(face->get_face()); //TODO: Make this more efficient by caching this object in font_face
|
||||||
line->update_max_char_height(itr->format->text_size /*TODO*/);
|
|
||||||
|
line->update_max_char_height(face->get_char_height());
|
||||||
|
|
||||||
shaper.process_text(text, itr->start, itr->end, itr->rtl == UBIDI_RTL, itr->script);
|
shaper.process_text(text, itr->start, itr->end, itr->rtl == UBIDI_RTL, itr->script);
|
||||||
hb_buffer_t *buffer = shaper.get_buffer();
|
hb_buffer_t *buffer = shaper.get_buffer();
|
||||||
|
|
|
@ -48,6 +48,7 @@ bool placement_finder_ng::next_position()
|
||||||
valid_ = false;
|
valid_ = false;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
info_->properties.process(layout_, feature_);
|
info_->properties.process(layout_, feature_);
|
||||||
layout_.layout(info_->properties.wrap_width, info_->properties.text_ratio);
|
layout_.layout(info_->properties.wrap_width, info_->properties.text_ratio);
|
||||||
|
|
||||||
|
@ -143,7 +144,8 @@ pixel_position placement_finder_ng::alignment_offset() const
|
||||||
glyph_positions_ptr placement_finder_ng::find_point_placement(pixel_position pos)
|
glyph_positions_ptr placement_finder_ng::find_point_placement(pixel_position pos)
|
||||||
{
|
{
|
||||||
glyph_positions_ptr glyphs = boost::make_shared<glyph_positions>();
|
glyph_positions_ptr glyphs = boost::make_shared<glyph_positions>();
|
||||||
if (!layout_.size()) return glyphs; //No data
|
if (!layout_.size()) return glyphs; /* No data. Don't return NULL pointer, which would mean
|
||||||
|
that not enough space was available. */
|
||||||
|
|
||||||
//TODO: Verify enough space is available. For point placement the bounding box is enough!
|
//TODO: Verify enough space is available. For point placement the bounding box is enough!
|
||||||
|
|
||||||
|
@ -163,7 +165,6 @@ glyph_positions_ptr placement_finder_ng::find_point_placement(pixel_position pos
|
||||||
text_layout::const_iterator line_itr = layout_.begin(), line_end = layout_.end();
|
text_layout::const_iterator line_itr = layout_.begin(), line_end = layout_.end();
|
||||||
for (; line_itr != line_end; line_itr++)
|
for (; line_itr != line_end; line_itr++)
|
||||||
{
|
{
|
||||||
// text_line *line_itr;
|
|
||||||
y -= (*line_itr)->height(); //Automatically handles first line differently
|
y -= (*line_itr)->height(); //Automatically handles first line differently
|
||||||
// reset to begining of line position
|
// reset to begining of line position
|
||||||
if (jalign_ == J_LEFT)
|
if (jalign_ == J_LEFT)
|
||||||
|
@ -176,7 +177,6 @@ glyph_positions_ptr placement_finder_ng::find_point_placement(pixel_position pos
|
||||||
text_line::const_iterator glyph_itr = (*line_itr)->begin(), glyph_end = (*line_itr)->end();
|
text_line::const_iterator glyph_itr = (*line_itr)->begin(), glyph_end = (*line_itr)->end();
|
||||||
for (; glyph_itr != glyph_end; glyph_itr++)
|
for (; glyph_itr != glyph_end; glyph_itr++)
|
||||||
{
|
{
|
||||||
// glyph_info *glyph_itr;
|
|
||||||
glyphs->push_back(*glyph_itr, pixel_position(x, y), angle_); //TODO: Store cosa, sina instead
|
glyphs->push_back(*glyph_itr, pixel_position(x, y), angle_); //TODO: Store cosa, sina instead
|
||||||
x += glyph_itr->width + glyph_itr->format->character_spacing;
|
x += glyph_itr->width + glyph_itr->format->character_spacing;
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,9 @@ uint32_t text_shaping::process_text(UnicodeString const& text, unsigned start, u
|
||||||
hb_buffer_set_unicode_funcs(buffer_, hb_icu_get_unicode_funcs());
|
hb_buffer_set_unicode_funcs(buffer_, hb_icu_get_unicode_funcs());
|
||||||
|
|
||||||
uint32_t length = text.length();
|
uint32_t length = text.length();
|
||||||
std::cout << "process_text: length: " << length << " start: " << start << " end: " << end << "rtl:" << rtl << "\n";
|
std::string s;
|
||||||
|
text.toUTF8String(s);
|
||||||
|
std::cout << "process_text: length: " << length << " start: " << start << " end: " << end << "rtl:" << rtl << "text: '"<<s<< "'\n";
|
||||||
|
|
||||||
hb_buffer_add_utf16(buffer_, text.getBuffer(), length, start, end-start);
|
hb_buffer_add_utf16(buffer_, text.getBuffer(), length, start, end-start);
|
||||||
hb_buffer_set_direction(buffer_, rtl?HB_DIRECTION_RTL:HB_DIRECTION_LTR);
|
hb_buffer_set_direction(buffer_, rtl?HB_DIRECTION_RTL:HB_DIRECTION_LTR);
|
||||||
|
|
Loading…
Reference in a new issue