Calculate text position the same way as it was done in Mapnik 2.0.

This commit is contained in:
Hermann Kraus 2012-07-29 03:50:22 +02:00
parent 22aeba9bbd
commit d3c473bbdc
6 changed files with 38 additions and 30 deletions

View file

@ -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_;
}; };

View file

@ -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));

View file

@ -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;
} }

View file

@ -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();

View file

@ -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;
} }

View file

@ -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);