/** get the complex path made from the internal complex region 
@remarks
	only for D2D impl because we can only clip with geometry paths
	& not directly with GDI region

	return NULL if region is a simple region (ie equal to region bounds)
*/
VGraphicPath *VRegion::GetComplexPath() const
{
	HRGN hrgn = (RgnRef)(*this);

	Gdiplus::Region region( hrgn);
	Gdiplus::Matrix matIdentity;
	UINT numRect = region.GetRegionScansCount(&matIdentity);
	if (numRect > 1)
	{
		VGraphicPath *path = new VGraphicPath();
		if (!path)
			return NULL;

		Gdiplus::Rect rects[8];
		Gdiplus::Rect *pRect = rects;
		if (numRect > 8)
			pRect = new Gdiplus::Rect[numRect];
		Gdiplus::Status status = region.GetRegionScans(&matIdentity, pRect, (INT *)&numRect);  
		if (status == Gdiplus::Ok)
		{
			path->Begin();
			Gdiplus::Rect *curRect = pRect;
			for (int i = 0; i < numRect; i++, curRect++)
			{
				if (i == 0)
					path->AddRect( VRect( curRect->GetLeft(), curRect->GetTop(), curRect->GetRight()-curRect->GetLeft(), curRect->GetBottom()-curRect->GetTop()));
				else
				{
					VGraphicPath pathRect;
					pathRect.Begin();
					pathRect.AddRect( VRect( curRect->GetLeft(), curRect->GetTop(), curRect->GetRight()-curRect->GetLeft(), curRect->GetBottom()-curRect->GetTop()));
					pathRect.End();

					path->Union( pathRect);
				}
			}
			path->End();
		}
		else
		{
			delete path;
			path = NULL;
		}
		if (numRect > 8)
			delete [] pRect;
		return path;
	}
	else
	   return NULL;
}
示例#2
0
bool TextOutlineStrategy::MeasureString(
	Gdiplus::Graphics* pGraphics, 
	Gdiplus::FontFamily* pFontFamily,
	Gdiplus::FontStyle fontStyle,
	int nfontSize,
	const wchar_t*pszText, 
	Gdiplus::Rect rtDraw,
	Gdiplus::StringFormat* pStrFormat,
	float* pfDestWidth,
	float* pfDestHeight )
{
	using namespace Gdiplus;
	GraphicsPath path;
	Status status = path.AddString(pszText,wcslen(pszText),pFontFamily,fontStyle,nfontSize,rtDraw,pStrFormat);
	if(status!=Ok)
		return false;

	*pfDestWidth= rtDraw.GetLeft();
	*pfDestHeight= rtDraw.GetTop();
	bool b = GDIPath::MeasureGraphicsPath(pGraphics, &path, pfDestWidth, pfDestHeight);

	if(false==b)
		return false;

	float pixelThick = 0.0f;
	b = GDIPath::ConvertToPixels(pGraphics,m_nThickness,0.0f,&pixelThick,NULL);

	if(false==b)
		return false;

	*pfDestWidth += pixelThick;
	*pfDestHeight += pixelThick;

	return true;
}
bool TextNoOutlineStrategy::MeasureString(
	Gdiplus::Graphics* pGraphics, 
	Gdiplus::FontFamily* pFontFamily,
	Gdiplus::FontStyle fontStyle,
	int nfontSize,
	const wchar_t*pszText, 
	Gdiplus::Rect rtDraw,
	Gdiplus::StringFormat* pStrFormat,
	float* pfPixelsStartX,
	float* pfPixelsStartY,
	float* pfDestWidth,
	float* pfDestHeight )
{
	using namespace Gdiplus;
	GraphicsPath path;
	Status status = path.AddString(pszText,wcslen(pszText),pFontFamily,fontStyle,nfontSize,rtDraw,pStrFormat);
	if(status!=Ok)
		return false;

	*pfDestWidth= rtDraw.GetLeft();
	*pfDestHeight= rtDraw.GetTop();
	bool b = GDIPath::MeasureGraphicsPath(pGraphics, &path, pfPixelsStartX, pfPixelsStartY, pfDestWidth, pfDestHeight);

	return b;
}
void VPictureData_GDIPlus_Vector::_InitSize()const
{
	if(fMetafile)
	{
		Gdiplus::Rect rect;
		Gdiplus::MetafileHeader gh;
		fMetafile->GetMetafileHeader(&gh);
		
		//sLONG width  = (short) ( ( (long) gh.EmfHeader.rclFrame.right * 96L ) / 2540L );
		//sLONG height = (short) ( ( (long) gh.EmfHeader.rclFrame.bottom * 96L ) / 2540L );
		
		/*re1.Width= gh.EmfHeader.rclFrame.right * gh.EmfHeader.szlDevice.cx / (gh.EmfHeader.szlMillimeters.cx*100);
		re1.Height= gh.EmfHeader.rclFrame.bottom * gh.EmfHeader.szlDevice.cy / (gh.EmfHeader.szlMillimeters.cy*100);
		re1.Width=re1.Width * (96.0/gh.GetDpiX());
		re1.Height=re1.Height * (96.0/gh.GetDpiY());*/
		
		gh.GetBounds(&rect);
		fBounds.SetCoords(rect.GetLeft(),rect.GetTop(),rect.GetRight()-rect.GetLeft(),rect.GetBottom()-rect.GetTop());
	}
}
示例#5
0
void PrintRichEdit(HWND hwnd, Gdiplus::Graphics* graphics, Gdiplus::Bitmap* background, Gdiplus::Rect layoutArea) {
	using namespace Gdiplus;
	//Calculate the area to render.
	HDC hdc1 = ::GetDC(hwnd);

	double anInchX = 1440 / GetDeviceCaps(hdc1, LOGPIXELSX);
	double anInchY = 1440 / GetDeviceCaps(hdc1, LOGPIXELSY);
			ReleaseDC(hwnd,hdc1);

	//double anInch = 1440.0  /  GetDeviceCaps(hdc1, LOGPIXELSX);

	RECT rectLayoutArea;
	rectLayoutArea.top = (int)(layoutArea.GetTop() * anInchY);
	rectLayoutArea.bottom = (int)(layoutArea.GetBottom() * anInchY);
	rectLayoutArea.left = (int)(layoutArea.GetLeft() *anInchX  );
	rectLayoutArea.right = (int)(layoutArea.GetRight() * anInchX);

	HDC hdc = graphics->GetHDC();
	Gdiplus::Graphics gr2(hdc);
	SolidBrush br(Color(255,255,255));

	// We need to draw background on new HDC, otherwise the text will look ugly
	Status st = gr2.DrawImage(background,layoutArea.GetLeft(),layoutArea.GetTop(),layoutArea.GetLeft(), layoutArea.GetTop(), layoutArea.Width, layoutArea.Height,Gdiplus::UnitPixel/*gr2.GetPageUnit()*/);

	FORMATRANGE fmtRange;
	fmtRange.chrg.cpMax = -1;                    //Indicate character from to character to 
	fmtRange.chrg.cpMin = 0;
	fmtRange.hdc = hdc;                                //Use the same DC for measuring and rendering
	fmtRange.hdcTarget = hdc;                    //Point at printer hDC
	fmtRange.rc = rectLayoutArea;            //Indicate the area on page to print
	fmtRange.rcPage = rectLayoutArea;    //Indicate size of page


	int characterCount = ::SendMessage(hwnd, EM_FORMATRANGE, 1, (LPARAM)&fmtRange);

	//Release the device context handle obtained by a previous call
	graphics->ReleaseHDC(hdc);
}
bool TextNoOutlineStrategy::GdiMeasureStringRealHeight(
	Gdiplus::Graphics* pGraphics, 
	LOGFONTW* pLogFont,
	const wchar_t*pszText, 
	Gdiplus::Rect rtDraw,
	float* pfPixelsStartX,
	float* pfPixelsStartY,
	float* pfDestWidth,
	float* pfDestHeight )
{
	using namespace Gdiplus;
	Gdiplus::GraphicsPath* pPath=NULL;
	bool b = GDIPath::GetStringPath(
		pGraphics, 
		&pPath, 
		pszText, 
		pLogFont,
		rtDraw);

	if(false==b)
	{
		if(pPath)
		{
			delete pPath;
			pPath = NULL;
		}
		return false;
	}
	*pfDestWidth= rtDraw.GetLeft();
	*pfDestHeight= rtDraw.GetTop();
	b = GDIPath::MeasureGraphicsPathRealHeight(pGraphics, pPath, pfPixelsStartX, pfPixelsStartY, pfDestWidth, pfDestHeight);

	if(pPath)
	{
		delete pPath;
		pPath = NULL;
	}

	return b;
}
示例#7
0
            HRESULT Action(
                const P* pts,
                size_t count,
                const Gdiplus::Rect& clip,
                ScanConvertCallback callback,
                INT_PTR hint)
            {
                if(count <= 0) return E_INVALIDARG;
                if(pts == NULL) return E_INVALIDARG;
                if(callback == NULL) return E_INVALIDARG;

                n = (INT) count;
                pt = pts;

                /// initialize index array as natrual order
                std::vector<INT> idx(n);
                active.resize(n);
                for(INT i = 0; i < n; i ++)
                {
                    idx[i] =  i;
                }

                /// Sort idx by the order of pt[idx[k]].Y
                std::sort(&idx[0], &idx[0] + n, CompareIndex(pt));

                nact = 0;       /// number of active edges, init as empty
                INT k = 0;      /// idx[k] is the next vertex to precess
                INT y0 = max(clip.GetTop(), xtl::FloorCast<INT>(pt[idx[0]].Y));     /// the topmost scanline
                INT y1 = min(clip.GetBottom(), xtl::CeilCast<INT>(pt[idx[n-1]].Y)); /// the bottom  scanline

                /// step through scanlines
                /// scanline y is at y+.5 in continuous coordinates
                for(INT y = y0; y < y1; y ++)
                {
		            /// check vertices between previous scanline and current one, if any
                    for (; (k < n) && (pt[idx[k]].Y <= y); k++)
                    {
			            /// to simplify, if pt.y = y+.5, pretend it's above
                        /// invariant: y-.5 < pt[i].y <= y+.5
			            INT i = idx[k];

			            ///  insert or delete edges before and after vertex i 
                        ///  (i-1 to i, and i to i+1) from active list if they cross scanline y
                        INT j = i > 0 ? i-1 : n-1;	/// vertex previous to i
			            if (pt[j].Y <= y)	        /// old edge, remove from active list
                        {
                            DeleteActiveEdge(j);
                        }
                        else if (pt[j].Y > y)       ///  new edge, add to active list
                        {
                            InsertActiveEdge(j, y);
                        }

			            j = i < (n - 1) ? i+1 : 0;	/// vertex next after i
			            if (pt[j].Y <= y)	        /// old edge, remove from active list
				        {
				            DeleteActiveEdge(i);
				        }
			            else if (pt[j].Y > y)	    /// new edge, add to active list
				        {
				            InsertActiveEdge(i, y);
				        }
                    }

		            /// sort active edge list by active[j].x
                    std::sort(&active[0], &active[0] + nact, CompareEdge());

		            /// draw horizontal segments for scanline y
                    for (INT j=0; j < nact; j += 2)	/// draw horizontal segments
                    {
                        /// span 'tween j & j+1 is inside, span tween j+1 & j+2 is outside
                        INT xl = xtl::CeilCast<INT>(active[j].x);		/// left end of span
                        if (xl < clip.GetLeft()) xl = clip.GetLeft();
                        if (xl > clip.GetRight()) xl = clip.GetRight();

                        INT xr = xtl::CeilCast<INT>(active[j+1].x);	 /// right end of span
                        if (xr < clip.GetLeft()) xr = clip.GetLeft();
                        if (xr > clip.GetRight()) xr = clip.GetRight();

                        if (xl < xr)
                        {
                            /// Invoke call back in span
                            if(!callback(y, xl, xr, hint))
                            {
                                /// if call back returns false
                                /// return prematurely
                                return S_OK;
                            }
                        }

                        active[j].x += active[j].dx;	    /// increment edge coords
                        active[j+1].x += active[j+1].dx;
                    }
                }

                return S_OK;
            }
