⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 entityrenderer.cpp

📁 mtext,编辑器,支持潜入对象
💻 CPP
📖 第 1 页 / 共 2 页
字号:

void CEntityRenderer::outputPolyBezier(int ndims, 
									   int face, 
									   gr_displayobject* pDispObj,
									   CDrawDevice* pDrawDevice,
									   gr_view* pView,
									   POINT BltArea[2],
									   int*	pFirstPt,
									   int undraw,
									   int undrawcol,
									   int rop,
									   int hl,
									   int width)
{
	int fi1, fi2, fi4;
	fi2 = (pDispObj->npts + face) * ndims;
	
	const int	BufferSize = 100;
	bool		NeedToDelete;
	
	POINT*		pPolyPts; 
	POINT		PointBuffer[BufferSize];
	
	if(fi2 / ndims > BufferSize)
	{
		pPolyPts = new POINT[fi2 / ndims];
		NeedToDelete = true;
	}
	else
	{
		pPolyPts = PointBuffer;
		NeedToDelete = false;
	}
	
	for(fi1 = 0; fi1 < fi2; fi1 += ndims) 
	{
		if(face && fi1 >= fi2 - ndims) 
			gr_rp2pix(pView, pDispObj->chain[0], pDispObj->chain[1], (int*)&pPolyPts[fi1 / ndims].x, (int*)&pPolyPts[fi1 / ndims].y);
		else 
			gr_rp2pix(pView, pDispObj->chain[fi1], pDispObj->chain[fi1+1], (int*)&pPolyPts[fi1 / ndims].x, (int*)&pPolyPts[fi1 / ndims].y);
	} // end of for(fi1=0...
	
	// Expand the Bitblt area if needed.
	if(BltArea) 
		for(fi1 = 0; fi1 < fi2; fi1 += ndims) 
		{
			fi4 = fi1 / ndims;
			if(*pFirstPt)
			{
				BltArea[0].x = pPolyPts[fi4].x;  
				BltArea[0].y = pPolyPts[fi4].y;
				BltArea[1].x = pPolyPts[fi4].x;  
				BltArea[1].y = pPolyPts[fi4].y;
				*pFirstPt = 0;
			} 
			else 
			{
				if(BltArea[0].x > pPolyPts[fi4].x)
					BltArea[0].x = pPolyPts[fi4].x;
				if(BltArea[0].y > pPolyPts[fi4].y)
					BltArea[0].y = pPolyPts[fi4].y;
				if(BltArea[1].x < pPolyPts[fi4].x)
					BltArea[1].x = pPolyPts[fi4].x;
				if(BltArea[1].y < pPolyPts[fi4].y)
					BltArea[1].y = pPolyPts[fi4].y;
			}
		}
		
	SetDcFillColorMem(undraw ? undrawcol : pDispObj->color, hl, rop, pDrawDevice);
	SetDcColorMem(undraw ? undrawcol : pDispObj->color, width, hl, rop, pDrawDevice);
	pDrawDevice->PolyBezier(pPolyPts, pDispObj->npts + face);
		
	if(NeedToDelete)
		delete[] pPolyPts;
} 

