Здравствуйте использую agg для растеризации шрифта, вот мой код:
create_symbol(LOGFONT & lFont , int glyph_code)
{
int format = GGO_NATIVE ;
HDC dc = GetDC(NULL);
HFONT hFont = ::CreateFontIndirect( &lFont );
HGDIOBJ old_font = SelectObject(dc, hFont);
std::vector<char> buf;
GLYPHMETRICS gm;
TEXTMETRIC tm;
wchar_t szText[2];
szText[0] = (wchar_t)glyph_code;
szText[1] = 0;
::GetTextMetrics(dc , &tm);
base_tmDescent = tm.tmDescent;
base_tmAscent = tm.tmAscent;
base_tmInternalLeading = tm.tmInternalLeading;
base_tmExternalLeading = tm.tmExternalLeading;
base_size = abs(lFont.lfHeight);
int total_size = GetGlyphOutline(dc, glyph_code, format, &gm, 0, NULL, &m_matrix);
if ( total_size == GDI_ERROR || !total_size)
{
::SelectObject(dc, old_font);
::DeleteObject(hFont);
::ReleaseDC(NULL, dc);
return;
}
buf.resize(total_size);
total_size = GetGlyphOutline(dc, glyph_code, format, &gm, buf.size(), (void*)&buf.front(),
&m_matrix);
if ( total_size == GDI_ERROR || !total_size)
{
::SelectObject(dc, old_font);
::DeleteObject(hFont);
::ReleaseDC(NULL, dc);
return;
}
m_advance_x = gm.gmCellIncX;
m_advance_y = -gm.gmCellIncY;
m_affine.transform(&m_advance_x, &m_advance_y);
m_path32.remove_all();
if(decompose_win32_glyph_outline(&buf.front() ,
total_size,
m_flip_y,
m_affine,
m_path32))
{
agg::rect_d bnd = m_path32.bounding_rect();
m_data_size = m_path32.byte_size();
m_data_type = agg::glyph_data_outline;
m_bounds.x1 = int(floor(bnd.x1));
m_bounds.y1 = int(floor(bnd.y1));
m_bounds.x2 = int(ceil(bnd.x2));
m_bounds.y2 = int(ceil(bnd.y2));
m_base_width = m_bounds.x2 - m_bounds.x1;
m_base_height = m_bounds.y2 - m_bounds.y1;
}
int size = m_path32.byte_size();
path_buf.resize(size);
m_path32.serialize(&path_buf.front());
::SelectObject(dc, old_font);
::DeleteObject(hFont);
::ReleaseDC(NULL, dc);
потом рисую:
agg::rendering_buffer rbuf;
double Ks = (double)((double)size / (double)base_size); // size - новый размер символа, меньший чем у символа с которого брали геометрию
double bmp_widht = m_base_width * Ks + 1;
double bmp_height = m_base_height * Ks + 1;
std::vector<BYTE> bmp_buf;
double tmDescent = base_tmDescent * Ks;
double tmAscent = base_tmAscent * Ks;
double tmInternalLeading = base_tmInternalLeading * Ks;
double tmExternalLeading = base_tmExternalLeading * Ks;
int img_size = GetLineWidth_1((bmp_widht + Dx) * 32) * (bmp_height + Dy);
bmp_buf.resize(img_size);
int stride = (((int)(bmp_widht + Dx) * 4 + 3) >> 2) << 2;
rbuf.attach(&bmp_buf.front() , bmp_widht + Dx , bmp_height + Dy , stride );
agg::pixfmt_bgra32 pixf(rbuf);
agg::renderer_base<agg::pixfmt_bgra32> renb(pixf);
agg::scanline_p8 sl;
renb.clear(agg::rgba8(0, 0, 0 , 0));
agg::renderer_scanline_aa_solid<agg::renderer_base<agg::pixfmt_bgra32> > ren(renb);
agg::trans_affine mtx;
mtx *= agg::trans_affine_scaling(Ks);//уменьшаем в Ks раз
mtx *= agg::trans_affine_translation(0, 0);//переносим центр координт
agg::serialized_integer_path_adaptor<agg::int32, 6> path_adaptor;
path_adaptor.init(&path_buf.front() , path_buf.size() , 0, 0, 1.0);
agg::conv_transform< agg::serialized_integer_path_adaptor<agg::int32, 6> > trans(path_adaptor, mtx);
agg::conv_curve< agg::conv_transform< agg::serialized_integer_path_adaptor<agg::int32, 6> > > stroke(trans);
agg::rasterizer_scanline_aa<agg::rasterizer_sl_clip_dbl> ras;
ren.color(agg::rgba8(0, 0, 0, 255));
ras.add_path(stroke);
ren.color(agg::rgba(0.5,0,0, 1));
agg::render_scanlines(ras, sl, ren);
Все хорошо растеризуеться и масштабируется, пока шрифт в шрифте lfOrientation и lfEscapement
если задать какое то значение, то символ уже не входить в битмап, хотя если поменять центр координат mtx *= agg::trans_affine_translation(0, 0); то можно сделать так что бы он входил при любом угле, побывал использовать mtx *= agg::trans_affine_rotation(m_angle); , но не помогает.