//---------------------------------------------------------------------------- // Graphics class - Version 0.1.2 - 01-04-2006 // Marlon Mircevski //---------------------------------------------------------------------------- //#include "stdafx.h" #pragma warning(disable : 4786) #pragma warning(disable : 4097) #include "agg_pixfmt_rgba.h" #include "agg_conv_curve.h" #include "agg_conv_stroke.h" #include "agg_conv_dash.h" #include "agg_span_gradient.h" #include "agg_span_interpolator_linear.h" #include "agg_conv_transform.h" #include "agg_span_image_filter_rgba.h" #include "agg_span_pattern_rgba.h" #include "agg_image_accessors.h" #include "agg_span_allocator.h" #include "agg_image_filters.h" typedef agg::span_interpolator_linear<> interpolator_type_linear; typedef agg::span_allocator span_alloc_type; #include #include "ap_Graphics.h" #include "ap_GraphicsPath.h" #include "ap_Pen.h" #include "ap_Brush.h" #include "ap_Font.h" //if this is defined, you cannot mix simple Gdi and Aggplus drawing calls //but code works faster #define def_AP_Update_Dc_at_End namespace Aggplus { Graphics::Graphics(DWORD dwWidth, DWORD dwHeight, int stride, LPVOID pMemBuffer) : m_dwConfigFlags(0) { Create(dwWidth, dwHeight, stride, pMemBuffer); } Graphics::Graphics(Image* image) : m_dwConfigFlags(0) { if(!image || image->GetLastStatus()!=Ok) { assert(FALSE); return; } Create(image->GetWidth(), image->GetHeight(), image->m_nStride, image->m_pImgData); assert(m_dwConfigFlags&def_flag_G_ExtBuffer); //Just check... } Graphics::Graphics(HDC hdc) : m_dwConfigFlags(0) { RECT clipBox; ::GetClipBox(hdc, &clipBox); int nW=clipBox.right-clipBox.left; int nH=clipBox.bottom-clipBox.top; assert(nW>0 && nH>0); Create(nW, nH, -4*nW, NULL); m_dwConfigFlags|=def_flag_G_FromHDC; m_fromhdc_HDC=hdc; m_fromhdc_X=clipBox.left; m_fromhdc_Y=clipBox.top; } Graphics *Graphics::FromHDC(HDC hdc) { return(new Graphics(hdc)); } void Graphics::Create(DWORD dwWidth, DWORD dwHeight, int stride, LPVOID pMemBuffer) { m_PageUnit=UnitDisplay; m_dwWidth=dwWidth; m_dwHeight=dwHeight; if(pMemBuffer) { m_dwConfigFlags|=def_flag_G_ExtBuffer; //External buffer, no delete on destructor } m_frame_buffer.create(m_dwWidth, m_dwHeight, false, stride, pMemBuffer); m_fromhdc_HDC=NULL; m_fromhdc_X=m_fromhdc_Y=0; m_rasterizer.get_rasterizer().gamma(agg::gamma_none()); } Graphics::~Graphics() { #ifdef def_AP_Update_Dc_at_End if(m_dwConfigFlags & def_flag_G_FromHDC) { BITMAPINFO hDib; memset(&hDib, 0, sizeof(BITMAPINFO)); hDib.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); hDib.bmiHeader.biWidth = m_dwWidth; hDib.bmiHeader.biHeight = m_dwHeight; hDib.bmiHeader.biPlanes = 1; hDib.bmiHeader.biBitCount = 32; hDib.bmiHeader.biCompression = BI_RGB; hDib.bmiHeader.biSizeImage = m_dwWidth * m_dwHeight * 4; #ifndef _X_NODCAlpha_ LPVOID pBits; HBITMAP hBitmap = CreateDIBSection(m_fromhdc_HDC, &hDib, DIB_RGB_COLORS, &pBits, NULL, 0); if(!hBitmap) assert(FALSE); else { memcpy(pBits, m_frame_buffer.get_internal_buf(), m_dwWidth * m_dwHeight * 4); HDC mdc=CreateCompatibleDC( m_fromhdc_HDC ); if(!mdc) assert(FALSE); else { HBITMAP hbmOld=(HBITMAP)::SelectObject(mdc, hBitmap); BLENDFUNCTION bln; bln.BlendOp=AC_SRC_OVER; bln.BlendFlags=0; bln.SourceConstantAlpha=255; bln.AlphaFormat=AC_SRC_ALPHA; AlphaBlend(m_fromhdc_HDC, m_fromhdc_X, m_fromhdc_Y, m_dwWidth, m_dwHeight, mdc, 0, 0, m_dwWidth, m_dwHeight, bln); //BitBlt(m_fromhdc_HDC, m_fromhdc_X, m_fromhdc_Y, m_dwWidth, m_dwHeight, mdc, 0, 0, SRCCOPY); ::SelectObject(mdc, hbmOld); //::GdiFlush(); DeleteDC(mdc); } ::DeleteObject(hBitmap); } #else SetDIBitsToDevice(m_fromhdc_HDC, m_fromhdc_X, m_fromhdc_Y, m_dwWidth, m_dwHeight, 0, 0, 0, m_dwHeight, m_frame_buffer.get_internal_buf(), &hDib, DIB_RGB_COLORS); #endif //_X_NODCAlpha_ } #endif //def_AP_Update_Dc_at_End } Graphics *Graphics::FromImage(Image *image) { return(new Graphics(image)); } void Graphics::zBuffer_Begin() { //Experimental! #ifndef def_AP_Update_Dc_at_End if(m_dwConfigFlags & def_flag_G_FromHDC) { m_frame_buffer.ren_base().clear(agg::rgba8(0,0,0,0)); } #endif //!def_AP_Update_Dc_at_End } void Graphics::zBuffer_End() { //Experimental! #ifndef def_AP_Update_Dc_at_End if(m_dwConfigFlags & def_flag_G_FromHDC) { BITMAPINFO hDib; memset(&hDib, 0, sizeof(BITMAPINFO)); hDib.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); hDib.bmiHeader.biWidth = m_dwWidth; hDib.bmiHeader.biHeight = m_dwHeight; hDib.bmiHeader.biPlanes = 1; hDib.bmiHeader.biBitCount = 32; hDib.bmiHeader.biCompression = BI_RGB; hDib.bmiHeader.biSizeImage = m_dwWidth * m_dwHeight * 4; #ifndef _X_NODCAlpha_ LPVOID pBits; HBITMAP hBitmap = CreateDIBSection(m_fromhdc_HDC, &hDib, DIB_RGB_COLORS, &pBits, NULL, 0); if(!hBitmap) assert(FALSE); else { memcpy(pBits, m_frame_buffer.get_internal_buf(), m_dwWidth * m_dwHeight * 4); HDC mdc=CreateCompatibleDC( m_fromhdc_HDC ); if(!mdc) assert(FALSE); else { HBITMAP hbmOld=(HBITMAP)::SelectObject(mdc, hBitmap); BLENDFUNCTION bln; bln.BlendOp=AC_SRC_OVER; bln.BlendFlags=0; bln.SourceConstantAlpha=255; bln.AlphaFormat=AC_SRC_ALPHA; AlphaBlend(m_fromhdc_HDC, m_fromhdc_X, m_fromhdc_Y, m_dwWidth, m_dwHeight, mdc, 0, 0, m_dwWidth, m_dwHeight, bln); //BitBlt(m_fromhdc_HDC, m_fromhdc_X, m_fromhdc_Y, m_dwWidth, m_dwHeight, mdc, 0, 0, SRCCOPY); ::SelectObject(mdc, hbmOld); //::GdiFlush(); DeleteDC(mdc); } ::DeleteObject(hBitmap); } #else SetDIBitsToDevice(m_fromhdc_HDC, m_fromhdc_X, m_fromhdc_Y, m_dwWidth, m_dwHeight, 0, 0, 0, m_dwHeight, m_frame_buffer.get_internal_buf(), &hDib, DIB_RGB_COLORS); #endif //_X_NODCAlpha_ } #endif //!def_AP_Update_Dc_at_End } Status Graphics::Clear(const Color &color) { if(m_ClipRect.IsEmptyArea()) { zBuffer_Begin();//for fromHDC m_frame_buffer.ren_base().clear(color.GetAggColor()); zBuffer_End(); //for fromHDC } else { BrushSolid sbrush(color); GraphicsPath Path; RectF dct(0,0,(float)m_dwWidth,(float)m_dwHeight); Path.AddRectangle(dct); FillPath(&sbrush, &Path); } return Ok; } Status Graphics::DrawPath(const Pen* pen, const GraphicsPath* path) //ZTODO: const GraphicsPath* path { //TRACE("DrawPath\n"); assert(pen); m_rasterizer.get_rasterizer().reset(); //butt_cap, square_cap, round_cap //pg.line_cap(agg::vcgen_stroke::round_cap); agg::line_join_e LineJoin; switch(pen->GetLineJoin()) { case LineJoinMiter : LineJoin=agg::miter_join; break; case LineJoinBevel : LineJoin=agg::bevel_join; break; default: case LineJoinRound : LineJoin=agg::round_join; break; case LineJoinMiterClipped: LineJoin=agg::miter_join_revert; break; } REAL fWidth=pen->GetWidth(); double dblMiterLimit=0.50; agg::path_storage path_copy(path->m_agg_ps); typedef agg::conv_curve conv_crv_type; conv_crv_type c_c_path(path_copy); if(pen->GetDashStyle()==DashStyleSolid) { typedef agg::conv_stroke Path_Conv_StrokeN; Path_Conv_StrokeN pgN(c_c_path); //typedef agg::conv_stroke Path_Conv_StrokeN; //Path_Conv_StrokeN pgN(path->m_agg_ps); pgN.line_join(LineJoin); pgN.miter_limit(dblMiterLimit); pgN.width(fWidth); typedef agg::conv_transform transStroke; transStroke trans(pgN, m_MatrixGfx.m_agg_mtx); m_rasterizer.get_rasterizer().add_path(trans); } else { typedef agg::conv_dash Path_Conv_Dash; Path_Conv_Dash poly2_dash(c_c_path); typedef agg::conv_stroke Path_Conv_StrokeD; Path_Conv_StrokeD pgD(poly2_dash); switch(pen->GetDashStyle()) { case DashStyleDash: poly2_dash.add_dash(3.00*fWidth, fWidth); break; case DashStyleDot: poly2_dash.add_dash(fWidth, fWidth); break; case DashStyleDashDot: poly2_dash.add_dash(3.00*fWidth, fWidth); poly2_dash.add_dash(fWidth, fWidth); break; case DashStyleDashDotDot: poly2_dash.add_dash(3.00*fWidth, fWidth); poly2_dash.add_dash(fWidth, fWidth); poly2_dash.add_dash(fWidth, fWidth); break; default: case DashStyleCustom:break; } pgD.line_join(LineJoin); pgD.miter_limit(dblMiterLimit); pgD.width(fWidth); agg::conv_transform trans(pgD, m_MatrixGfx.m_agg_mtx); m_rasterizer.get_rasterizer().add_path(trans); } DoFillPath(pen->GetBrush()); return Ok; } Status Graphics::FillPath(const Brush* brush, const GraphicsPath* path) { assert(brush); m_rasterizer.get_rasterizer().reset(); agg::path_storage p2(path->m_agg_ps); typedef agg::conv_transform trans_type; trans_type trans(p2, m_MatrixGfx.m_agg_mtx); typedef agg::conv_curve conv_crv_type; conv_crv_type c_c_path(trans); m_rasterizer.get_rasterizer().add_path(c_c_path); DoFillPath(brush); return Ok; } void Graphics::DoFillPathSolid(Color dwColor) { zBuffer_Begin();//for fromHDC //### typedef agg::renderer_scanline_aa_solid solid_renderer_type; solid_renderer_type ren_fine(m_frame_buffer.ren_base()); ren_fine.color(dwColor.GetAggColor()); agg::render_scanlines(m_rasterizer.get_rasterizer(), m_rasterizer.get_scanline(), ren_fine); //ZTODO: Region Clipping /* if(m_RegionClip.Dali_e_prazen()) { agg::render_scanlines(m_agg_RAS, SL, ren_fine); } else //DoClip { { //Test View Path rasterizer_type ras2; ras2.gamma(agg::gamma_none()); agg::path_storage CLpath(m_RegionClip.m_agg_ps); agg::trans_affine mtx; mtx.multiply(*m_MatrixGfx.m_pmtx); agg::conv_transform mxpath(CLpath, mtx); ras2.add_path(mxpath); //ras2.add_path(CLpath); agg::render_scanlines(ras2, sl, ren_fine); } //scanline_type sl; scanline_type sl1; scanline_type sl2; agg::scanline_storage_aa8 storage; agg::scanline_storage_aa8 storage1; agg::scanline_storage_aa8 storage2; agg::render_scanlines(m_agg_RAS, sl1, storage1); { //Path rasterizer_type ras2; ras2.gamma(agg::gamma_none()); agg::path_storage CLpath(m_RegionClip.m_agg_ps); agg::trans_affine mtx; mtx.multiply(m_RegionMatrix.m_agg_mtx);//;(*m_MatrixGfx.m_pmtx); agg::conv_transform mxpath(CLpath, mtx); ras2.add_path(mxpath); //ras2.add_path(CLpath); agg::render_scanlines(ras2, sl2, storage2); } agg::sbool_op_e op=agg::sbool_and; //if(m_xClip->m_boolMode==Region::boolModeExclude) { op=agg::sbool_a_minus_b; } agg::sbool_combine_shapes_aa(op, storage1, storage2, sl1, sl2, SL, storage); agg::render_scanlines(storage, SL, ren_fine); } */ zBuffer_End(); //for fromHDC } void Graphics::DoFillPathGradient(BrushLinearGradient *pBrush) { zBuffer_Begin();//for fromHDC //### int mins[2]; int maxs[2]; mins[0] = m_rasterizer.get_rasterizer().min_x(); mins[1] = m_rasterizer.get_rasterizer().min_y(); maxs[0] = m_rasterizer.get_rasterizer().max_x(); maxs[1] = m_rasterizer.get_rasterizer().max_y(); int WR = maxs[0]-mins[0]; int HR = maxs[1]-mins[1]; RectF Rct((float)mins[0], (float)mins[1], (float)WR, (float)HR); //pBrush->GetRectangle(&Rct); Matrix mGrdMtx; float brRot = pBrush->GetRotate(); if (WR>0 && brRot>0.0f) { int nAng=int(brRot)%360; if((nAng>=90 && nAng<=180) || (nAng>=270 && nAng<=360)) { mGrdMtx.Translate(WR, 0.00);//, MatrixOrderAppend); WR=-WR; } double dblAng=agg::deg2rad(brRot); double Dx=WR*cos(dblAng)+HR*sin(dblAng); float fScale=(float)(fabs(Dx/WR)); mGrdMtx.Rotate(brRot); mGrdMtx.Scale(fScale, fScale); } //mGrdMtx.Scale(0.2, 1.0); Matrix mImgMtx; mImgMtx.Translate(Rct.X, Rct.Y); mImgMtx.Multiply(&mGrdMtx); double dblStart=0.0; double dblEnd=Rct.Width; agg::trans_affine mtx_Work(mImgMtx.m_agg_mtx); mtx_Work.multiply(m_MatrixGfx.m_agg_mtx); mtx_Work.invert(); interpolator_type_linear span_interpolator(mtx_Work); // Span interpolator span_alloc_type span_allocator; // Span Allocator typedef agg::gradient_reflect_adaptor gr_adaptor; agg::gradient_radial gradient_x; gr_adaptor gr_x(gradient_x); gr_adaptor* gr_ptr = &gr_x; typedef agg::span_gradient gradient_span_gen; typedef agg::span_allocator gradient_span_alloc; gradient_span_alloc span_alloc; //agg::gradient_linear_color colors(pBrush->m_dwColorA.GetAggColor(), pBrush->m_dwColorB.GetAggColor()); gradient_span_gen span_gen(span_interpolator, *gr_ptr, *pBrush, dblStart, dblEnd); typedef agg::renderer_scanline_aa renderer_gradient_type; // The gradient renderer renderer_gradient_type ren_gradient(m_frame_buffer.ren_base(), span_alloc, span_gen); agg::render_scanlines(m_rasterizer.get_rasterizer(), m_rasterizer.get_scanline(), ren_gradient); zBuffer_End(); //for fromHDC } void Graphics::DoFillPathTextureClampSz(const Matrix &mImgMtx, const void *pImgBuff, DWORD dwImgWidth, DWORD dwImgHeight, int nImgStride) { assert((unsigned)abs(nImgStride)>=4*dwImgWidth); zBuffer_Begin();//for fromHDC span_alloc_type span_allocator; // Span Allocator typedef agg::pixfmt_rgba32 pixfmt; typedef agg::image_accessor_clip img_source_type; typedef agg::span_image_filter_rgba_bilinear span_gen_type; typedef agg::renderer_scanline_aa renderer_type; agg::trans_affine mtx_Work(mImgMtx.m_agg_mtx); mtx_Work.multiply(m_MatrixGfx.m_agg_mtx); mtx_Work.invert(); interpolator_type_linear interpolator(mtx_Work); { agg::rendering_buffer PatRendBuff((BYTE *)pImgBuff, dwImgWidth, dwImgHeight, nImgStride); pixfmt img_pixf(PatRendBuff); img_source_type img_src(img_pixf, agg::rgba(0, 0, 0, 0)); span_gen_type sg(img_src, interpolator); renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg); agg::render_scanlines(m_rasterizer.get_rasterizer(), m_rasterizer.get_scanline(), ri); } zBuffer_End(); //for fromHDC } void Graphics::DoFillPath(const Brush* Brush) { if(!Brush) { assert(FALSE); return; } if(Brush->m_bType==BrushTypeSolidColor) { Color clr;((BrushSolid *)Brush)->GetColor(&clr); DoFillPathSolid(clr); } else if(Brush->m_bType==BrushTypeHatchFill) { assert(FALSE); //ZTODO } else if(Brush->m_bType==BrushTypeTextureFill) { BrushTexture *ptxBrush=(BrushTexture *)Brush; LPVOID pImgBuff=ptxBrush->PatternFinalize(); if(pImgBuff) { DWORD dwImgWidth=ptxBrush->PatternGetWidth(); DWORD dwImgHeight=ptxBrush->PatternGetHeight(); if(pImgBuff && dwImgWidth && dwImgHeight) { if(ptxBrush->m_wrapMode==WrapModeClamp) { DoFillPathTextureClampSz(ptxBrush->m_mtx, pImgBuff, dwImgWidth, dwImgHeight, ptxBrush->PatternGetStride()); } else { agg::trans_affine mtx_Work(ptxBrush->m_mtx.m_agg_mtx); mtx_Work.multiply(m_MatrixGfx.m_agg_mtx); mtx_Work.invert(); span_alloc_type span_allocator; // Span Allocator interpolator_type_linear interpolator(mtx_Work); agg::rendering_buffer PatRendBuff((BYTE *)pImgBuff, dwImgWidth, dwImgHeight, dwImgWidth * 4); zBuffer_Begin();//for fromHDC if(ptxBrush->m_wrapMode==WrapModeTileFlipX) { typedef agg::pixfmt_rgba32 pixfmt; //image_accessor_wrap typedef agg::wrap_mode_reflect wrap_x_type; typedef agg::wrap_mode_repeat wrap_y_type; typedef agg::image_accessor_wrap img_source_type; typedef agg::span_image_filter_rgba_bilinear span_gen_type; typedef agg::renderer_scanline_aa renderer_type; pixfmt img_pixf(PatRendBuff); img_source_type img_src(img_pixf); span_gen_type sg(img_src, interpolator); renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg); agg::render_scanlines(m_rasterizer.get_rasterizer(), m_rasterizer.get_scanline(), ri); } else if(ptxBrush->m_wrapMode==WrapModeTileFlipY) { typedef agg::pixfmt_rgba32 pixfmt; //image_accessor_wrap typedef agg::wrap_mode_repeat wrap_x_type; typedef agg::wrap_mode_reflect wrap_y_type; typedef agg::image_accessor_wrap img_source_type; typedef agg::span_image_filter_rgba_bilinear span_gen_type; typedef agg::renderer_scanline_aa renderer_type; pixfmt img_pixf(PatRendBuff); img_source_type img_src(img_pixf); span_gen_type sg(img_src, interpolator); renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg); agg::render_scanlines(m_rasterizer.get_rasterizer(), m_rasterizer.get_scanline(), ri); } else if(ptxBrush->m_wrapMode==WrapModeTileFlipXY) { typedef agg::pixfmt_rgba32 pixfmt; //image_accessor_wrap typedef agg::wrap_mode_reflect wrap_x_type; typedef agg::wrap_mode_reflect wrap_y_type; typedef agg::image_accessor_wrap img_source_type; typedef agg::span_image_filter_rgba_bilinear span_gen_type; typedef agg::renderer_scanline_aa renderer_type; pixfmt img_pixf(PatRendBuff); img_source_type img_src(img_pixf); span_gen_type sg(img_src, interpolator); renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg); agg::render_scanlines(m_rasterizer.get_rasterizer(), m_rasterizer.get_scanline(), ri); } else //Repeat { typedef agg::pixfmt_rgba32 pixfmt; //image_accessor_wrap typedef agg::wrap_mode_repeat wrap_x_type; typedef agg::wrap_mode_repeat wrap_y_type; typedef agg::image_accessor_wrap img_source_type; typedef agg::span_image_filter_rgba_bilinear span_gen_type; typedef agg::renderer_scanline_aa renderer_type; pixfmt img_pixf(PatRendBuff); img_source_type img_src(img_pixf); span_gen_type sg(img_src, interpolator); renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg); agg::render_scanlines(m_rasterizer.get_rasterizer(), m_rasterizer.get_scanline(), ri); } zBuffer_End(); //for fromHDC } } } } else if(Brush->m_bType==BrushTypePathGradient) { assert(FALSE); //ZTODO } else if(Brush->m_bType==BrushTypeLinearGradient) { DoFillPathGradient((BrushLinearGradient *)Brush); } } void Graphics::ClipBoxSet(const RectF& rect) { m_ClipRect=rect; m_ClipMatrix=m_MatrixGfx; if(!m_ClipRect.IsEmptyArea()) { double x1=m_ClipRect.X; double y1=m_ClipRect.Y; double x2=x1+m_ClipRect.Width; double y2=y1+m_ClipRect.Height; m_ClipMatrix.m_agg_mtx.transform(&x1, &y1); m_ClipMatrix.m_agg_mtx.transform(&x2, &y2); m_rasterizer.get_rasterizer().clip_box(x1, y1, x2, y2); } else { m_rasterizer.get_rasterizer().reset_clipping(); } } Status Graphics::FillRectangle(const Brush* brush, REAL x, REAL y, REAL width, REAL height) { GraphicsPath Path; RectF rct(x, y, width, height); Path.AddRectangle(rct); return FillPath(brush, &Path); } void Graphics::DrawRectangle(const Pen* pen, float x, float y, float width, float height) { GraphicsPath Path; RectF rct(x, y, width, height); Path.AddRectangle(rct); DrawPath(pen, &Path); } Status Graphics::DrawBezier(const Pen* pen, REAL x1, REAL y1, REAL x2, REAL y2, REAL x3, REAL y3, REAL x4, REAL y4) { GraphicsPath Path; Path.AddBezier(x1, y1, x2, y2, x3, y3, x4, y4); return DrawPath(pen, &Path); } Status Graphics::DrawImage(Image* image, REAL x, REAL y, REAL width, REAL height) { if(!image || image->GetLastStatus()!=Ok) return UnknownImageFormat; if(width==0.00 || height==0.00) return InvalidParameter; m_rasterizer.get_rasterizer().reset(); agg::path_storage p2; p2.move_to(x, y);p2.line_to(x+width, y);p2.line_to(x+width, y+height);p2.line_to(x, y+height);p2.close_polygon(); agg::conv_transform trans(p2, m_MatrixGfx.m_agg_mtx); // Global Affine transformer m_rasterizer.get_rasterizer().add_path(trans); void *pImgBuff=image->m_pImgData; DWORD dwImgWidth=image->GetWidth(); DWORD dwImgHeight=image->GetHeight(); Matrix ImgMtx; ImgMtx.Translate(x, y); ImgMtx.Scale(width/float(dwImgWidth), height/float(dwImgHeight)); DoFillPathTextureClampSz(ImgMtx, pImgBuff, dwImgWidth, dwImgHeight, image->m_nStride); return(Ok); } Status Graphics::DrawSVGImage(SVGImage* image, REAL x, REAL y, REAL width, REAL height) { agg::svg::renderer_rgba renderer(get_rasterizer(), get_frame_buffer()); get_rasterizer().gamma(1.0); image->m_settings.gamma(1.0); image->m_attributes.window(x, y, 2*(x+width), 2*(y+height)); agg::svg::rendering_interpreter rin( image->m_pipeline, image->m_attributes, renderer, image->m_id2elem_map,image->m_gradient_lut_cache); //#ifdef EXPAND_PATHS // rin.expand(expand); //#endif rin.ignore_viewBox(true); image->m_storage.traverse(rin); assert(0 == image->m_attributes.num_sessions()); if (image->m_settings.gamma() != 1.0) { get_frame_buffer().pixfmt().apply_gamma_inv(image->m_settings.gamma_lut()); } get_rasterizer().reset_clipping(); return(Ok); } //Not Implemented OK, check image dpi! void Graphics::DrawImage(Image* image, float x, float y, float srcx, float srcy, float srcwidth, float srcheight, Unit srcUnit) { if(!image || image->GetLastStatus()!=Ok) return; if(srcwidth==0.00 || srcheight==0.00) return; m_rasterizer.get_rasterizer().reset(); agg::path_storage p2; p2.move_to(x, y);p2.line_to(x+srcwidth, y);p2.line_to(x+srcwidth, y+srcheight);p2.line_to(x, y+srcheight);p2.close_polygon(); agg::conv_transform trans(p2, m_MatrixGfx.m_agg_mtx); // Global Affine transformer //ras.reset(); m_rasterizer.get_rasterizer().add_path(trans); void *pImgBuff=image->m_pImgData; DWORD dwImgWidth=image->GetWidth(); DWORD dwImgHeight=image->GetHeight(); Matrix ImgMtx; ImgMtx.Translate(x, y); DoFillPathTextureClampSz(ImgMtx, pImgBuff, dwImgWidth, dwImgHeight, image->m_nStride); } Status Graphics::DrawLine(const Pen* pen, REAL x1, REAL y1, REAL x2, REAL y2) { GraphicsPath Path; Path.AddLine(x1, y1, x2, y2); return DrawPath(pen, &Path); } //Cliping /* void Graphics::tmpSetClip(const RectF& rect)//, CombineMode mode) { GraphicsPath Path; Path.MoveTo(rect.X, rect.Y); Path.LineTo(rect.X+rect.Width, rect.Y); Path.LineTo(rect.X+rect.Width, rect.Y+rect.Height); Path.LineTo(rect.X, rect.Y+rect.Height); Path.CloseFigure(); //SetClip(&Path, CombineModeReplace); tmpSetClip(&Path); } */ /* void Graphics::tmpSetClip(const GraphicsPath *Path)//, CombineMode mode) { m_RegionClip=Region(Path); m_RegionMatrix=m_MatrixGfx; */ /* switch(mode) { default: case CombineModeReplace: ResetClip(); m_RegionClip=Region(Path); break; case CombineModeIntersect: case CombineModeUnion: // 2 case CombineModeXor: // 3 case CombineModeComplement: // 5 (Exclude From) assert(FALSE); break; case CombineModeExclude: // 4 m_RegionClip.NapraviPrazen(); //### m_RegionClip=Region(Path); m_RegionClip.m_boolMode=Region::boolModeExclude; break; } TRACE("ZTODO: Graphics::SetClip GraphicsPath\n"); //assert(FALSE); */ /* } */ /* void Graphics::tmpSetClip(const Region *ClipRegion)//, CombineMode mode) { m_RegionClip=*ClipRegion; m_RegionMatrix=m_MatrixGfx; */ /* assert(mode==CombineModeReplace); if(ClipRegion->Dali_e_prazen()) { ResetClip(); } //prikrpa, necini else { GraphicsPath path; path.m_agg_ps=ClipRegion->m_agg_ps; SetClip(&path, mode); } TRACE("ZTODO: Graphics::SetClip:ClipRegion\n"); */ /* } */ /* void Graphics::tmpResetClip() { m_RegionClip.NapraviPrazen(); } void Graphics::tmpGetClip(Region *ClipRegion) { (*ClipRegion)=m_RegionClip; } */ Status Graphics::DrawString(const WCHAR *string, INT length, const Font *font, const RectF &layoutRect, const StringFormat *stringFormat, const Brush *brush) { GraphicsPath Path; Path.AddStringFont(string, length, font, layoutRect, stringFormat); return FillPath(brush, &Path); } /* //In Work Status Graphics::MeasureString_Exact(const WCHAR* string, INT length, const Font* font, const PointF &origin, RectF* bndBoxGP, RectF* bndBoxReal) const { assert(font); RectF fRectReal, fRectBox; font->z_MeasureLineRel(string, length, &fRectReal, &fRectBox); fRectBox.Offset(origin); fRectBox.Width+=(float)font->z_get_1_6_em(); //for :) 1/6em see http://support.microsoft.com/default.aspx?scid=kb;en-us;307208 fRectBox.Width+=(float)font->z_get_1_6_em(); //for :) 1/6em see http://support.microsoft.com/default.aspx?scid=kb;en-us;307208 *bndBoxGP=fRectBox; fRectReal.Offset(origin); *bndBoxReal=fRectReal; return Ok; } */ Status Graphics::MeasureString(const WCHAR *string, INT length, const Font *font, const RectF &layoutRect, const StringFormat *stringFormat, RectF *boundingBox, INT *codepointsFitted, INT *linesFilled) const { return aggplus_flat_add_string_byfont_getbounds(NULL, string, length, font, layoutRect, stringFormat, boundingBox, codepointsFitted, linesFilled); } }