void CEntityRenderer::outputPolyline(int ndims, 
							   int face, 
							   struct gr_displayobject *tdo1, 
							   CDrawDevice *pDrawDevice,
							   struct gr_view *gView, 
							   POINT BltArea[2],
							   int *FstPt,
							   int undraw,
							   int undrawcol,
							   int rop,
							   int hl,
							   int width)
{
	int fi1,fi2,fi3,fi4;
	int chainidx;
	int clipresult;
	
	int drawpl=0;    // if 1, draw the polyline
	int numplpts=0;  // number of points in the polyline
	
	SetDcColorMem(undraw ? undrawcol : tdo1->color,width,hl,rop,pDrawDevice);
	
	fi2=(tdo1->npts-2+face)*ndims;
	
	const int BufferSize = 100;
	bool NeedToDelete;
	
	POINT * pPolyPts;
	POINT PointBuffer[BufferSize];
	
	// Note space needed is fi2/ndims + 2 because the loop below has fi1 <= fi2
	// and the function gr_vect_rp2pix stores two points in the pPolyPts array,
	// not just one.
	
	int space_needed = fi2/ndims + 2; 
	
	if (space_needed > BufferSize)
	{
		pPolyPts = new POINT[space_needed];
		NeedToDelete = true;
	}
	else
	{
		pPolyPts = PointBuffer;
		NeedToDelete = false;
	}
	
	// Convert the points into the poly list.
	for (chainidx=0,fi1=0; fi1<=fi2; fi1+=ndims) 
	{
		if (face && fi1==fi2) 
		{
			clipresult=gr_vect_rp2pix(
				&tdo1->chain[fi1],
				&tdo1->chain[0],
				(int *)&pPolyPts[chainidx].x,  /* Filling 4 ints. */
				gView);
		} 
		else 
		{
			clipresult=gr_vect_rp2pix(
				&tdo1->chain[fi1],
				&tdo1->chain[fi1+ndims],
				(int *)&pPolyPts[chainidx].x,  /* Filling 4 ints. */
				gView);
		}  
		
		if(BltArea && (clipresult==0 || clipresult==2)) 
		{
			for(fi3=((chainidx==0) ? 0 :1); fi3<2; fi3++) 
			{
				fi4=chainidx+fi3;
				assert(fi4 < space_needed);
				if(*FstPt) 
				{
					BltArea[0].x=pPolyPts[fi4].x;  
					BltArea[0].y=pPolyPts[fi4].y;
					BltArea[1].x=pPolyPts[fi4].x;  
					BltArea[1].y=pPolyPts[fi4].y;
					*FstPt=0;
				} 
				else 
				{
					if(BltArea[0].x>pPolyPts[fi4].x)
						BltArea[0].x=pPolyPts[fi4].x;
					if(BltArea[0].y>pPolyPts[fi4].y)
						BltArea[0].y=pPolyPts[fi4].y;
					if(BltArea[1].x<pPolyPts[fi4].x)
						BltArea[1].x=pPolyPts[fi4].x;
					if(BltArea[1].y<pPolyPts[fi4].y)
						BltArea[1].y=pPolyPts[fi4].y;
				}
			} // end of for(fi3=...
		} // end of if(BltArea && ...
		
		chainidx++;	
		
		// each of the cases clipresult==1 and clipresult==2 sets chainidx to 0, which keeps the next code block
		// from executing, so commenting out the continues is valid
		//
		
		if(clipresult==0) 
		{  
			// Normal, acceptable vector, so see if there are more
			continue;
		} 
		else if(clipresult==1) 
		{
			if(chainidx>1) 
			{  // Off the screen.
				drawpl=1;           // set flag to indicate need to draw
				numplpts=chainidx;  // set number of points
			}
			// Reset the beg poly point counter.
			chainidx=0;
		} 
		else if(clipresult==2) 
		{  // Chopped it
			drawpl=1;               // set flag to indicate need to draw
			numplpts=chainidx+1;    // set number of points
			
			// Reset the beg poly point counter.
			chainidx=0;
		}
		
		if (drawpl) 
		{
			pDrawDevice->Polyline(pPolyPts,numplpts);
		}	// end of draw the polyline block
		
		drawpl = 0;
		
	} // end of loop over points in poly list
	
	// at this point we've gone through this list item and we draw anything remaining
	
    if(chainidx) 
	{
		
		numplpts=chainidx+1;   
		
		pDrawDevice->Polyline(pPolyPts,numplpts);
		
	}
	
	if (NeedToDelete)
	{
		delete [] pPolyPts;
	}
}

