work-in-progress
This commit is contained in:
parent
6c54adc389
commit
2ceaa110cb
7 changed files with 44 additions and 37 deletions
|
@ -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.
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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_;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue