public:
impl(texture_atlas& atlas, const text_info& info, bool normalize_coordinates)
- : face_(get_new_face(u8(info.font_file)))
+ : face_(get_new_face(u8(info.font_file), u8(info.font)))
, atlas_(atlas)
, size_(info.size)
, tracking_(info.size*info.tracking/1000.0)
, name_(info.font)
{
if (FT_Set_Char_Size(face_.get(), static_cast<FT_F26Dot6>(size_*64), 0, 72, 72))
- CASPAR_THROW_EXCEPTION(freetype_exception() << msg_info("Failed to set font size"));
+ CASPAR_THROW_EXCEPTION(expected_freetype_exception() << msg_info("Failed to set font size"));
}
- void set_tracking(int tracking)
+ void set_tracking(double tracking)
{
tracking_ = size_ * tracking / 1000.0;
}
int count_glyphs_in_range(unicode_block block)
- {
+ {
unicode_range range = get_range(block);
//TODO: extract info from freetype
FT_UInt glyph_index = FT_Get_Char_Index(face_.get(), i);
if(!glyph_index) //ignore codes that doesn't have a glyph for now. Might want to map these to a special glyph later.
continue;
-
+
FT_Error err = FT_Load_Glyph(face_.get(), glyph_index, flags);
if(err) continue; //igonore glyphs that fail to load
}
atlas_.set_region(region.x, region.y, bitmap.width, bitmap.rows, bitmap.buffer, bitmap.pitch, col);
- glyphs_.insert(std::pair<int, glyph_info>(i, glyph_info(bitmap.width, bitmap.rows,
+ glyphs_.insert(std::pair<int, glyph_info>(i, glyph_info(bitmap.width, bitmap.rows,
region.x / static_cast<double>(atlas_.width()),
region.y / static_cast<double>(atlas_.height()),
(region.x + bitmap.width) / static_cast<double>(atlas_.width()),
}
}
- std::vector<frame_geometry::coord> create_vertex_stream(const std::wstring& str, int x, int y, int parent_width, int parent_height, string_metrics* metrics)
+ std::vector<frame_geometry::coord> create_vertex_stream(const std::wstring& str, int x, int y, int parent_width, int parent_height, string_metrics* metrics, double shear)
{
//TODO: detect glyphs that aren't in the atlas and load them (and maybe that entire unicode_block on the fly
{
auto glyph_it = glyphs_.find(*it);
if (glyph_it != glyphs_.end())
- {
+ {
const glyph_info& coords = glyph_it->second;
FT_UInt glyph_index = FT_Get_Char_Index(face_.get(), (*it));
auto ll_index = ul_index + 3;
//vertex 1 upper left
- result[ul_index].vertex_x = left; //vertex.x
+ result[ul_index].vertex_x = left; //vertex.x
result[ul_index].vertex_y = top; //vertex.y
result[ul_index].texture_x = coords.left; //texcoord.r
result[ul_index].texture_y = coords.top; //texcoord.s
//vertex 2 upper right
- result[ur_index].vertex_x = right; //vertex.x
+ result[ur_index].vertex_x = right; //vertex.x
result[ur_index].vertex_y = top; //vertex.y
result[ur_index].texture_x = coords.right; //texcoord.r
result[ur_index].texture_y = coords.top; //texcoord.s
//vertex 3 lower right
- result[lr_index].vertex_x = right; //vertex.x
- result[lr_index].vertex_y = bottom; //vertex.y
- result[lr_index].texture_x = coords.right; //texcoord.r
- result[lr_index].texture_y = coords.bottom; //texcoord.s
+ result[lr_index].vertex_x = right; //vertex.x
+ result[lr_index].vertex_y = bottom; //vertex.y
+ result[lr_index].texture_x = coords.right; //texcoord.r
+ result[lr_index].texture_y = coords.bottom; //texcoord.s
//vertex 4 lower left
- result[ll_index].vertex_x = left; //vertex.x
- result[ll_index].vertex_y = bottom; //vertex.y
- result[ll_index].texture_x = coords.left; //texcoord.r
- result[ll_index].texture_y = coords.bottom; //texcoord.s
+ result[ll_index].vertex_x = left; //vertex.x
+ result[ll_index].vertex_y = bottom; //vertex.y
+ result[ll_index].texture_x = coords.left; //texcoord.r
+ result[ll_index].texture_y = coords.bottom; //texcoord.s
int bearingY = face_->glyph->metrics.horiBearingY >> 6;
string_metrics measure_string(const std::wstring& str)
{
string_metrics result;
-
+
bool use_kerning = (face_->face_flags & FT_FACE_FLAG_KERNING) == FT_FACE_FLAG_KERNING;
int index = 0;
FT_UInt previous = 0;
{
auto glyph_it = glyphs_.find(*it);
if(glyph_it != glyphs_.end())
- {
+ {
const glyph_info& coords = glyph_it->second;
FT_UInt glyph_index = FT_Get_Char_Index(face_.get(), (*it));
{
return size_;
}
-};
+};
texture_font::texture_font(texture_atlas& atlas, const text_info& info, bool normalize_coordinates) : impl_(new impl(atlas, info, normalize_coordinates)) {}
void texture_font::load_glyphs(unicode_block range, const color<double>& col) { impl_->load_glyphs(range, col); }
-void texture_font::set_tracking(int tracking) { impl_->set_tracking(tracking); }
-std::vector<frame_geometry::coord> texture_font::create_vertex_stream(const std::wstring& str, int x, int y, int parent_width, int parent_height, string_metrics* metrics) { return impl_->create_vertex_stream(str, x, y, parent_width, parent_height, metrics); }
+void texture_font::set_tracking(double tracking) { impl_->set_tracking(tracking); }
+std::vector<frame_geometry::coord> texture_font::create_vertex_stream(const std::wstring& str, int x, int y, int parent_width, int parent_height, string_metrics* metrics, double shear) { return impl_->create_vertex_stream(str, x, y, parent_width, parent_height, metrics, shear); }
string_metrics texture_font::measure_string(const std::wstring& str) { return impl_->measure_string(str); }
std::wstring texture_font::get_name() const { return impl_->get_name(); }
double texture_font::get_size() const { return impl_->get_size(); }