void CEntityRenderer::drawDisplayObjects(gr_displayobject* beg, 
										 int width,
										 CDrawDevice* pDrawDevice,
										 db_drawing* flp, 
										 gr_view*gView,
										 POINT BltArea[2],
										 int* FstPt,
										 int xor,
										 int hl,
										 int undraw,
										 int undrawcol,
										 int fillmode)
{
	gr_displayobject*	pTmpDispObj;
	int					rop;
	bool				bUsingGDIPath = false;
	
	CDC*		pDC = pDrawDevice->getCDC();
	CIcadView*	pIcadView = SDS_CMainWindow->GetIcadView();
	
    //<alm>
    int hl_store = hl;
    //</alm>

	for(pTmpDispObj = beg; pTmpDispObj; pTmpDispObj = pTmpDispObj->next) 
	{
		int		face, ndims,
			iFillColor;
		
		if(pTmpDispObj->npts < 2 || !pTmpDispObj->chain)
			continue;
		
		ndims = ((pTmpDispObj->type & DISP_OBJ_PTS_3D) ? 1 : 0) + 2;
		face = ((pTmpDispObj->type & DISP_OBJ_PTS_CLOSED) != 0);
		
		if((pTmpDispObj->color == -1 || xor) && !undraw) 
		{
			rop = R2_XORPEN;
			pDrawDevice->SetDrawMode(RasterConstants::MODE_XOR);
		}
		else
		{
			rop = R2_COPYPEN;
			pDrawDevice->SetDrawMode(RasterConstants::MODE_COPY);
		}

        //<alm>
        if (pTmpDispObj->type & DISP_OBJ_HIGHLIGHTED)
        {
            hl = 1;
        }
        else
        {
            hl = hl_store;
        }
        //</alm>

        if((pTmpDispObj->type & DISP_OBJ_PTS_GDI_FILLPATH ||
			pTmpDispObj->type & DISP_OBJ_PTS_GDI_TRUETYPE) && !bUsingGDIPath)
		{
			// Prepare a GDI path for filling.
			pDC->SetPolyFillMode(ALTERNATE);
			pDC->BeginPath();
			iFillColor = pTmpDispObj->color;
			bUsingGDIPath = true;
		}
		
		// Now draw it!
		if(((pTmpDispObj->type & DISP_OBJ_PTS_FILLABLE) || (pTmpDispObj->type & DISP_OBJ_PTS_GDI_FILLPATH)) && fillmode)
        {
			// Solid Fill or a path for a Solid hatch or for a TTF text contour
			CEntityRenderer::outputPolygon(ndims,
				face,
				pTmpDispObj,
				pDrawDevice,
				gView,
				BltArea,
				FstPt,
				undraw,
				undrawcol,
				rop,
				hl,
				width,
				!(pTmpDispObj->type & DISP_OBJ_PTS_GDI_FILLPATH));	//Fill the interior only, do not draw outline.
			/*D.G.*/// ... if it's not a path of a solid hatch or TTF text contour!
        }
		else
			if(pTmpDispObj->type & DISP_OBJ_PTS_GDI_TRUETYPE)
				CEntityRenderer::outputPolyBezier(ndims,
				face,
				pTmpDispObj,
				pDrawDevice,
				gView,
				BltArea,
				FstPt,
				undraw,
				undrawcol,
				rop,
				hl,
				width);
			else
				CEntityRenderer::outputPolyline(ndims,
				face,
				pTmpDispObj,
				pDrawDevice,
				gView,
				BltArea,
				FstPt,
				undraw,
				undrawcol,
				rop,
				hl,
				width);
			
			if(bUsingGDIPath && (!pTmpDispObj->next || pTmpDispObj->GetSourceEntity() != pTmpDispObj->next->GetSourceEntity() ||
				(!(pTmpDispObj->next->type & DISP_OBJ_PTS_GDI_FILLPATH) &&
				!(pTmpDispObj->next->type & DISP_OBJ_PTS_GDI_TRUETYPE))))
			{
				// Now let's fill the GDI path.
				pDC->EndPath();

				if(IsPrinting())
					SetDcFillColorMem(undraw ? undrawcol : iFillColor, hl, rop, pDrawDevice);
				else
				{
					HBRUSH hBrush;
					if(hl)
					{
						resbuf	rb;
						sds_getvar("BKGCOLOR", &rb);
						int		BGColor = SDS_RGBFromACADColor(rb.resval.rint);
						hBrush = ::CreateHatchBrush(HS_DIAGCROSS, BGColor);
					}
					else
						hBrush = ::CreateSolidBrush(::SDS_BrushColorFromACADColor(undraw ? undrawcol : iFillColor));
					
					::DeleteObject(::SelectObject(pDC->m_hDC, hBrush));
				}
				
				if(hl)
				{
					int		oldBackMode = pDC->SetBkMode(TRANSPARENT);
					pDC->StrokeAndFillPath();
					pDC->SetBkMode(oldBackMode);
				}
				else
					pDC->StrokeAndFillPath();
				
				bUsingGDIPath = false;
			}
	} // end of loop over items (DispObjs) to draw
}

