Agg растеризация шрифтов
От: linux_fun  
Дата: 10.03.09 05:54
Оценка:
Здравствуйте использую 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); , но не помогает.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.