示例#8
0
bool TextOutlineStrategy::GdiMeasureStringRealHeight(
	Gdiplus::Graphics* pGraphics, 
	LOGFONTW* pLogFont,
	const wchar_t*pszText, 
	Gdiplus::Rect rtDraw,
	float* pfDestWidth,
	float* pfDestHeight )
{
	using namespace Gdiplus;
	Gdiplus::GraphicsPath* pPath=NULL;
	bool b = GDIPath::GetStringPath(
		pGraphics, 
		&pPath, 
		pszText, 
		pLogFont,
		rtDraw);

	if(false==b)
	{
		if(pPath)
		{
			delete pPath;
			pPath = NULL;
		}
		return false;
	}
	*pfDestWidth= rtDraw.GetLeft();
	*pfDestHeight= rtDraw.GetTop();
	b = GDIPath::MeasureGraphicsPathRealHeight(pGraphics, pPath, pfDestWidth, pfDestHeight);

	if(false==b)
	{
		if(pPath)
		{
			delete pPath;
			pPath = NULL;
		}
		return false;
	}

	float pixelThick = 0.0f;
	b = GDIPath::ConvertToPixels(pGraphics,m_nThickness,0.0f,&pixelThick,NULL);

	if(false==b)
	{
		if(pPath)
		{
			delete pPath;
			pPath = NULL;
		}
		return false;
	}

	*pfDestWidth += pixelThick;
	*pfDestHeight += pixelThick;

	if(pPath)
	{
		delete pPath;
		pPath = NULL;
	}
	return true;
}