#ifndef _USE_DISP_OBJ_PTS_3D_
void CEntityRenderer::DrawEntity(db_handitem *elp,
								CDrawDevice *pDrawDevice,
								db_drawing *flp, 
								struct gr_view *gView,
								POINT BltArea[2],
								int *FstPt,
								int xor,
								int hl,
								int undraw,
								int undrawcol,
								int fillmode,
								int norecurs,
								db_viewport *pViewportForVpLayerSettings, 
								bool bRedraw,
								int width)
{
	struct gr_displayobject *beg=NULL,*end=NULL;
	db_handitem *telp;
	int freebeg=0;
	
	// get the target DC in case we have any TrueType text
	CDC*		pDC = pDrawDevice->getCDC();
	CIcadView*	pIcadView = SDS_CMainWindow->GetIcadView();
	
#if 0
	// DP: first version of code for displaying of 3D display objects
	// DP: now this functionality in rewritten DrawEntity()
	gr_displayobject* pOriginal = (struct gr_displayobject *)elp->ret_disp();
	gr_displayobject* pEnd = NULL;
	if(pOriginal == NULL)
	{
		telp=elp;
		// As an optimization, only use the VpLayerSettings if they really are going to matter
		//
		db_viewport *pViewport = NULL;
		if ( ( pViewportForVpLayerSettings != NULL ) &&
			( pViewportForVpLayerSettings->GetVpLayerFrozenLayerCount( ) > 0 ) )
		{
			pViewport = pViewportForVpLayerSettings;
		}
		
		// get the display objects
		int result = gr_getdispobjs(flp,
			NULL,
			&telp,
			&pOriginal,
			&pEnd,
			NULL,
			flp,
			gView,
			0,
			pDC,
			pViewport);

		if(pOriginal == NULL)
			return;

		elp->set_disp(pOriginal);
		freebeg = 1;
	}
	else
		freebeg = 1;

	int i, j, k;
	int inc; 

	beg = (gr_displayobject*)malloc(sizeof(gr_displayobject));
	beg->SetSourceEntity(pOriginal->GetSourceEntity());
	
	beg->next = NULL;
	beg->type = pOriginal->type & ~0x01;
	beg->color = pOriginal->color;
	beg->npts = pOriginal->npts;
	inc = 2 + (pOriginal->type & 0x01);
	
	beg->chain = (sds_real*)malloc((pOriginal->npts * 2 + 1) * sizeof(sds_real));
	for(i = 0, j = 0, k = 0; i < pOriginal->npts; ++i, j += inc, k += 2)
		gr_ucs2rp(&(pOriginal->chain[j]), &(beg->chain[k]), gView);
	
	end = beg;
	pOriginal = pOriginal->next;
	while(pOriginal != NULL)
	{
		end->next = (gr_displayobject*)malloc(sizeof(gr_displayobject));
		end->next->SetSourceEntity(pOriginal->GetSourceEntity());

		end->next->next = NULL;
		end->next->type = pOriginal->type & ~0x01;
		end->next->color = pOriginal->color;
		end->next->npts = pOriginal->npts;
		inc = 2 + (pOriginal->type & 0x01);

		end->next->chain = (sds_real*)malloc((pOriginal->npts * 2 + 1) * sizeof(sds_real));
		for(i = 0, j = 0, k = 0; i < pOriginal->npts; ++i, j += inc, k += 2)
			gr_ucs2rp(&(pOriginal->chain[j]), &(end->next->chain[k]), gView);

		end = end->next;
		pOriginal = pOriginal->next;
	}
#else
	if (bRedraw)
	{  // begin Redraw case
		beg=(struct gr_displayobject *)elp->ret_disp();
	}  //   end Redraw case
	else
	{  // begin Regen case
		telp=elp;
		// As an optimization, only use the VpLayerSettings if they really are going to matter
		//
		db_viewport *pViewport = NULL;
		if ( ( pViewportForVpLayerSettings != NULL ) &&
			( pViewportForVpLayerSettings->GetVpLayerFrozenLayerCount( ) > 0 ) )
		{
			pViewport = pViewportForVpLayerSettings;
		}
		
		
		// get the display objects
		int result = gr_getdispobjs(flp,
			NULL,
			&telp,
			&beg,
			&end,
			NULL,
			flp,
			gView,
			1,
			pDC,
			pViewport);
		
		if(result) 
			return;
        freebeg=1;
	}  //   end Regen case
#endif // 0
	
	if(beg != NULL)
		CEntityRenderer::drawDisplayObjects( beg, 
		width, 
		pDrawDevice, 
		flp, 
		gView, 
		BltArea, 
		FstPt, 
		xor, 
		hl, 
		undraw, 
		undrawcol, 
		fillmode);
	
		/*
		The last parameter, onlyFill is not used anymore.
		If the entity has polygon display object(s) and Polygon() member function is called,
		it will always fill the interior without drawing outline.
		
		  However, if a polyline diplay object has same start and end points, and
		  Polygon() member function is called from Polyline() to remove nubbin problems, 
		  it will not	fill in the interior, but it will draw outline.
		  
			The previous code did not work for blocks containing solid, dimension, etc...
			because entities inside a block does not go thru drawDisplayObjects, and
			there is no way to catch that.
	*/
	
	if (freebeg)
		gr_freedisplayobjectll(beg);
}
#endif

void CEntityRenderer::SetDcFillColorMem(int color, 
									   int hl, 
									   int rop, 
									   CDrawDevice *pDevice)
{
	// this is here just to placate the compiler
}

void CEntityRenderer::SetDcColorMem(int color, 
								   int width, 
								   int hl, 
								   int rop, 
								   CDrawDevice *pDevice)
{
	// this is here just to placate the compiler
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -