分享

AGG 成果

 lhzstudio 2011-10-15
AGG 成果
2010-07-11 22:14

作为本文的结尾,这里放上一个用AGG生成不规则文字窗体的代码。它综合了我们之前学到的AGG字体引擎、坐标转换、颜色渐变等几大模 块。由于AGG的抗锯齿特性,使用生 成的窗体看上去边缘过渡非常自然,几乎看不到“毛边”。

先放上最终生成的窗体的效果:

C++编程网 C++编程网 C++编程网

貌似比网页左上角的logo还要好看那么一点点-_-

  1. #define _WIN32_WINNT 0x0501
  2. #include <windows.h>
  3. #include <agg_array.h>
  4. #include <agg_pixfmt_rgba.h>
  5. #include <agg_scanline_u.h>
  6. #include <agg_renderer_scanline.h>
  7. #include <../font_win32_tt/agg_font_win32_tt.h>
  8. #include <agg_font_cache_manager.h>
  9. #include <agg_span_solid.h>
  10. #include <agg_span_interpolator_linear.h>
  11. #include <agg_span_gradient.h>
  12. #include <agg_span_allocator.h>
  13. #include <agg_conv_transform.h>
  14. #include <agg_ellipse.h>
  15. #include <agg_trans_single_path.h>
  16. typedef agg::font_engine_win32_tt_int16 fe_type;
  17. typedef agg::font_cache_manager<fe_type> fcman_type;
  18. typedef agg::renderer_base<agg::pixfmt_bgra32> renb_type;
  19. // 使用指定的顶点源和线段生成器输出文字
  20. template<class VS, class SpanGenerator>
  21. void AggDrawText(renb_type &renb,
  22.                   fcman_type &font_manager,
  23.                   VS &vs, SpanGenerator &span_gen,
  24.                  const wchar_t *txt)
  25. {
  26.     using namespace agg;
  27.     
  28.      span_allocator<rgba8> span_alloc;
  29.      rasterizer_scanline_aa<> ras;
  30.      scanline_u8 sl;
  31.     
  32.     double x=0, y=0;
  33.     for(const wchar_t *p = txt; *p; p++)
  34.      {
  35.         const glyph_cache* gc = font_manager.glyph(*p);
  36.         if(gc)
  37.          {
  38.              font_manager.init_embedded_adaptors(gc, x, y);
  39.              ras.add_path(vs);
  40.              agg::render_scanlines_aa(ras, sl, renb, span_alloc, span_gen);
  41.              x += gc->advance_x;
  42.              y += gc->advance_y;
  43.          }
  44.      }
  45. }
  46. // 向renb的指定位置和半径输出http://www. ,有环绕效果
  47. void DrawUrl(HDC dc, renb_type &renb,
  48.              double ox, double oy, double rx, double ry)
  49. {
  50.     using namespace agg;
  51.     //字体引擎
  52.      fe_type font(dc);
  53.      fcman_type font_manager(font);
  54.      font.height(18.0);
  55.      font.flip_y(true);
  56.      font.hinting(true);
  57.     if(!font.create_font("Comic Sans MS",agg::glyph_ren_outline)) return;
  58.     //坐标转换管道
  59.     typedef conv_curve<
  60.          fcman_type::path_adaptor_type
  61.      > cc_pa_type;
  62.      cc_pa_type ccpath(font_manager.path_adaptor());
  63.     typedef conv_transform<cc_pa_type,
  64.          trans_single_path> ct_cc_pa_type;
  65.      trans_single_path trans_path;
  66.      ct_cc_pa_type ctpath(ccpath, trans_path);
  67.     
  68.      ellipse ell(0,0,rx,ry);
  69.      trans_affine ellmtx;
  70.      conv_transform<ellipse> ctell(ell, ellmtx);
  71.      ellmtx.rotate(agg::pi);
  72.      ellmtx.translate(ox,oy);
  73.      trans_path.add_path(ctell);
  74.     // 线段生成器
  75.      span_solid<rgba8> ss;
  76.      ss.color(rgba(1,0,0));
  77.      AggDrawText(renb, font_manager, ctpath, ss, L"http://www.");
  78. }
  79. // 向renb的指定位置输出“C++编程”几个字,有镜象效果
  80. void DrawName(HDC dc, renb_type &renb, double x, double y)
  81. {
  82.     using namespace agg;
  83.     // 字体引擎
  84.      fe_type font(dc);
  85.      fcman_type font_manager(font);
  86.      font.height(30.0);
  87.      font.flip_y(true);
  88.      font.hinting(true);
  89.     if(!font.create_font("黑体",agg::glyph_ren_outline)) return;
  90.     // 坐标转换管道
  91.     typedef conv_curve<
  92.          fcman_type::path_adaptor_type
  93.      > cc_pa_type;
  94.      cc_pa_type ccpath(font_manager.path_adaptor());
  95.     typedef conv_transform<cc_pa_type> ct_cc_pa_type;
  96.      trans_affine mtx;
  97.      ct_cc_pa_type ctpath( ccpath, mtx );
  98.      mtx.translate(50,50);
  99.     //线段生成器
  100.      span_solid<rgba8> ss;
  101.      ss.color(rgba(0,0,0));
  102.      AggDrawText(renb, font_manager, ctpath, ss, L"C++编程");
  103.     // 改变坐标转换矩阵(镜像)
  104.      mtx.reset();
  105.      mtx.flip_y();
  106.      mtx.translate(50,60);
  107.     // 渐变线段生成器
  108.     typedef span_interpolator_linear<> interpolator_type;
  109.      trans_affine img_mtx;
  110.      interpolator_type ip(img_mtx);
  111.     typedef gradient_y gradientF_type;
  112.      gradientF_type grF;
  113.     typedef gradient_linear_color<rgba8> colorF_type;
  114.      colorF_type colorF(rgba(0,0,0), rgba(0,0,0,0));
  115.     
  116.     typedef span_gradient<rgba8,
  117.          interpolator_type,
  118.          gradientF_type,
  119.          colorF_type> span_gen_type;
  120.      span_gen_type span_gen(ip,grF,colorF,30,80);
  121.     
  122.      AggDrawText(renb, font_manager, ctpath, span_gen, L"C++编程");
  123. }
  124. // 调用DrawUrl和DrawName向renb输出文字
  125. void DrawIt(HDC dc, renb_type &renb)
  126. {
  127.     // 以透明色填充
  128.      renb.clear(rgba(0,0,0,0));
  129.     // 输出文字
  130.      DrawUrl(dc, renb, 100, 50, 80, 40);
  131.      DrawName(dc, renb, 50, 50);
  132. }
  133. // 使用AGG处理图片后与hwnd关联
  134. void SetLayoutWin(HWND hwnd)
  135. {
  136.     // 起始位置和窗体大小
  137.      POINT ptWinPos = {500,200};
  138.      SIZE sizeWindow = {200, 100};
  139.     // 建立DIB
  140.      BITMAPINFO bmp_info;
  141.      ::ZeroMemory(&bmp_info, sizeof(bmp_info));
  142.      bmp_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  143.      bmp_info.bmiHeader.biWidth = sizeWindow.cx;
  144.      bmp_info.bmiHeader.biHeight = sizeWindow.cy;
  145.      bmp_info.bmiHeader.biPlanes = 1;
  146.      bmp_info.bmiHeader.biBitCount = 32;
  147.      bmp_info.bmiHeader.biCompression = BI_RGB;
  148.     
  149.     HDC hdcTemp = GetDC(0);
  150.     HDC mem_dc = ::CreateCompatibleDC(hdcTemp);
  151.      ReleaseDC(0, hdcTemp);
  152.     void* buf = NULL;
  153.     HBITMAP bmp = ::CreateDIBSection(
  154.          mem_dc,
  155.          &bmp_info,
  156.          DIB_RGB_COLORS,
  157.          &buf,
  158.          0, 0
  159.      );
  160.     
  161.     // 把bmp与mem_dc关联,这样AGG就可以和原生GDI一起工作了
  162.     HBITMAP temp = (HBITMAP)::SelectObject(mem_dc, bmp);
  163.      {
  164.         // AGG处理
  165.          agg::rendering_buffer rbuf(
  166.              (unsigned char*)buf,
  167.              sizeWindow.cx, sizeWindow.cy,
  168.              -sizeWindow.cx*4);
  169.          agg::pixfmt_bgra32 pixf(rbuf);
  170.          renb_type renb(pixf);
  171.          DrawIt(mem_dc,renb);
  172.      }
  173.     // 把画好的mem_dc与hwnd关联到一起
  174.      BLENDFUNCTION m_Blend={AC_SRC_OVER,0,255,AC_SRC_ALPHA};
  175.      POINT ptSrc = {0, 0};
  176.     BOOL bRet = UpdateLayeredWindow(hwnd, 0, &ptWinPos,
  177.                                      &sizeWindow, mem_dc, &ptSrc,
  178.                                      0, &m_Blend, ULW_ALPHA);
  179.     // 回收
  180.      ::DeleteObject(bmp);
  181.      ::DeleteDC(mem_dc);
  182. }
  183. // Windows消息处理
  184. LRESULT CALLBACK WndProc (HWND hwnd, UINT umsg, WPARAM wParam,
  185.                           LPARAM lParam)
  186. {
  187.   switch (umsg)
  188.    {
  189.     case WM_CLOSE:
  190.        DestroyWindow (hwnd);
  191.       return 0;
  192.     case WM_DESTROY:
  193.        PostQuitMessage (0);
  194.       return 0;
  195.     case WM_NCHITTEST:
  196.       return HTCAPTION;
  197.    }
  198.   return DefWindowProc (hwnd, umsg, wParam, lParam);
  199. }
  200. int APIENTRY WinMain(HINSTANCE hInstance,
  201.                      HINSTANCE hPrevInstance,
  202.                      LPTSTR     lpCmdLine,
  203.                      int        nCmdShow)
  204. {
  205.      WNDCLASS wc={
  206.          0,WndProc,
  207.          0,0,
  208.          hInstance,
  209.          NULL,LoadCursor(NULL, IDC_ARROW),
  210.          (HBRUSH)(COLOR_WINDOW+1),
  211.          0,"AGGWIN"
  212.      };
  213.      ::RegisterClass(&wc);
  214.     HWND hWnd = ::CreateWindowEx(WS_EX_LAYERED,"AGGWIN", NULL, WS_OVERLAPPEDWINDOW,
  215.        CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
  216.     if (!hWnd) return -1;
  217.      SetLayoutWin(hWnd);
  218.      ::ShowWindow(hWnd, nCmdShow);
  219.     // 主消息循环:
  220.      MSG msg;
  221.     while (GetMessage(&msg, NULL, 0, 0))
  222.      {
  223.          TranslateMessage(&msg);
  224.          DispatchMessage(&msg);
  225.      }
  226.     return (int) msg.wParam;
  227. }

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多