基于Litecad半透明阴影填充(单一颜色)的一种实现方法
2014 年 3 月 21 日 基于Litecad半透明阴影填充(单一颜色)的一种实现方法无评论
在制作编录软件时,需要对一个区域进行半透明填充,类似于加一层蒙版,但是litecad API并没有提供透明填充的方法,官方论坛明确提出不支持。下文将介绍一种填充方法。
设计思路:
在litecad绘制并显示cad图的过程中,如果通过注册lcOnEventPaint回调函数ProcPaint,则会在绘制前和绘制后分别调用回调函数ProcPaint,并传入显示器的设备上下文hDC,通过直接绘制hDC实现阴影的显示。如同上一篇文章中绘制坐标轴和坐标文字的原理,不过这次是在cad图绘制后再绘制透明填充。
实现代码:
下例展示了在litecad绘制多边形后通过保存的坐标点列表,绘制阴影的过程:
1.数据结构
//采区边界点
typedef struct T_Point
{
double x;
double y;
};
typedef std::vector<T_Point> BOARD_POINT_LIST;
enum AREA_TYPE
{
UNMINED =0,
MINING,
MINED
};
typedef struct T_AreaBoard{
CString areaName;
AREA_TYPE areaType;
BOARD_POINT_LIST pointList;
};
typedef std::vector<T_AreaBoard> AREA_BOARD_LIST;
typedef struct T_Point
{
double x;
double y;
};
typedef std::vector<T_Point> BOARD_POINT_LIST;
enum AREA_TYPE
{
UNMINED =0,
MINING,
MINED
};
typedef struct T_AreaBoard{
CString areaName;
AREA_TYPE areaType;
BOARD_POINT_LIST pointList;
};
typedef std::vector<T_AreaBoard> AREA_BOARD_LIST;
2.注册回调
lcOnEventPaint( &CCADView::ProcPaint );
3.函数实现
void CALLBACK CCADView::ProcPaint( HANDLE hLcWnd, HANDLE hView, int Mode, HDC hDC, int Left, int Top, int Right, int Bottom )
{
int WIDTH = Right-Left;
int HEIGHT = Bottom-Top;
int DELTA = HEIGHT/6;
currentLeft = lcPropGetFloat( hView, LC_PROP_VIEW_LEF );
currentTop = lcPropGetFloat( hView, LC_PROP_VIEW_TOP );
currentRight = lcPropGetFloat( hView, LC_PROP_VIEW_RIG );
currentBottom = lcPropGetFloat( hView, LC_PROP_VIEW_BOT );
if (Mode==1)
{
//在HDC上绘制采区阴影
//TODO:阴影太大时填充拖动存在性能问题(Release版本无性能问题)
AREA_BOARD_LIST::iterator it = mAreaBoardList.begin();
for (;it!=mAreaBoardList.end();it++)
{
if (!isLayerVisible(it->areaName)||it->pointList.size()==0)
{
continue;
}
int size = it->pointList.size();
PointF* point = new PointF[size];
double x=0, y=0;
int count=0;
for (int i=0; i<size;i++)
{
point[i].X = REAL((it->pointList[i].x-currentLeft)/scaleX);
point[i].Y = REAL((currentTop-it->pointList[i].y)/scaleY);
x += point[i].X;
y += point[i].Y;
count++;
}
Color color;
switch(it->areaType)
{
case UNMINED:
color = Color(128, 94, 94, 94);
break;
case MINING:
color = Color(128, 74, 114, 114);
break;
case MINED:
color = Color(128, 114, 87, 74);
break;
}
SolidBrush solidBrush(color);
Graphics graphics(hDC);
graphics.FillPolygon(&solidBrush, point, size, FillModeAlternate);
SafeDeleteArray(point);
//采区文字显示
SetTextColor(hDC,RGB(210,221,124));
TextOut(hDC, x/count, y/count, it->areaName, it->areaName.GetLength());
}
}
}
{
int WIDTH = Right-Left;
int HEIGHT = Bottom-Top;
int DELTA = HEIGHT/6;
currentLeft = lcPropGetFloat( hView, LC_PROP_VIEW_LEF );
currentTop = lcPropGetFloat( hView, LC_PROP_VIEW_TOP );
currentRight = lcPropGetFloat( hView, LC_PROP_VIEW_RIG );
currentBottom = lcPropGetFloat( hView, LC_PROP_VIEW_BOT );
if (Mode==1)
{
//在HDC上绘制采区阴影
//TODO:阴影太大时填充拖动存在性能问题(Release版本无性能问题)
AREA_BOARD_LIST::iterator it = mAreaBoardList.begin();
for (;it!=mAreaBoardList.end();it++)
{
if (!isLayerVisible(it->areaName)||it->pointList.size()==0)
{
continue;
}
int size = it->pointList.size();
PointF* point = new PointF[size];
double x=0, y=0;
int count=0;
for (int i=0; i<size;i++)
{
point[i].X = REAL((it->pointList[i].x-currentLeft)/scaleX);
point[i].Y = REAL((currentTop-it->pointList[i].y)/scaleY);
x += point[i].X;
y += point[i].Y;
count++;
}
Color color;
switch(it->areaType)
{
case UNMINED:
color = Color(128, 94, 94, 94);
break;
case MINING:
color = Color(128, 74, 114, 114);
break;
case MINED:
color = Color(128, 114, 87, 74);
break;
}
SolidBrush solidBrush(color);
Graphics graphics(hDC);
graphics.FillPolygon(&solidBrush, point, size, FillModeAlternate);
SafeDeleteArray(point);
//采区文字显示
SetTextColor(hDC,RGB(210,221,124));
TextOut(hDC, x/count, y/count, it->areaName, it->areaName.GetLength());
}
}
}
其中mAreaBoardList为在绘制边界时存储的边界列表。
Tags: litecad 半透明填充 蒙板 阴影
发表评论