Calculate glyph dimensions.

This commit is contained in:
Hermann Kraus 2012-06-30 21:40:41 +02:00
parent bf66b71f3e
commit ead99b1411
8 changed files with 248 additions and 70 deletions

View file

@ -33,6 +33,7 @@
#include <mapnik/char_info.hpp>
#include <mapnik/pixel_position.hpp>
#include <mapnik/image_compositing.hpp>
#include <mapnik/text/face.hpp>
// freetype2
extern "C"
@ -69,8 +70,6 @@ class font_face;
class text_path;
class string_info;
typedef boost::shared_ptr<font_face> face_ptr;
class MAPNIK_DECL font_glyph
{
public:
@ -94,62 +93,6 @@ public:
typedef boost::shared_ptr<font_glyph> glyph_ptr;
class font_face : boost::noncopyable
{
public:
font_face(FT_Face face)
: face_(face) {}
std::string family_name() const
{
return std::string(face_->family_name);
}
std::string style_name() const
{
return std::string(face_->style_name);
}
FT_GlyphSlot glyph() const
{
return face_->glyph;
}
FT_Face get_face() const
{
return face_;
}
unsigned get_char(unsigned c) const
{
return FT_Get_Char_Index(face_, c);
}
bool set_pixel_sizes(unsigned size)
{
if (! FT_Set_Pixel_Sizes( face_, 0, size ))
return true;
return false;
}
bool set_character_sizes(float size)
{
if ( !FT_Set_Char_Size(face_,0,(FT_F26Dot6)(size * (1<<6)),0,0))
return true;
return false;
}
~font_face()
{
MAPNIK_LOG_DEBUG(font_engine_freetype) << "font_face: Clean up face \"" << family_name() << " " << style_name() << "\"";
FT_Done_Face(face_);
}
private:
FT_Face face_;
};
class MAPNIK_DECL font_face_set : private boost::noncopyable
{
public:

View file

@ -0,0 +1,97 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2012 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_FACE_HPP
#define MAPNIK_FACE_HPP
//mapnik
#include <mapnik/text/glyph_info.hpp>
// freetype2
extern "C"
{
#include <ft2build.h>
#include FT_FREETYPE_H
}
//boost
#include <boost/utility.hpp>
#include <boost/shared_ptr.hpp>
//stl
#include <map>
#include <string>
namespace mapnik
{
class font_face : boost::noncopyable
{
public:
font_face(FT_Face face)
: face_(face) {}
std::string family_name() const
{
return std::string(face_->family_name);
}
std::string style_name() const
{
return std::string(face_->style_name);
}
FT_Face get_face() const
{
return face_;
}
unsigned get_char(unsigned c) const
{
return FT_Get_Char_Index(face_, c);
}
bool set_pixel_sizes(unsigned size)
{
if (! FT_Set_Pixel_Sizes( face_, 0, size ))
return true;
return false;
}
bool set_character_sizes(float size)
{
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();
private:
FT_Face face_;
std::map<glyph_index_t, glyph_info> dimension_cache_;
};
} //ns mapnik
#endif // FACE_HPP

View file

@ -0,0 +1,56 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2012 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_GLYPH_INFO_HPP
#define MAPNIK_GLYPH_INFO_HPP
//boost
#include <boost/shared_ptr.hpp>
namespace mapnik
{
class font_face;
struct char_properties;
typedef boost::shared_ptr<font_face> face_ptr;
typedef unsigned glyph_index_t;
struct glyph_info
{
glyph_info()
: glyph_index(0), face(), char_index(0), format(0),
width(0), ymin(0), ymax(0), line_height(0), valid(false) {}
glyph_index_t glyph_index;
face_ptr face;
unsigned char_index; //Position in the string of all characters i.e. before itemizing
char_properties *format;
double width;
double ymin;
double ymax;
double line_height;
bool valid; //Are all values valid?
double height() const { return ymax-ymin; }
};
} //ns mapnik
#endif // GLYPH_INFO_HPP

View file

@ -25,6 +25,7 @@
//mapnik
#include <mapnik/text/itemizer.hpp>
#include <mapnik/font_engine_freetype.hpp>
#include <mapnik/text/glyph_info.hpp>
//stl
#include <vector>
@ -32,13 +33,6 @@
namespace mapnik
{
struct glyph_info
{
font_glyph glyph;
uint32_t char_index; //Position in the string of all characters i.e. before itemizing
uint32_t x_advance;
};
class text_layout
{
public:

View file

@ -185,6 +185,7 @@ source = Split(
text/layout.cpp
text/itemizer.cpp
text/scrptrun.cpp
text/face.cpp
"""
)

View file

@ -531,4 +531,5 @@ template box2d<double>text_renderer<image_32>::prepare_glyphs(text_path*);
template void text_renderer<grid>::render_id(int, pixel_position, double );
template text_renderer<grid>::text_renderer(grid&, face_manager<freetype_engine>&, stroker&, composite_mode_e);
template box2d<double>text_renderer<grid>::prepare_glyphs(text_path*);
}

81
src/text/face.cpp Normal file
View file

@ -0,0 +1,81 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2012 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
*
*****************************************************************************/
#include <mapnik/text/face.hpp>
#include <mapnik/debug.hpp>
extern "C"
{
#include FT_GLYPH_H
}
namespace mapnik
{
void font_face::glyph_dimensions(glyph_info &glyph)
{
//TODO
//Check if char is already in cache
// std::map<glyph_index_t, glyph_info>::const_iterator itr;
// itr = dimension_cache_.find(glyph.glyph_index);
// if (itr != dimension_cache_.end()) {
// glyph = itr->second;
// return;
// }
FT_Matrix matrix;
FT_Vector pen;
pen.x = 0;
pen.y = 0;
FT_BBox glyph_bbox;
FT_Glyph image;
matrix.xx = (FT_Fixed)( 1 * 0x10000L );
matrix.xy = (FT_Fixed)( 0 * 0x10000L );
matrix.yx = (FT_Fixed)( 0 * 0x10000L );
matrix.yy = (FT_Fixed)( 1 * 0x10000L );
FT_Set_Transform(face_, &matrix, &pen); //TODO: Matrix is always only set to the identity matrix. This seems to be useless.
if (FT_Load_Glyph (face_, glyph.glyph_index, FT_LOAD_NO_HINTING)) return;
if (FT_Get_Glyph(face_->glyph, &image)) return;
FT_Glyph_Get_CBox(image, ft_glyph_bbox_pixels, &glyph_bbox);
FT_Done_Glyph(image);
glyph.ymin = glyph_bbox.yMin; //TODO: Which data format? 26.6, integer?
glyph.ymax = glyph_bbox.yMax; //TODO: Which data format? 26.6, integer?
glyph.line_height = face_->size->metrics.height/64.0;
//TODO: dimension_cache_.insert(std::pair<unsigned, char_info>(c, dim));
}
font_face::~font_face()
{
MAPNIK_LOG_DEBUG(font_face) <<
"font_face: Clean up face \"" << family_name() <<
" " << style_name() << "\"";
FT_Done_Face(face_);
}
}//ns mapnik

View file

@ -32,6 +32,8 @@
* processed_text
* string_info
* text_path
* char_info
* font_glyph
*/
namespace mapnik
@ -73,9 +75,10 @@ void text_layout::shape_text()
{
glyph_info tmp;
tmp.char_index = offset + glyphs[i].cluster;
tmp.glyph.index = glyphs[i].codepoint;
tmp.glyph.face = face;
tmp.x_advance = positions[i].x_advance;
tmp.glyph_index = glyphs[i].codepoint;
tmp.width = positions[i].x_advance / 64.0;
tmp.face = face;
face->glyph_dimensions(tmp);
glyphs_.push_back(tmp);
}
offset += chars;
@ -85,9 +88,11 @@ void text_layout::shape_text()
for (;itr2 != end2; itr2++)
{
std::cout << "'" << (char) itemizer.get_text().charAt(itr2->char_index) <<
"' glyph codepoint:" << itr2->glyph.index <<
"' glyph codepoint:" << itr2->glyph_index <<
" cluster: " << itr2->char_index <<
" x_advance: "<< itr2->x_advance/64.0 << "\n";
" width: "<< itr2->width <<
" height: " << itr2->height() <<
"\n";
}
}