Files
core/ASCImageStudio3/ASCGraphics/agg/ap_Graphics.cpp
Elen.Subbotina 70e623d70b восстановление
git-svn-id: svn://fileserver/activex/AVS/Sources/TeamlabOffice/trunk/ServerComponents@62634 954022d7-b5bf-4e40-9824-e11837661b57
2016-05-21 00:05:02 +03:00

863 lines
28 KiB
C++

//----------------------------------------------------------------------------
// 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<agg::rgba8> span_alloc_type;
#include <math.h>
#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<agg::path_storage> conv_crv_type;
conv_crv_type c_c_path(path_copy);
if(pen->GetDashStyle()==DashStyleSolid)
{
typedef agg::conv_stroke<conv_crv_type> Path_Conv_StrokeN;
Path_Conv_StrokeN pgN(c_c_path);
//typedef agg::conv_stroke<agg::path_storage> 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<Path_Conv_StrokeN> transStroke;
transStroke trans(pgN, m_MatrixGfx.m_agg_mtx);
m_rasterizer.get_rasterizer().add_path(trans);
}
else
{
typedef agg::conv_dash<conv_crv_type> Path_Conv_Dash;
Path_Conv_Dash poly2_dash(c_c_path);
typedef agg::conv_stroke<Path_Conv_Dash> 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<Path_Conv_StrokeD> 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<agg::path_storage> trans_type;
trans_type trans(p2, m_MatrixGfx.m_agg_mtx);
typedef agg::conv_curve<trans_type> 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<base_renderer_type> 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<agg::path_storage> 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<agg::path_storage> 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<agg::gradient_radial> gr_adaptor;
agg::gradient_radial gradient_x;
gr_adaptor gr_x(gradient_x);
gr_adaptor* gr_ptr = &gr_x;
typedef agg::span_gradient<agg::rgba8,
interpolator_type_linear,
gr_adaptor,
BrushLinearGradient > gradient_span_gen;
typedef agg::span_allocator<gradient_span_gen::color_type> gradient_span_alloc;
gradient_span_alloc span_alloc;
//agg::gradient_linear_color<agg::rgba8> 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<base_renderer_type, gradient_span_alloc, gradient_span_gen> 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<pixfmt> img_source_type;
typedef agg::span_image_filter_rgba_bilinear<img_source_type, interpolator_type_linear> span_gen_type;
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> 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<pixfmt, wrap_x_type, wrap_y_type> img_source_type;
typedef agg::span_image_filter_rgba_bilinear<img_source_type, interpolator_type_linear> span_gen_type;
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> 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<pixfmt, wrap_x_type, wrap_y_type> img_source_type;
typedef agg::span_image_filter_rgba_bilinear<img_source_type, interpolator_type_linear> span_gen_type;
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> 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<pixfmt, wrap_x_type, wrap_y_type> img_source_type;
typedef agg::span_image_filter_rgba_bilinear<img_source_type, interpolator_type_linear> span_gen_type;
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> 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<pixfmt, wrap_x_type, wrap_y_type> img_source_type;
typedef agg::span_image_filter_rgba_bilinear<img_source_type, interpolator_type_linear> span_gen_type;
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> 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<agg::path_storage> 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<agg::path_storage> 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);
}
}