public static void PolyDraw( System.Drawing.Drawing2D.GraphicsPath pPath, POINT[] lppt, byte[] lpbTypes, int cCount) { int nIndex; POINT pptLastMoveTo = new POINT(); POINT pptPrev = new POINT(); bool bLastMoveToNull = true; // for each of the points we have... for (nIndex = 0; nIndex < cCount; nIndex++) { switch (lpbTypes[nIndex]) { case PT_MOVETO: if (bLastMoveToNull == false && nIndex > 0) { pPath.CloseFigure(); } pptLastMoveTo = lppt[nIndex]; bLastMoveToNull = false; pptPrev = lppt[nIndex]; break; case PT_LINETO | PT_CLOSEFIGURE: pPath.AddLine(pptPrev.X, pptPrev.Y, lppt[nIndex].X, lppt[nIndex].Y); pptPrev = lppt[nIndex]; if (bLastMoveToNull == false) { pPath.CloseFigure(); pptPrev = pptLastMoveTo; } bLastMoveToNull = true; break; case PT_LINETO: pPath.AddLine(pptPrev.X, pptPrev.Y, lppt[nIndex].X, lppt[nIndex].Y); pptPrev = lppt[nIndex]; break; case PT_BEZIERTO | PT_CLOSEFIGURE: //ASSERT(nIndex + 2 <= cCount); pPath.AddBezier( pptPrev.X, pptPrev.Y, lppt[nIndex].X, lppt[nIndex].Y, lppt[nIndex + 1].X, lppt[nIndex + 1].Y, lppt[nIndex + 2].X, lppt[nIndex + 2].Y); nIndex += 2; pptPrev = lppt[nIndex]; if (bLastMoveToNull == false) { pPath.CloseFigure(); pptPrev = pptLastMoveTo; } bLastMoveToNull = true; break; case PT_BEZIERTO: //ASSERT(nIndex + 2 <= cCount); pPath.AddBezier( pptPrev.X, pptPrev.Y, lppt[nIndex].X, lppt[nIndex].Y, lppt[nIndex + 1].X, lppt[nIndex + 1].Y, lppt[nIndex + 2].X, lppt[nIndex + 2].Y); nIndex += 2; pptPrev = lppt[nIndex]; break; } } // If the figure was never closed and should be, // close it now. if (bLastMoveToNull == false && nIndex > 1) { pPath.AddLine(pptPrev.X, pptPrev.Y, pptLastMoveTo.X, pptLastMoveTo.Y); //pPath->CloseFigure(); } }
static extern bool PolyDraw(IntPtr hdc, POINT[] lppt, byte[] lpbTypes, int cCount);
public static bool GetStringPath( System.Drawing.Graphics pGraphics, System.Drawing.Drawing2D.GraphicsPath ppPath, string pszText, LOGFONT plf, System.Drawing.Rectangle rtDraw) { IntPtr hDC = pGraphics.GetHdc(); int nPrevMode = SetBkMode(hDC, TRANSPARENT); // create and select it IntPtr hFont = CreateFontIndirect(plf); if (null == hFont) return false; IntPtr hOldFont = (IntPtr)SelectObject(hDC, hFont); RECT rect = new RECT(rtDraw); // use a path to record how the text was drawn const uint DT_CENTER = 0x00000001; BeginPath(hDC); DrawText(hDC, pszText, pszText.Length, ref rect, DT_CENTER); EndPath(hDC); // Find out how many points are in the path. Note that // for long strings or complex fonts, this number might be // gigantic! int nNumPts = GetPath(hDC, null, null, 0); if (nNumPts == 0) return false; // Allocate memory to hold points and stroke types from // the path. POINT[] lpPoints = new POINT[nNumPts]; byte[] lpTypes = new byte[nNumPts]; // Now that we have the memory, really get the path data. nNumPts = GetPath(hDC, lpPoints, lpTypes, nNumPts); // If it worked, draw the lines. Win95 and Win98 don't support // the PolyDraw API, so we use our own member function to do // similar work. If you're targeting only Windows NT, you can // use the PolyDraw() API and avoid the COutlineView::PolyDraw() // member function. if (nNumPts != -1) PolyDraw(ppPath, lpPoints, lpTypes, nNumPts); // Put back the old font SelectObject(hDC, hOldFont); DeleteObject(hFont); SetBkMode(hDC, nPrevMode); pGraphics.ReleaseHdc(hDC); return true; }