Skip to content

Commit

Permalink
Perf: 提高默认样式的直线的绘制速度 (#214)
Browse files Browse the repository at this point in the history
* ignore .history (generated by Local History extension)
* perf: 提高默认样式的直线的绘制速度(PS_GEOMETRIC 笔类型的绘制速度极慢)
* perf: 绘制直线时,如线型为 NULL_LINE 则跳过绘制只移动当前点
  • Loading branch information
yixy-only authored Jul 12, 2024
1 parent b07e2cb commit fb92037
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 35 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.vs/
.history
*.tlog
*.obj
[Dd]ebug/
Expand Down
101 changes: 66 additions & 35 deletions src/egegapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -256,26 +256,44 @@ void moverel(int dx, int dy, PIMAGE pimg)
void line(int x1, int y1, int x2, int y2, PIMAGE pimg)
{
PIMAGE img = CONVERT_IMAGE(pimg);
MoveToEx(img->m_hDC, x1, y1, NULL);
LineTo(img->m_hDC, x2, y2);
if (img) {
if (img->m_linestyle.linestyle != NULL_LINE) {
MoveToEx(img->m_hDC, x1, y1, NULL);
LineTo(img->m_hDC, x2, y2);
} else {
MoveToEx(img->m_hDC, x2, y2, NULL);
}
}
CONVERT_IMAGE_END;
}

void linerel(int dx, int dy, PIMAGE pimg)
{
PIMAGE img = CONVERT_IMAGE(pimg);
POINT pt;
GetCurrentPositionEx(img->m_hDC, &pt);
dx += pt.x;
dy += pt.y;
LineTo(img->m_hDC, dx, dy);
if (img) {
POINT pt;
GetCurrentPositionEx(img->m_hDC, &pt);
dx += pt.x;
dy += pt.y;
if (img->m_linestyle.linestyle != NULL_LINE) {
LineTo(img->m_hDC, dx, dy);
} else {
MoveToEx(img->m_hDC, dx, dy, NULL);
}
}
CONVERT_IMAGE_END;
}

void lineto(int x, int y, PIMAGE pimg)
{
PIMAGE img = CONVERT_IMAGE(pimg);
LineTo(img->m_hDC, x, y);
if (img) {
if (img->m_linestyle.linestyle != NULL_LINE) {
LineTo(img->m_hDC, x, y);
} else {
MoveToEx(img->m_hDC, x, y, NULL);
}
}
CONVERT_IMAGE_END;
}

Expand Down Expand Up @@ -531,46 +549,59 @@ static int upattern2array(unsigned short pattern, DWORD style[])

static void update_pen(PIMAGE img)
{
LOGBRUSH lbr;
lbr.lbColor = ARGBTOZBGR(img->m_linecolor);
lbr.lbStyle = BS_SOLID;
lbr.lbHatch = 0;

const int linestyle = img->m_linestyle.linestyle;
const unsigned short pattern = img->m_linestyle.upattern;
const int thickness = img->m_linestyle.thickness;

// 添加这些属性以获得正确的显示效果
int ls = linestyle | PS_GEOMETRIC;
HPEN hpen;

switch (img->m_linestartcap) {
case LINECAP_FLAT : ls |= PS_ENDCAP_FLAT; break;
case LINECAP_ROUND: ls |= PS_ENDCAP_ROUND; break;
case LINECAP_SQUARE: ls |= PS_ENDCAP_SQUARE; break;
default: ls |= PS_ENDCAP_FLAT; break;
}
if ((thickness == 1) && ((linestyle == SOLID_LINE) || (linestyle == NULL_LINE))) {
LOGPEN logPen;
logPen.lopnStyle = linestyle; // Other styles may be drawn incorrectly
logPen.lopnWidth.x = 1; // Width
logPen.lopnWidth.y = 1; // Unuse
logPen.lopnColor = ARGBTOZBGR(img->m_linecolor);

switch(img->m_linejoin) {
case LINEJOIN_MITER: ls |= PS_JOIN_MITER; break;
case LINEJOIN_BEVEL: ls |= PS_JOIN_BEVEL; break;
case LINEJOIN_ROUND: ls |= PS_JOIN_ROUND; break;
default: ls |= PS_JOIN_MITER; break;
}
hpen = CreatePenIndirect(&logPen);
} else {
unsigned int penStyle = linestyle;

SetMiterLimit(img->m_hDC, img->m_linejoinmiterlimit, NULL);
penStyle |= PS_GEOMETRIC;

HPEN hpen;
if (linestyle == USERBIT_LINE) {
DWORD style[20] = {0};
int bn = upattern2array(pattern, style);
hpen = ExtCreatePen(ls, thickness, &lbr, bn, style);
} else {
hpen = ExtCreatePen(ls, thickness, &lbr, 0, NULL);
switch (img->m_linestartcap) {
case LINECAP_FLAT : penStyle |= PS_ENDCAP_FLAT; break;
case LINECAP_ROUND: penStyle |= PS_ENDCAP_ROUND; break;
case LINECAP_SQUARE: penStyle |= PS_ENDCAP_SQUARE; break;
default: penStyle |= PS_ENDCAP_FLAT; break;
}

switch(img->m_linejoin) {
case LINEJOIN_MITER: penStyle |= PS_JOIN_MITER; break;
case LINEJOIN_BEVEL: penStyle |= PS_JOIN_BEVEL; break;
case LINEJOIN_ROUND: penStyle |= PS_JOIN_ROUND; break;
default: penStyle |= PS_JOIN_MITER; break;
}

LOGBRUSH lbr;
lbr.lbColor = ARGBTOZBGR(img->m_linecolor);
lbr.lbStyle = BS_SOLID;
lbr.lbHatch = 0;

if (linestyle == USERBIT_LINE) {
DWORD style[20] = {0};
int bn = upattern2array(pattern, style);
hpen = ExtCreatePen(penStyle, thickness, &lbr, bn, style);
} else {
hpen = ExtCreatePen(penStyle, thickness, &lbr, 0, NULL);
}
}

if (hpen) {
DeleteObject(SelectObject(img->m_hDC, hpen));
}

SetMiterLimit(img->m_hDC, img->m_linejoinmiterlimit, NULL);

// why update pen not in IMAGE???
#ifdef EGE_GDIPLUS
Gdiplus::Pen* pen = img->getPen();
Expand Down

0 comments on commit fb92037

Please sign in to comment.