work-in-progress

This commit is contained in:
artemp 2015-06-30 16:55:58 +02:00
parent 6c54adc389
commit 2ceaa110cb
7 changed files with 44 additions and 37 deletions

View file

@ -92,7 +92,8 @@ static void shape_text(text_line & line,
{
++pos;
hb_buffer_clear_contents(buffer.get());
hb_buffer_add_utf16(buffer.get(), uchar_to_utf16(text.getBuffer()), text.length(), text_item.start, static_cast<int>(text_item.end - text_item.start));
hb_buffer_add_utf16(buffer.get(), uchar_to_utf16(text.getBuffer()), text.length(), text_item.start,
static_cast<int>(text_item.end - text_item.start));
hb_buffer_set_direction(buffer.get(), (text_item.dir == UBIDI_RTL)?HB_DIRECTION_RTL:HB_DIRECTION_LTR);
hb_buffer_set_script(buffer.get(), _icu_script_to_script(text_item.script));
hb_font_t *font(hb_ft_font_create(face->get_face(), nullptr));
@ -120,13 +121,15 @@ static void shape_text(text_line & line,
continue;
}
double max_glyph_height = 0;
for (unsigned i=0; i<num_glyphs; ++i)
double ymin = 0.0;
double ymax = 0.0;
for (unsigned i = 0; i < num_glyphs; ++i)
{
auto const& gpos = positions[i];
auto const& glyph = glyphs[i];
unsigned char_index = glyph.cluster;
glyph_info g(glyph.codepoint,char_index,text_item.format_);
if (face->glyph_dimensions(g))
{
g.face = face;
@ -134,13 +137,14 @@ static void shape_text(text_line & line,
//Overwrite default advance with better value provided by HarfBuzz
g.unscaled_advance = gpos.x_advance;
g.offset.set(gpos.x_offset * g.scale_multiplier, gpos.y_offset * g.scale_multiplier);
double tmp_height = g.height();
if (tmp_height > max_glyph_height) max_glyph_height = tmp_height;
width_map[char_index] += g.advance();
line.add_glyph(std::move(g), scale_factor);
ymin = std::min(g.ymin(), ymin);
ymax = std::max(g.ymax(), ymax);
}
}
line.update_max_char_height(max_glyph_height);
std::cerr << "update y min/max " << ymin << "," << ymax << std::endl;
line.set_y_minmax(ymin, ymax);
break; //When we reach this point the current font had all glyphs.
}
}

View file

@ -88,7 +88,8 @@ public:
inline double height() const { return height_; }
// Width of the longest line (in pixels).
inline double width() const { return width_ ; }
inline double ymin() const { return ymin_; }
inline double ymax() const { return ymax_; }
// Line iterator.
inline const_iterator begin() const { return lines_.begin(); }
inline const_iterator end() const { return lines_.end(); }
@ -145,6 +146,8 @@ private:
std::map<unsigned, double> width_map_;
double width_;
double height_;
double ymin_;
double ymax_;
unsigned glyphs_count_;
// output

View file

@ -62,12 +62,15 @@ public:
// Real line height. For first line: max_char_height(), for all others: line_height().
double height() const;
// Height of the tallest glyph in this line.
double max_char_height() const { return max_char_height_; }
// Called for each font/style to update the maximum height of this line.
void update_max_char_height(double max_char_height);
inline double ymin() const { return ymin_; }
inline double ymax() const { return ymax_; }
// Called for each font/style to update the max/min y of this line.
inline void set_y_minmax(double ymin, double ymax)
{
ymin_ = ymin;
ymax_ = ymax;
}
// Line height including line spacing.
double line_height() const { return line_height_; }
@ -83,12 +86,13 @@ public:
// Number of glyphs.
unsigned size() const;
unsigned space_count() const { return space_count_; }
inline unsigned space_count() const { return space_count_; }
private:
glyph_vector glyphs_;
double line_height_; // Includes line spacing (returned by freetype)
double max_char_height_; // Max height of any glyphs in line - calculated by shaper
double ymin_;
double ymax_;
double width_;
double glyphs_width_;
unsigned first_char_;

View file

@ -64,12 +64,14 @@ bool font_face::glyph_dimensions(glyph_info & glyph) const
}
FT_BBox glyph_bbox;
FT_Glyph_Get_CBox(image, FT_GLYPH_BBOX_TRUNCATE, &glyph_bbox);
FT_Done_Glyph(image);
glyph.unscaled_ymin = glyph_bbox.yMin;
glyph.unscaled_ymax = glyph_bbox.yMax;
glyph.unscaled_advance = face_->glyph->advance.x;
glyph.unscaled_line_height = face_->size->metrics.height;
// https://github.com/mapnik/mapnik/issues/2928
std::cerr << "yMin=" << glyph_bbox.yMin << " yMax=" << glyph_bbox.yMax << std::endl;
FT_Done_Glyph(image);
return true;
}

