void grid_text_renderer<T>::render(glyph_positions const& pos, value_integer feature_id) { glyphs_.clear(); prepare_glyphs(pos); FT_Error error; FT_Vector start; unsigned height = pixmap_.height(); pixel_position const& base_point = pos.get_base_point(); start.x = static_cast<FT_Pos>(base_point.x * (1 << 6)); start.y = static_cast<FT_Pos>((height - base_point.y) * (1 << 6)); // now render transformed glyphs double halo_radius = 0.0; for (auto & glyph : glyphs_) { if (glyph.properties) { halo_radius = glyph.properties->halo_radius * scale_factor_; } FT_Glyph_Transform(glyph.image, 0, &start); error = FT_Glyph_To_Bitmap(&glyph.image, FT_RENDER_MODE_NORMAL, 0, 1); if (!error) { FT_BitmapGlyph bit = reinterpret_cast<FT_BitmapGlyph>(glyph.image); render_halo_id(&bit->bitmap, feature_id, bit->left, height - bit->top, static_cast<int>(halo_radius)); } } }
void grid_text_renderer<T>::render(glyph_positions const& pos, value_integer feature_id) { prepare_glyphs(pos); FT_Error error; FT_Vector start; unsigned height = pixmap_.height(); pixel_position const& base_point = pos.get_base_point(); start.x = static_cast<FT_Pos>(base_point.x * (1 << 6)); start.y = static_cast<FT_Pos>((height - base_point.y) * (1 << 6)); start.x += transform_.tx * 64; start.y += transform_.ty * 64; // now render transformed glyphs double halo_radius = 0.0; FT_Matrix halo_matrix; halo_matrix.xx = halo_transform_.sx * 0x10000L; halo_matrix.xy = halo_transform_.shx * 0x10000L; halo_matrix.yy = halo_transform_.sy * 0x10000L; halo_matrix.yx = halo_transform_.shy * 0x10000L; for (auto & glyph : glyphs_) { halo_radius = glyph.properties.halo_radius * scale_factor_; FT_Glyph_Transform(glyph.image, &halo_matrix, &start); error = FT_Glyph_To_Bitmap(&glyph.image, FT_RENDER_MODE_NORMAL, 0, 1); if (!error) { FT_BitmapGlyph bit = reinterpret_cast<FT_BitmapGlyph>(glyph.image); if (bit->bitmap.pixel_mode == FT_PIXEL_MODE_BGRA) { pixel_position render_pos(base_point); image_rgba8 glyph_image(render_glyph_image(glyph, bit->bitmap, transform_, render_pos)); const constexpr std::size_t pixel_size = sizeof(image_rgba8::pixel_type); render_halo_id<pixel_size>(glyph_image.bytes(), glyph_image.width(), glyph_image.height(), feature_id, render_pos.x, render_pos.y, static_cast<int>(halo_radius)); } else { render_halo_id<1>(bit->bitmap.buffer, bit->bitmap.width, bit->bitmap.rows, feature_id, bit->left, height - bit->top, static_cast<int>(halo_radius)); } } FT_Done_Glyph(glyph.image); } }
scoped_glyph_positions_offset(glyph_positions & glyphs, pixel_position const& offset) : glyphs_(glyphs) , base_point_(glyphs.get_base_point()) , marker_pos_(glyphs.marker_pos()) { // move the glyphs to the correct offset glyphs_.set_base_point(base_point_ + offset); // update the position of any marker if (auto const& marker_info = glyphs_.get_marker()) { glyphs_.set_marker(marker_info, marker_pos_ + offset); } }
void grid_text_renderer<T>::render(glyph_positions const& pos, value_integer feature_id) { prepare_glyphs(pos); FT_Error error; FT_Vector start; unsigned height = pixmap_.height(); pixel_position const& base_point = pos.get_base_point(); start.x = static_cast<FT_Pos>(base_point.x * (1 << 6)); start.y = static_cast<FT_Pos>((height - base_point.y) * (1 << 6)); start.x += transform_.tx * 64; start.y += transform_.ty * 64; // now render transformed glyphs double halo_radius = 0.0; FT_Matrix halo_matrix; halo_matrix.xx = halo_transform_.sx * 0x10000L; halo_matrix.xy = halo_transform_.shx * 0x10000L; halo_matrix.yy = halo_transform_.sy * 0x10000L; halo_matrix.yx = halo_transform_.shy * 0x10000L; for (auto & glyph : glyphs_) { halo_radius = glyph.properties.halo_radius * scale_factor_; FT_Glyph_Transform(glyph.image, &halo_matrix, &start); error = FT_Glyph_To_Bitmap(&glyph.image, FT_RENDER_MODE_NORMAL, 0, 1); if (!error) { FT_BitmapGlyph bit = reinterpret_cast<FT_BitmapGlyph>(glyph.image); render_halo_id(&bit->bitmap, feature_id, bit->left, height - bit->top, static_cast<int>(halo_radius)); } FT_Done_Glyph(glyph.image); } }
void agg_text_renderer<T>::render(glyph_positions const& pos) { glyphs_.clear(); prepare_glyphs(pos); FT_Error error; FT_Vector start; FT_Vector start_halo; int height = pixmap_.height(); pixel_position const& base_point = pos.get_base_point(); start.x = static_cast<FT_Pos>(base_point.x * (1 << 6)); start.y = static_cast<FT_Pos>((height - base_point.y) * (1 << 6)); start_halo = start; start.x += transform_.tx * 64; start.y += transform_.ty * 64; start_halo.x += halo_transform_.tx * 64; start_halo.y += halo_transform_.ty * 64; FT_Matrix halo_matrix; halo_matrix.xx = halo_transform_.sx * 0x10000L; halo_matrix.xy = halo_transform_.shx * 0x10000L; halo_matrix.yy = halo_transform_.sy * 0x10000L; halo_matrix.yx = halo_transform_.shy * 0x10000L; FT_Matrix matrix; matrix.xx = transform_.sx * 0x10000L; matrix.xy = transform_.shx * 0x10000L; matrix.yy = transform_.sy * 0x10000L; matrix.yx = transform_.shy * 0x10000L; // default formatting double halo_radius = 0; color black(0,0,0); unsigned fill = black.rgba(); unsigned halo_fill = black.rgba(); double text_opacity = 1.0; double halo_opacity = 1.0; for (auto const& glyph : glyphs_) { halo_fill = glyph.properties.halo_fill.rgba(); halo_opacity = glyph.properties.halo_opacity; halo_radius = glyph.properties.halo_radius * scale_factor_; // make sure we've got reasonable values. if (halo_radius <= 0.0 || halo_radius > 1024.0) continue; FT_Glyph g; error = FT_Glyph_Copy(glyph.image, &g); if (!error) { FT_Glyph_Transform(g, &halo_matrix, &start_halo); if (rasterizer_ == HALO_RASTERIZER_FULL) { stroker_->init(halo_radius); FT_Glyph_Stroke(&g, stroker_->get(), 1); error = FT_Glyph_To_Bitmap(&g, FT_RENDER_MODE_NORMAL, 0, 1); if (!error) { FT_BitmapGlyph bit = reinterpret_cast<FT_BitmapGlyph>(g); composite_bitmap(pixmap_, &bit->bitmap, halo_fill, bit->left, height - bit->top, halo_opacity, halo_comp_op_); } } else { error = FT_Glyph_To_Bitmap(&g, FT_RENDER_MODE_NORMAL, 0, 1); if (!error) { FT_BitmapGlyph bit = reinterpret_cast<FT_BitmapGlyph>(g); render_halo(&bit->bitmap, halo_fill, bit->left, height - bit->top, halo_radius, halo_opacity, halo_comp_op_); } } } FT_Done_Glyph(g); } // render actual text for (auto & glyph : glyphs_) { fill = glyph.properties.fill.rgba(); text_opacity = glyph.properties.text_opacity; FT_Glyph_Transform(glyph.image, &matrix, &start); error = FT_Glyph_To_Bitmap(&glyph.image ,FT_RENDER_MODE_NORMAL, 0, 1); if (!error) { FT_BitmapGlyph bit = reinterpret_cast<FT_BitmapGlyph>(glyph.image); composite_bitmap(pixmap_, &bit->bitmap, fill, bit->left, height - bit->top, text_opacity, comp_op_); } FT_Done_Glyph(glyph.image); } }
void cairo_context::add_text(glyph_positions const& pos, cairo_face_manager & manager, composite_mode_e comp_op, composite_mode_e halo_comp_op, double scale_factor) { pixel_position const& base_point = pos.get_base_point(); const double sx = base_point.x; const double sy = base_point.y; for (auto const& glyph_pos : pos) { glyph_info const& glyph = glyph_pos.glyph; glyph.face->set_character_sizes(glyph.format->text_size * scale_factor); } //render halo double halo_radius = 0; set_operator(halo_comp_op); for (auto const& glyph_pos : pos) { glyph_info const& glyph = glyph_pos.glyph; halo_radius = glyph.format->halo_radius * scale_factor; // make sure we've got reasonable values. if (halo_radius <= 0.0 || halo_radius > 1024.0) continue; double text_size = glyph.format->text_size * scale_factor; cairo_matrix_t matrix; matrix.xx = text_size * glyph_pos.rot.cos; matrix.xy = text_size * glyph_pos.rot.sin; matrix.yx = text_size * -glyph_pos.rot.sin; matrix.yy = text_size * glyph_pos.rot.cos; matrix.x0 = 0; matrix.y0 = 0; set_font_matrix(matrix); set_font_face(manager, glyph.face); pixel_position new_pos = glyph_pos.pos + glyph.offset.rotate(glyph_pos.rot); glyph_path(glyph.glyph_index, pixel_position(sx + new_pos.x, sy - new_pos.y)); set_line_width(2.0 * halo_radius); set_line_join(ROUND_JOIN); set_color(glyph.format->halo_fill, glyph.format->halo_opacity); stroke(); } set_operator(comp_op); for (auto const& glyph_pos : pos) { glyph_info const& glyph = glyph_pos.glyph; double text_size = glyph.format->text_size * scale_factor; cairo_matrix_t matrix; matrix.xx = text_size * glyph_pos.rot.cos; matrix.xy = text_size * glyph_pos.rot.sin; matrix.yx = text_size * -glyph_pos.rot.sin; matrix.yy = text_size * glyph_pos.rot.cos; matrix.x0 = 0; matrix.y0 = 0; set_font_matrix(matrix); set_font_face(manager, glyph.face); pixel_position new_pos = glyph_pos.pos + glyph.offset.rotate(glyph_pos.rot); set_color(glyph.format->fill, glyph.format->text_opacity); show_glyph(glyph.glyph_index, pixel_position(sx + new_pos.x, sy - new_pos.y)); } }
void agg_text_renderer<T>::render(glyph_positions const& pos) { glyphs_.clear(); prepare_glyphs(pos); FT_Error error; FT_Vector start; int height = pixmap_.height(); pixel_position const& base_point = pos.get_base_point(); start.x = static_cast<FT_Pos>(base_point.x * (1 << 6)); start.y = static_cast<FT_Pos>((height - base_point.y) * (1 << 6)); //render halo double halo_radius = 0; char_properties_ptr format; for (auto const& glyph : glyphs_) { if (glyph.properties) { format = glyph.properties; // Settings have changed. halo_radius = glyph.properties->halo_radius * scale_factor_; } // make sure we've got reasonable values. if (halo_radius <= 0.0 || halo_radius > 1024.0) continue; FT_Glyph g; error = FT_Glyph_Copy(glyph.image, &g); if (!error) { FT_Glyph_Transform(g,0,&start); if (rasterizer_ == HALO_RASTERIZER_FULL) { stroker_->init(halo_radius); FT_Glyph_Stroke(&g, stroker_->get(), 1); error = FT_Glyph_To_Bitmap(&g, FT_RENDER_MODE_NORMAL, 0, 1); if (!error) { FT_BitmapGlyph bit = reinterpret_cast<FT_BitmapGlyph>(g); composite_bitmap(pixmap_, &bit->bitmap, format->halo_fill.rgba(), bit->left, height - bit->top, format->text_opacity, comp_op_); } } else { error = FT_Glyph_To_Bitmap(&g, FT_RENDER_MODE_NORMAL, 0, 1); if (!error) { FT_BitmapGlyph bit = reinterpret_cast<FT_BitmapGlyph>(g); render_halo(&bit->bitmap, format->halo_fill.rgba(), bit->left, height - bit->top, halo_radius, format->text_opacity, comp_op_); } } } FT_Done_Glyph(g); } // render actual text for (auto & glyph : glyphs_) { if (glyph.properties) { format = glyph.properties; } FT_Glyph_Transform(glyph.image, 0, &start); error = FT_Glyph_To_Bitmap(&glyph.image ,FT_RENDER_MODE_NORMAL,0,1); if (!error) { FT_BitmapGlyph bit = reinterpret_cast<FT_BitmapGlyph>(glyph.image); composite_bitmap(pixmap_, &bit->bitmap, format->fill.rgba(), bit->left, height - bit->top, format->text_opacity, comp_op_); } } }
void agg_text_renderer<T>::render(glyph_positions const& pos) { prepare_glyphs(pos); FT_Error error; FT_Vector start; FT_Vector start_halo; int height = pixmap_.height(); pixel_position const& base_point = pos.get_base_point(); start.x = static_cast<FT_Pos>(base_point.x * (1 << 6)); start.y = static_cast<FT_Pos>((height - base_point.y) * (1 << 6)); start_halo = start; start.x += transform_.tx * 64; start.y += transform_.ty * 64; start_halo.x += halo_transform_.tx * 64; start_halo.y += halo_transform_.ty * 64; FT_Matrix halo_matrix; halo_matrix.xx = halo_transform_.sx * 0x10000L; halo_matrix.xy = halo_transform_.shx * 0x10000L; halo_matrix.yy = halo_transform_.sy * 0x10000L; halo_matrix.yx = halo_transform_.shy * 0x10000L; FT_Matrix matrix; matrix.xx = transform_.sx * 0x10000L; matrix.xy = transform_.shx * 0x10000L; matrix.yy = transform_.sy * 0x10000L; matrix.yx = transform_.shy * 0x10000L; // default formatting double halo_radius = 0; color black(0,0,0); unsigned fill = black.rgba(); unsigned halo_fill = black.rgba(); double text_opacity = 1.0; double halo_opacity = 1.0; for (auto const& glyph : glyphs_) { halo_fill = glyph.properties.halo_fill.rgba(); halo_opacity = glyph.properties.halo_opacity; halo_radius = glyph.properties.halo_radius * scale_factor_; // make sure we've got reasonable values. if (halo_radius <= 0.0 || halo_radius > 1024.0) continue; FT_Glyph g; error = FT_Glyph_Copy(glyph.image, &g); if (!error) { FT_Glyph_Transform(g, &halo_matrix, &start_halo); if (rasterizer_ == HALO_RASTERIZER_FULL) { stroker_->init(halo_radius); FT_Glyph_Stroke(&g, stroker_->get(), 1); error = FT_Glyph_To_Bitmap(&g, FT_RENDER_MODE_NORMAL, 0, 1); if (!error) { FT_BitmapGlyph bit = reinterpret_cast<FT_BitmapGlyph>(g); if (bit->bitmap.pixel_mode != FT_PIXEL_MODE_BGRA) { composite_bitmap(pixmap_, &bit->bitmap, halo_fill, bit->left, height - bit->top, halo_opacity, halo_comp_op_); } } } else { error = FT_Glyph_To_Bitmap(&g, FT_RENDER_MODE_NORMAL, 0, 1); if (error) { continue; } FT_BitmapGlyph bit = reinterpret_cast<FT_BitmapGlyph>(g); if (bit->bitmap.pixel_mode == FT_PIXEL_MODE_BGRA) { pixel_position render_pos(base_point); image_rgba8 glyph_image(render_glyph_image(glyph, bit->bitmap, transform_, render_pos)); const constexpr std::size_t pixel_size = sizeof(image_rgba8::pixel_type); render_halo<pixel_size>(glyph_image.bytes(), glyph_image.width(), glyph_image.height(), halo_fill, render_pos.x, render_pos.y, halo_radius, halo_opacity, halo_comp_op_); } else { render_halo<1>(bit->bitmap.buffer, bit->bitmap.width, bit->bitmap.rows, halo_fill, bit->left, height - bit->top, halo_radius, halo_opacity, halo_comp_op_); } } } FT_Done_Glyph(g); } // render actual text for (auto & glyph : glyphs_) { fill = glyph.properties.fill.rgba(); text_opacity = glyph.properties.text_opacity; FT_Glyph_Transform(glyph.image, &matrix, &start); error = 0; if ( glyph.image->format != FT_GLYPH_FORMAT_BITMAP ) { error = FT_Glyph_To_Bitmap(&glyph.image ,FT_RENDER_MODE_NORMAL, 0, 1); } if (error == 0) { FT_BitmapGlyph bit = reinterpret_cast<FT_BitmapGlyph>(glyph.image); int pixel_mode = bit->bitmap.pixel_mode; if (pixel_mode == FT_PIXEL_MODE_BGRA) { int x = base_point.x + glyph.pos.x; int y = base_point.y - glyph.pos.y; agg::trans_affine transform( glyph_transform(transform_, bit->bitmap.rows, x, y, -glyph.rot.angle(), glyph.bbox)); composite_color_glyph(pixmap_, bit->bitmap, transform, text_opacity, comp_op_); } else { composite_bitmap(pixmap_, &bit->bitmap, fill, bit->left, height - bit->top, text_opacity, comp_op_); } } FT_Done_Glyph(glyph.image); } }