齐硕换热器:AGG 成果

来源:百度文库 编辑:九乡新闻网 时间:2024/04/26 00:09:21
AGG 成果2010-07-11 22:14

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

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

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

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