View file

@ -288,7 +288,7 @@ bool placement_finder::single_line_placement(vertex_cache &pp, text_upright_e or
pixel_position pos = off_pp.current_position() + cluster_offset;
// Center the text on the line
double char_height = line.max_char_height();
double char_height = line.ymax() - line.ymin();//line.max_char_height();
pos.y = -pos.y - char_height/2.0*rot.cos;
pos.x = pos.x + char_height/2.0*rot.sin;

View file

@ -37,20 +37,12 @@ namespace mapnik
{
// Output is centered around (0,0)
static void rotated_box2d(box2d<double> & box, rotation const& rot, pixel_position const& center, double width, double height)
static void rotated_box2d(box2d<double> & box, rotation const& rot, pixel_position const& center, double width, double ymin, double ymax)
{
double half_width, half_height;
if (true)//rot.sin == 0 && rot.cos == 1.)
{
half_width = width / 2.;
half_height = height / 2.;
}
else
{
half_width = (width * rot.cos + height * rot.sin) /2.;
half_height = (width * rot.sin + height * rot.cos) /2.;
}
box.init(center.x - half_width, center.y - half_height, center.x + half_width, center.y + half_height);
half_width = width / 2.;
half_height = (ymax - ymin) / 2.;
box.init(center.x - half_width, center.y - half_height + ymin, center.x + half_width, center.y + half_height + ymin);
}
pixel_position evaluate_displacement(double dx, double dy, directions_e dir)
@ -107,6 +99,8 @@ text_layout::text_layout(face_manager_freetype & font_manager,
width_map_(),
width_(0.0),
height_(0.0),
ymin_(0.0),
ymax_(0.0),
glyphs_count_(0),
lines_(),
layout_properties_(layout_defaults),
@ -198,10 +192,11 @@ void text_layout::layout()
init_auto_alignment();
// Find text origin.
std::cerr << "ymin=" << ymin_ << " ymax=" << ymax_ << std::endl;
displacement_ = scale_factor_ * displacement_ + alignment_offset();
if (rotate_displacement_) displacement_ = displacement_.rotate(!orientation_);
// Find layout bounds, expanded for rotation
rotated_box2d(bounds_, orientation_, displacement_, width_, height_);
rotated_box2d(bounds_, orientation_, displacement_, width_, ymin_, ymax_);
}
// In the Unicode string characters are always stored in logical order.
@ -414,6 +409,8 @@ void text_layout::add_line(text_line && line)
line.set_first_line(true);
}
height_ += line.height();
ymin_ += line.ymin();
ymax_ += line.ymax();
glyphs_count_ += line.size();
width_ = std::max(width_, line.width());
lines_.emplace_back(std::move(line));

View file

@ -29,7 +29,8 @@ namespace mapnik {
text_line::text_line(unsigned first_char, unsigned last_char)
: glyphs_(),
line_height_(0.0),
max_char_height_(0.0),
ymin_(0.0),
ymax_(0.0),
width_(0.0),
glyphs_width_(0.0),
first_char_(first_char),
@ -41,7 +42,8 @@ text_line::text_line(unsigned first_char, unsigned last_char)
text_line::text_line(text_line && rhs)
: glyphs_(std::move(rhs.glyphs_)),
line_height_(std::move(rhs.line_height_)),
max_char_height_(std::move(rhs.max_char_height_)),
ymin_(std::move(rhs.ymin_)),
ymax_(std::move(rhs.ymax_)),
width_(std::move(rhs.width_)),
glyphs_width_(std::move(rhs.glyphs_width_)),
first_char_(std::move(rhs.first_char_)),
@ -86,15 +88,10 @@ text_line::const_iterator text_line::end() const
double text_line::height() const
{
if (first_line_) return max_char_height_;
if (first_line_) return ymax_ - ymin_;
return line_height_;
}
void text_line::update_max_char_height(double max_char_height)
{
max_char_height_ = std::max(max_char_height_, max_char_height);
}
void text_line::set_first_line(bool first_line)
{
first_line_ = first_line;