void text_renderer::prepare_glyphs(glyph_positions const& positions) { FT_Matrix matrix; FT_Vector pen; FT_Error error; glyphs_.reserve(positions.size()); for (auto const& glyph_pos : positions) { glyph_info const& glyph = glyph_pos.glyph; glyph.face->set_character_sizes(glyph.format->text_size * scale_factor_); //TODO: Optimize this? matrix.xx = static_cast<FT_Fixed>( glyph_pos.rot.cos * 0x10000L); matrix.xy = static_cast<FT_Fixed>(-glyph_pos.rot.sin * 0x10000L); matrix.yx = static_cast<FT_Fixed>( glyph_pos.rot.sin * 0x10000L); matrix.yy = static_cast<FT_Fixed>( glyph_pos.rot.cos * 0x10000L); pixel_position pos = glyph_pos.pos + glyph.offset.rotate(glyph_pos.rot); pen.x = static_cast<FT_Pos>(pos.x * 64); pen.y = static_cast<FT_Pos>(pos.y * 64); FT_Face face = glyph.face->get_face(); FT_Set_Transform(face, &matrix, &pen); error = FT_Load_Glyph(face, glyph.glyph_index, FT_LOAD_NO_HINTING); if (error) continue; FT_Glyph image; error = FT_Get_Glyph(face->glyph, &image); if (error) continue; glyphs_.emplace_back(image, *glyph.format); } }
void text_renderer::prepare_glyphs(glyph_positions const& positions) { FT_Matrix matrix; FT_Vector pen; FT_Error error; glyphs_.clear(); glyphs_.reserve(positions.size()); for (auto const& glyph_pos : positions) { glyph_info const& glyph = glyph_pos.glyph; FT_Int32 load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING; FT_Face face = glyph.face->get_face(); if (glyph.face->is_color()) { load_flags |= FT_LOAD_COLOR ; if (face->num_fixed_sizes > 0) { int scaled_size = static_cast<int>(glyph.format->text_size * scale_factor_); int best_match = 0; int diff = std::abs(scaled_size - face->available_sizes[0].width); for (int i = 1; i < face->num_fixed_sizes; ++i) { int ndiff = std::abs(scaled_size - face->available_sizes[i].height); if (ndiff < diff) { best_match = i; diff = ndiff; } } error = FT_Select_Size(face, best_match); } } else { glyph.face->set_character_sizes(glyph.format->text_size * scale_factor_); } double size = glyph.format->text_size * scale_factor_; matrix.xx = static_cast<FT_Fixed>( glyph_pos.rot.cos * 0x10000L); matrix.xy = static_cast<FT_Fixed>(-glyph_pos.rot.sin * 0x10000L); matrix.yx = static_cast<FT_Fixed>( glyph_pos.rot.sin * 0x10000L); matrix.yy = static_cast<FT_Fixed>( glyph_pos.rot.cos * 0x10000L); pixel_position pos = glyph_pos.pos + glyph.offset.rotate(glyph_pos.rot); pen.x = static_cast<FT_Pos>(pos.x * 64); pen.y = static_cast<FT_Pos>(pos.y * 64); FT_Set_Transform(face, &matrix, &pen); error = FT_Load_Glyph(face, glyph.glyph_index, load_flags); if (error) continue; FT_Glyph image; error = FT_Get_Glyph(face->glyph, &image); if (error) continue; box2d<double> bbox(0, glyph_pos.glyph.ymin(), glyph_pos.glyph.advance(), glyph_pos.glyph.ymax()); glyphs_.emplace_back(image, *glyph.format, pos, glyph_pos.rot, size, bbox); } }