抗锯齿直线绘制方法(四)
到目前为止,还有Lh-2、Lh-3、Ld-2、Ld-3四个直线类型未处理,我们将Lh-2和Lh-3统一标记为Lh-2t3,可简写为Lh-23,将Ld-2和Ld-3统一标记为Ld-2t3,可简写为Ld-23。本章节主要介绍这些直线类的绘制方法,这类直线占全部直线类型的42%。
这类直线我们使用"对称斜线三段模型"方法来绘制抗锯齿直线。
1. 对称斜线与三段模型
1.1 对称斜线概念
在"直线特征"一节中讲过,第四像限靠近X轴区域的直线是由alen1和alen2两种长度的水平子线段组成,靠近对角线区域的直线是由alen1和alen2两种长度的对角子线段组成。我们称连续几个alen1长度子线段所组成的一段直线为"对称斜线",对称斜线的长度(宽度或高度)用xlen表示,两段对称斜线之间有一个长度为alen2的子线段,称为间隔线段。见图示9。
对称斜线的长度可以通过Gdixline_GetNextSegment函数的循环比较计算,但为了提高计算效率我们编写一个Gdixline_GetNextSegmentX函数来计算xlen值。这个函数涉及小数(即余数)处理的一些概念,函数中有注释。
1.2 三段模型概念
从图示9中可知,一条直线由三个基本线段组成,即首个对称斜线段xlen1、间隔线段alen2、后续对称斜线段xlen2、xlen3等。后续对称斜线段的最大长度为(xlen1+alen1)+xlen1。直线的长度是无限的,但模型数据是有限的,所以模型数据必须是可以首尾循环,因此我们将后续对称斜线段的(xlen1+alen1)部分称为过渡段,xlen1部分与首个对称斜线段xlen1重合,称为基本段。
所以直线由基本段xlen1、间隔段alen2和过渡段(xlen1+alen1)三部分所组成,其对应的模型分别标记为m1、m2、m3,称为三段模型。
在Lh-23和Ld-23类型的直线中,alen2的最大长度为4,但xlen1的长度可以无限。我们将xlen1<=12的直线称为有限直线,将xlen1>12的直线模型称为无限直线。
(1)有限直线三段模型
这类模型数据与直线各段长度是对应关系。
例: dx/dy=100/32的直线,其alen1=3,alen2=4,xlen1=12,xlen2=21。
则三段模型数据长度分别为:
m1=xlen1=12
m2=alen2=4
m3=xlen1+alen1=12+3=15
如Linex_model_3s32x模型数据表。
(2)无限直线三段模型
这类模型数据中只有间隔段与直线间隔长度是对应关系,而其它两个段是填充关系。填充关系,就是将每个对称斜线段进行四等分,每一个1/4斜线段的首个子线段(alen1)用模型中的一组颜色通量数据,其它子线段全部用模型中的填充颜色通量。
例: dx/dy=100/33的直线,其alen1=3,alen2=4。
m1=alen124=24
m2=alen2=4
m3=m1=24
如Linex_model_3s33x模型数据表。
1.3 三段模型数据
(1)Linex_model_3s32x等数据表为直线三段模型。如果基本段点数<=12则为有限直线模型,如果基本段点数>12则为无限直线模型。表格名中的"3s"表示为3段模型,"32"表示该模型数据的参考直线为dx/dy=100/32。"x"表示为X方向直线(dx>dy)模型,"y"表示为Y方向直线(dx<dy)模型。
每一个直线类型,其无限模型只有一个,而有限模型可以根据xlen1值定义多个模型。如Lh-2-3类直线的无限直线模型为Linex_model_3s49x,而有限模型有4个,分别为Linex_model_3s44x、Linex_model_3s45x、Linex_model_3s47x、Linex_model_3s48x。
有限模型中xlen1大的兼容xlen1小的,如Linex_model_3s48x的xlen1=12,它兼容Linex_model_3s47x等模型,但在绘制时发现兼容效果并不理想,所以增加Linex_model_3s47x等模型。也就是说,模型分类越细则绘图质量越高。
(2)Linex_model_x34等为模型数据检索表。
2. 基本函数
基本函数如下:
.code
;==========================================================
;计算下一个对称斜线段长度
;入: pLine=GDIX_LINEMEAN结构地址,包含直线参数。
; nlen=未绘制的剩余长度(不包括终止点)
;出: EAX=斜线段长度
;---------------------------------------------------
;说明:
; 一条对称斜线段是由相同长度的连续多条子线段所组成,
; 即计算到pLine.alen2为止,不包括pLine.alen2。
;==========================================================
Gdixline_GetNextSegmentX proc pLine:QWORD,nlen:DWORD
mov r8d,edx ;保护
mov r10d,[rcx.GDIX_LINEMEAN].rem
test r10d,r10d
jz ss_end ;无余数时
shl r10d,1 ;rem*2
cmp r10d,[rcx.GDIX_LINEMEAN].ndiv
jle ss_le
;-------------------------------------------------------
; alen1>alen2的情况。公式推导:
;在非进位处余数器加上rem,在进位处余数器加上(rem-ndiv)。
;则在n段位置处的余数器值应小于或等于除数的1/2,公式如下:
; sumr+rem+n*(rem-ndiv) <= ndiv/2
;变换:
; n*(ndiv-rem) <= sumr+rem-ndiv/2
; n*(ndiv-rem) <= sumr+rem/2+(rem-ndiv)/2
; (n+0.5)*(ndiv-rem) <= sumr+rem/2
; n+0.5 <= (sumr*2+rem)/((ndiv-rem)*2)
;舍弃0.5:
; n = (sumr*2+rem)/((ndiv-rem)*2)
; 即在第n个子线段处不进位,对应子线段为间隔段。
;-------------------------------------------------------
;---计算进位处---
mov r11d,[rcx.GDIX_LINEMEAN].ndiv
shl r11d,1
sub r11d,r10d ;(ndiv-rem)*2
mov eax,[rcx.GDIX_LINEMEAN].sumr
add eax,eax
add eax,[rcx.GDIX_LINEMEAN].rem ;rem+sumr*2
xor edx,edx
div r11d
shl edx,1
cmp edx,r11d
jle ss_2
inc eax
ss_2:
mov r11d,eax ;n
;---计算累加余数---
mov eax,[rcx.GDIX_LINEMEAN].rem
sub eax,[rcx.GDIX_LINEMEAN].ndiv
imul r11d
add eax,[rcx.GDIX_LINEMEAN].rem
add [rcx.GDIX_LINEMEAN].sumr,eax
;---返回斜线长度---
mov eax,[rcx.GDIX_LINEMEAN].alen1
mul r11d
cmp eax,r8d
jnbe ss_end
ret
;------------------------------------------
;alen1<alen2的情况。公式推导:
; 余数累加至除数的1/2时产生进位。
; (sumr+rem*n)=ndiv/2
; n =(ndiv -2*sumr)/(2*rem)
; 即在第n段产生进位,对应子线段为间隔段。
;------------------------------------------
ss_le:
;---计算进位处---
mov eax,[rcx.GDIX_LINEMEAN].ndiv
mov edx,[rcx.GDIX_LINEMEAN].sumr
shl edx,1
sub eax,edx ;ndiv-sumr*2
xor edx,edx
div r10d ;(ndiv-sumr*2)/(rem*2)
mov r11d,eax ;=n
;---计算累加余数---
inc eax ;包含间隔段(因为下次计算时跳过间隔段)
mul [rcx.GDIX_LINEMEAN].rem
sub eax,[rcx.GDIX_LINEMEAN].ndiv
add [rcx.GDIX_LINEMEAN].sumr,eax ;累加余数
;---返回斜线长度---
mov eax,[rcx.GDIX_LINEMEAN].alen1
mul r11d
cmp eax,r8d
jnbe ss_end
ret
ss_end:
mov eax,r8d
ret
Gdixline_GetNextSegmentX endp
;=======================================================
;绘制抗锯齿直线---类似于Gdi+中的GdipDrawLineI函数
;入: hdc=DC句柄
; x1,y1=起始点坐标
; x2,y2=终止点坐标
; Argb=ARGB颜色
;=======================================================
Gdix_DrawLine proc hdc:QWORD,x1:DWORD,y1:DWORD,\
x2:DWORD,y2:DWORD,Argb:DWORD
LOCAL ss_rsi:QWORD
LOCAL ss_rdi:QWORD
LOCAL ss_rbx:QWORD
LOCAL ss_r12:QWORD
LOCAL ss_Info:GDIX_LINEINFO
mov ss_rsi,rsi
mov ss_rdi,rdi
mov ss_rbx,rbx
mov ss_r12,r12
lea rbx,ss_Info
;---RGB颜色转换为COLORREF颜色值---
mov eax,Argb
mov r10d,eax
and eax,0ffffffh
ror ax,8
rol eax,16
ror ax,8
ror eax,8
and r10d,0ff000000h
or eax,r10d
mov Argb,eax
;---计算直线特征参数(要求计算方向为正)---
invoke Gdix_GetLineInfo,rbx,x1,y1,x2,y2,1
test eax,eax
jz ss_out ;长度为零
mov rsi,ss_Info.px ;指向步进变量
mov rdi,ss_Info.py ;指向计算变量
;---分类分支绘制---
test eax,GDIX_HV45LINE
jnz ss_hv45 ;水平线、垂直线或45度线
cmp ss_Info.hSeg.alen,1
jz ss_diag ;偏向对角线
;-----------------------------------------------------------
;偏向于水平(垂直)的直线。根据首段水平(垂直)子线段长度分类。
;-----------------------------------------------------------
cmp ss_Info.hSeg.alen1,8 ;alen1=首段水平(垂直)子线段长度
jnc ss_hg8m
cmp ss_Info.hSeg.alen1,4
jnc ss_h47j
cmp ss_Info.hSeg.rem,0 ;余数=0时
jz ss_h47j
;---Lh-2和Lh-3类型直线---
invoke Gdix_DrawLine_h23m,hdc,Argb,0
jmp ss_out
ss_h47j: ;Lh-4至Lh-7类型直线
invoke Gdix_DrawLine_h47j,hdc,Argb,0
jmp ss_out
ss_hg8m: ;Lh-g8类型直线
invoke Gdix_DrawLine_hg8m,hdc,Argb,0
jmp ss_out
;------------------------------------------------------------
;偏向于对角线的直线。根据首段对角子线段长度分类。
;------------------------------------------------------------
ss_diag:
cmp ss_Info.dSeg.alen1,8 ;alen1=首段水平(垂直)子线段长度
jnc ss_dg8m
cmp ss_Info.dSeg.alen1,4
jnc ss_d47j
cmp ss_Info.dSeg.rem,0 ;余数=0时
jz ss_d47j
;---Ld-2和Ld-3类型直线---
invoke Gdix_DrawLine_d23m,hdc,Argb,0
jmp ss_out
ss_d47j: ;Ld-4至Ld-7类型直线
invoke Gdix_DrawLine_d47j,hdc,Argb,0
jmp ss_out
ss_dg8m: ;Ld-g8类型直线
invoke Gdix_DrawLine_dg8m,hdc,Argb,0
jmp ss_out
;---水平线或垂直线或45度线---
ss_hv45:
test eax,GDIX_45LINE
jnz ss_45
;---水平线或垂直线---
invoke Gdix_DrawLine_hor,hdc,Argb,0
jmp ss_out
;---45度线---
ss_45:
invoke Gdix_DrawLine_Ang45,hdc,Argb,0
ss_out:
mov r12,ss_r12
mov rbx,ss_rbx
mov rsi,ss_rsi
mov rdi,ss_rdi
ret
Gdix_DrawLine endp
基本函数说明:
(1)Gdixline_GetNextSegmentX函数: 用于计算下一个对称斜线段的长度,当GDIX_LINEMEAN结构的sumr成员值为零时,返回直线中首个对称斜线段的长度。
(2)Gdix_DrawLine函数: 这是绘制抗锯齿直线的总调用入口函数,经几次补充后,现已是一个完善的函数。
3. Lh-2t3类直线的抗锯齿绘制
绘制函数共有5个,其中测试函数1个:
(1)Gdix_LoadLineAlpha_h23m函数: 模型选择与装载。
(2)Gdix_DrawLine_h23mS函数: 使用有限模型绘制一段对称斜线。
(3)Gdix_DrawLine_h23mS24函数: 使用无限模型绘制一段对称斜线。
(4)Gdix_DrawLine_h23m函数: Lh-2t3直线绘制总函数。
(5)Gdpx_LineTest41函数: Lh-2t3直线绘制的测试函数。
;-------------------------------------------------
;颜色通量分配结构---用于3段模型
;-------------------------------------------------
ALPHA_LINE3S STRUCT
ALPHA_LINEHD <>
ALPHA_DISTR3 60 dup(<>)
ALPHA_LINE3S ENDS
.data
;-----------------------------------------------
;有限直线三段模型: Lh-3-4类型
;-----------------------------------------------
Linex_model_3s32x db 3 ;段数
db 12 ;基本段模型点数
db 0, 223, 0, 151, 0, 64
db 0, 231, 0, 159, 0, 80
db 0, 239, 0, 167, 0, 88
db 8, 239, 0, 175, 0, 96
db 4 ;间隔段模型点数
db 16, 239, 0, 183, 0, 104, 0, 24
db 15 ;过渡段模型点数
db 0, 199, 0, 112, 0, 32
db 0, 207, 0, 128, 0, 40
db 0, 215, 0, 143, 0, 48
db 0, 223, 0, 151, 0, 64
db 0, 239, 0, 159, 0, 80
;-----------------------------------------------
;无限直线三段模型: Lh-3-4类型
;-----------------------------------------------
Linex_model_3s33x db 3 ;段数
db 24 ;基本段模型点数
db 0, 223, 0, 151, 0, 64 ;第一个1/4斜线子线段颜色通量分配
db 0, 231, 0, 151, 0, 64 ;第一个1/4斜线子线段充填颜色通量分配
db 0, 231, 0, 159, 0, 80 ;第二个1/4斜线子线段颜色通量分配
db 0, 239, 0, 159, 0, 80 ;第二个1/4斜线子线段充填颜色通量分配
db 0, 239, 0, 159, 0, 88 ;第三个1/4斜线子线段颜色通量分配
db 8, 239, 0, 167, 0, 88 ;第三个1/4斜线子线段充填颜色通量分配
db 8, 239, 0, 167, 0, 96 ;第四个1/4斜线子线段颜色通量分配
db 16, 239, 0, 175, 0, 96 ;第四个1/4斜线子线段充填颜色通量分配
db 4 ;间隔段模型点数
db 16, 239, 0, 175, 0, 96, 0, 24
db 24 ;过渡段模型点数
db 0, 191, 0, 104, 0, 24
db 0, 191, 0, 104, 0, 24
db 0, 207, 0, 112, 0, 32
db 0, 207, 0, 112, 0, 32
db 0, 215, 0, 128, 0, 40
db 0, 215, 0, 128, 0, 40
db 0, 223, 0, 143, 0, 48
db 0, 223, 0, 143, 0, 48
;-----------------------------------------------
;无限直线三段模型: Lh-3-2类型
;-----------------------------------------------
Linex_model_3s34x db 3 ;段数
db 24 ;基本段模型点数
db 0, 223, 0, 143, 0, 48
db 0, 223, 0, 143, 0, 48
db 0, 223, 0, 128, 0, 40
db 0, 215, 0, 128, 0, 40
db 0, 215, 0, 112, 0, 32
db 0, 207, 0, 112, 0, 32
db 0, 207, 0, 104, 0, 24
db 0, 191, 0, 104, 0, 24
db 2 ;间隔段模型点数
db 0, 191, 0, 96
db 24 ;过渡段模型点数
db 16, 239, 0, 175, 0, 96
db 16, 239, 0, 175, 0, 96
db 8, 239, 0, 167, 0, 88
db 8, 239, 0, 167, 0, 88
db 0, 239, 0, 159, 0, 80
db 0, 239, 0, 159, 0, 80
db 0, 231, 0, 151, 0, 64
db 0, 231, 0, 151, 0, 64
;-----------------------------------------------
;有限直线三段模型: Lh-3-2类型
;-----------------------------------------------
Linex_model_3s35x db 3 ;段数
db 12 ;基本段模型点数
db 0, 223, 0, 143, 0, 48
db 0, 223, 0, 128, 0, 40
db 0, 215, 0, 112, 0, 32
db 0, 207, 0, 104, 0, 24
db 2 ;间隔段模型点数
db 0, 191, 0, 96
db 15 ;过渡段模型点数
db 16, 239, 0, 175, 0, 88
db 8, 239, 0, 167, 0, 88
db 0, 239, 0, 159, 0, 72
db 0, 231, 0, 151, 0, 56
db 0, 239, 0, 159, 0, 80
;-----------------------------------------------
;有限直线三段模型: Lh-2-3类型
;-----------------------------------------------
Linex_model_3s44x db 3 ;段数
db 2 ;基本段模型点数
db 0, 223, 0, 120
db 3 ;间隔段模型点数
db 16, 231, 0, 151, 0, 32
db 4 ;过渡段模型点数
db 0, 175, 0, 64
db 0, 215, 0, 96
;-----------------------------------------------
;有限直线三段模型: Lh-2-3类型
;-----------------------------------------------
Linex_model_3s45x db 3 ;段数
db 4 ;基本段模型点数
db 0, 223, 0, 112
db 16, 223, 0, 143
db 3 ;间隔段模型点数
db 32, 223, 0, 159, 0, 48
db 6 ;过渡段模型点数
db 0, 191, 0, 80
db 0, 223, 0, 96
db 8, 223, 0, 128
;-----------------------------------------------
;有限直线三段模型: Lh-2-3类型
;-----------------------------------------------
Linex_model_3s47x db 3 ;段数
db 6 ;基本段模型点数
db 0,223, 0,112
db 8, 231, 0, 128
db 16,231, 0, 143
db 3 ;间隔段模型点数
db 24, 231,0, 159, 0, 32
db 8 ;过渡段模型点数
db 0, 175, 0, 48
db 0, 191, 0, 96
db 0, 207, 0, 80
db 0, 223, 0, 96
;-----------------------------------------------
;有限直线三段模型: Lh-2-3类型
;-----------------------------------------------
Linex_model_3s48x db 3 ;段数
db 12 ;基本段模型点数
db 24, 223, 0, 112
db 8, 223, 0, 112
db 16, 223, 0, 128
db 16, 223, 0, 143
db 24, 223, 0, 143
db 32, 223, 0, 159
db 3 ;间隔段模型点数
db 32, 223, 0, 167, 0, 48
db 14 ;过渡段模型点数
db 0, 175, 0, 56
db 0, 191, 0, 64
db 0, 199, 0, 80
db 0, 207, 0, 88
db 0, 223, 0, 96
db 0, 223, 0, 96
db 0, 223, 0, 96
;-----------------------------------------------
;有限直线三段模型: Lh-2-3类型
;-----------------------------------------------
Linex_model_3s49x db 3 ;段数
db 16 ;基本段模型点数
db 24, 223, 0, 112
db 24, 223, 0, 112
db 8, 223, 0, 128
db 16, 223, 0, 128
db 16, 223, 0, 143
db 24, 223, 0, 143
db 24, 223, 0, 159
db 32, 223, 0, 159
db 3 ;间隔段模型点数
db 32, 223, 0, 159, 0, 48
db 16 ;过渡段模型点数
db 0, 175, 0, 48
db 0, 175, 0, 48
db 0, 175, 0, 64
db 0, 191, 0, 64
db 0, 191, 0, 80
db 0, 207, 0, 80
db 0, 207, 0, 96
db 8, 223, 0, 96
;-----------------------------------------------
;有限直线三段模型: Lh-3-4类型
;-----------------------------------------------
Linex_model_3s32y db 3 ;段数
db 12 ;基本段模型点数
db 8, 239, 0, 167, 0, 88
db 8, 239, 0, 183, 0, 96
db 16, 239, 0, 191, 0, 104
db 24, 231, 0, 199, 0, 120
db 4 ;间隔段模型点数
db 32, 223, 0, 215, 0, 128, 0, 40
db 15 ;过渡段模型点数
db 0, 223, 0, 135, 0, 56
db 0, 231, 0, 151, 0, 64
db 0, 239, 0, 159, 0, 72
db 8, 239, 0, 167, 0, 88
db 8, 239, 0, 183, 0, 96
;-----------------------------------------------
;无限直线三段模型: Lh-3-4类型
;-----------------------------------------------
Linex_model_3s33y db 3 ;段数
db 24 ;基本段模型点数
db 0, 247, 0, 167, 0, 88
db 8, 239, 0, 167, 0, 88
db 8, 239, 0, 183, 0, 96
db 16, 231, 0, 183, 0, 96
db 16, 231, 0, 191, 0, 104
db 24, 231, 0, 191, 0, 104
db 24, 231, 0, 191, 0, 120
db 32, 223, 0, 199, 0, 120
db 4 ;间隔段模型点数
db 32, 223, 0, 199, 0, 128, 0, 40
db 24 ;过渡段模型点数
db 0, 215, 0, 128, 0, 40
db 0, 215, 0, 128, 0, 40
db 0, 223, 0, 135, 0, 56
db 0, 223, 0, 135, 0, 56
db 0, 231, 0, 151, 0, 64
db 0, 231, 0, 151, 0, 64
db 8, 231, 0, 159, 0, 72
db 8, 231, 0, 159, 0, 72
;-----------------------------------------------
;无限直线三段模型: Lh-3-2类型
;-----------------------------------------------
Linex_model_3s34y db 3 ;段数
db 24 ;基本段模型点数
db 0, 247, 0, 159, 0, 72
db 8, 231, 0, 159, 0, 72
db 8, 231, 0, 151, 0, 64
db 0, 231, 0, 151, 0, 64
db 0, 231, 0, 143, 0, 56
db 0, 223, 0, 135, 0, 56
db 0, 223, 0, 135, 0, 40
db 0, 215, 0, 128, 0, 40
db 2 ;间隔段模型点数
db 0, 215, 0, 128
db 24 ;过渡段模型点数
db 32, 223, 0, 199, 0, 120
db 32, 223, 0, 199, 0, 120
db 24, 231, 0, 191, 0, 104
db 24, 231, 0, 191, 0, 104
db 24, 223, 0, 183, 0, 96
db 16, 231, 0, 183, 0, 96
db 16, 231, 0, 167, 0, 88
db 8, 239, 0, 167, 0, 88
;-----------------------------------------------
;有限直线三段模型: Lh-3-2类型
;-----------------------------------------------
Linex_model_3s35y db 3 ;段数
db 12 ;基本段模型点数
db 8, 239, 0, 159, 0, 72
db 8, 223, 0, 151, 0, 64
db 0, 231, 0, 135, 0, 56
db 0, 223, 0, 128, 0, 40
db 2 ;间隔段模型点数
db 0, 215, 0, 120
db 15 ;过渡段模型点数
db 32, 223, 0, 199, 0, 112
db 24, 231, 0, 191, 0, 104
db 16, 231, 0, 183, 0, 96
db 8, 239, 0, 167, 0, 88
db 8, 231, 0, 159, 0, 72
;-----------------------------------------------
;有限直线三段模型: Lh-2-3类型
;-----------------------------------------------
Linex_model_3s40y db 3 ;段数
db 2 ;基本段模型点数
db 8, 239, 0, 151
db 3 ;间隔段模型点数
db 48, 207, 0, 207, 0, 104
db 4 ;过渡段模型点数
db 8, 239, 0, 151
db 0, 215, 0, 96
;-----------------------------------------------
;有限直线三段模型: Lh-2-3类型
;-----------------------------------------------
Linex_model_3s44y db 3 ;段数
db 2 ;基本段模型点数
db 8, 239, 0, 143
db 3 ;间隔段模型点数
db 24, 231, 0, 175, 0, 56
db 4 ;过渡段模型点数
db 0, 207, 0, 88
db 0, 223, 0, 112
;-----------------------------------------------
;有限直线三段模型: Lh-2-3类型
;-----------------------------------------------
Linex_model_3s45y db 3 ;段数
db 4 ;基本段模型点数
db 8, 239, 0, 143
db 24, 223, 0, 175
db 3 ;间隔段模型点数
db 48, 207, 0, 191, 0, 80
db 6 ;过渡段模型点数
db 0, 207, 0, 112
db 8, 223, 0, 128
db 24, 223, 0, 143
;-----------------------------------------------
;有限直线三段模型: Lh-2-3类型
;-----------------------------------------------
Linex_model_3s47y db 3 ;段数
db 6 ;基本段模型点数
db 0,223, 0, 143
db 24,223, 0, 143
db 24,231, 0, 175
db 3 ;间隔段模型点数
db 47,207, 0, 175, 0, 48
db 8 ;过渡段模型点数
db 0, 207,0, 80
db 0, 207,0, 112
db 8, 223,0, 112
db 8, 223,0, 112
;-----------------------------------------------
;有限直线三段模型: Lh-2-3类型
;-----------------------------------------------
Linex_model_3s48y db 3 ;段数
db 12 ;基本段模型点数
db 8,239, 0, 143
db 24, 223, 0, 143
db 24, 223, 0, 143
db 24, 231, 0, 175
db 48, 207, 0, 175
db 48, 207, 0, 175
db 3 ;间隔段模型点数
db 48, 207, 0, 207, 0, 80
db 14 ;过渡段模型点数
db 0, 207, 0, 80
db 0, 207, 0, 80
db 0, 231, 0, 112
db 8, 223, 0, 112
db 8, 223, 0, 112
db 8, 223, 0, 112
db 8, 223, 0, 112
;-----------------------------------------------
;有限直线三段模型: Lh-2-3类型
;-----------------------------------------------
Linex_model_3s49y db 3 ;段数
db 16 ;基本段模型点数
db 8,239, 0,143
db 24,223, 0,143
db 24,223, 0,143
db 24,223, 0,143
db 24,223, 0, 175
db 48,207, 0,175
db 48,207, 0, 175
db 48,207, 0, 175
db 3 ;间隔段模型点数
db 48,207, 0,191, 0,80
db 16 ;过渡段模型点数
db 0, 207, 0,80
db 0, 207, 0,80
db 0, 207, 0,80
db 0, 207, 0,80
db 8, 223, 0, 112
db 8, 223, 0, 112
db 8, 223, 0, 112
db 8, 223, 0, 112
;-------------------------------------------
;Lh-3-4类直线模型检索表---X方向
;-------------------------------------------
Linex_model_x34 dd 12 ;首段斜线长度<=该值时
dq Linex_model_3s32x
dd -1 ;最后1项必须为-1
dq Linex_model_3s33x
;-------------------------------------------
;Lh-3-2类直线模型检索表---X方向
;-------------------------------------------
Linex_model_x32 dd 12 ;首段斜线长度>=该值时
dq Linex_model_3s35x
dd -1
dq Linex_model_3s34x
;-------------------------------------------
;Lh-2-3类直线模型检索表---X方向
;-------------------------------------------
Linex_model_x23 dd 2 ;首段斜线长度>=该值时
dq Linex_model_3s44x
dd 4
dq Linex_model_3s45x
dd 6
dq Linex_model_3s47x
dd 12
dq Linex_model_3s48x
dd -1
dq Linex_model_3s49x
;-------------------------------------------
;Lh-3-4类直线模型检索表---Y方向
;-------------------------------------------
Linex_model_y34 dd 12 ;首段斜线长度<=该值时
dq Linex_model_3s32y
dd -1 ;最后1项必须为-1
dq Linex_model_3s33y
;-------------------------------------------
;Lh-3-2类直线模型检索表---Y方向
;-------------------------------------------
Linex_model_y32 dd 12 ;首段斜线长度>=该值时
dq Linex_model_3s35y
dd -1
dq Linex_model_3s34y
;-------------------------------------------
;Lh-2-3类直线模型检索表---Y方向
;-------------------------------------------
Linex_model_y23 dd 2 ;首段斜线长度>=该值时
dq Linex_model_3s44y
dd 4
dq Linex_model_3s45y
dd 6
dq Linex_model_3s47y
dd 12
dq Linex_model_3s48y
dd -1
dq Linex_model_3s49y
.code
;==========================================================
;装入3段模型。
;入: pAlpha=ALPHA_LINE3S结构地址
; alpha=源颜色通量(透明度)
; pLine=GDIX_LINEINFO结构地址。
; xlen=直线特征值,即首个斜线段长度。
; 由Gdixline_GetNextSegmentX函数计算求得。
;出: RAX=NO
;==========================================================
Gdix_LoadLineAlpha_h23m proc pAlpha:QWORD,alpha:DWORD,\
pLine:QWORD,xlen:DWORD
mov eax,[r8.GDIX_LINEINFO].hSeg.alen1
shl ax,8
or eax,[r8.GDIX_LINEINFO].hSeg.alen2
test [r8.GDIX_LINEINFO].zFlag,GDIX_LINESTEPX
jnz ss_xx ;直线绘制方向为X
lea r10,Linex_model_y34
cmp ax,304h
jz ss_1
lea r10,Linex_model_y32
cmp ax,302h
jz ss_1
lea r10,Linex_model_y23
jmp ss_1
ss_xx:
lea r10,Linex_model_x34
cmp ax,304h
jz ss_1
lea r10,Linex_model_x32
cmp ax,302h
jz ss_1
lea r10,Linex_model_x23
jmp ss_1
ss_lp1:
add r10,12 ;4+8
ss_1:
cmp r9d,[r10]
jnbe ss_lp1
ss_ot1:
add r10,4
mov r10,[r10]
invoke Gdix_LoadLineAlpha,rcx,alpha,r10
ret
Gdix_LoadLineAlpha_h23m endp
;==================================================================
;使用有限模型绘制一段的对称斜线---由Gdix_DrawLine_h23m调用。
;入: hdc=DC句柄
; nlen=绘制长度。必是nbase的位数。
; ucolor=COLORREF颜色值
; rbx=GDIX_LINEINFO结构地址
; rsi=步进变量地址
; rdi=计算变量地址
; r12=ALPHA_DISTR3结构数组地址
;出: EAX=nlen
; rsi所指变量的递增量为nlen
;==================================================================
Gdix_DrawLine_h23mS proc hdc:QWORD,nlen:DWORD,ucolor:QWORD
LOCAL ss_r13:QWORD
LOCAL ss_n1:DWORD
mov ss_r13,r13
mov r13d,[rbx.GDIX_LINEINFO].hSeg.alen1
mov eax,edx
xor edx,edx
div r13d
mov ss_n1,eax ;水平子线段的段数
ss_lp1:
mov r13d,[rbx.GDIX_LINEINFO].hSeg.alen1
ss_lp2:
invoke GdixLine_SetPixel3,hdc,ucolor,r12 ;绘线段首点
mov eax,[rbx.GDIX_LINEINFO].xinc
add [rsi],eax ;X递增
add r12,SIZEOF ALPHA_DISTR3
dec r13d
jnz ss_lp2
mov ecx,[rbx.GDIX_LINEINFO].yinc
add [rdi],ecx
ss_nt1:
dec ss_n1
jg ss_lp1
ss_out:
mov eax,nlen
mov r13,ss_r13
ret
Gdix_DrawLine_h23mS endp
;==========================================================
;绘制一段斜线---由Gdix_DrawLine_h23m调用。
;入: hdc=DC句柄
; nlen=绘制长度。必是nbase的位数。
; ucolor=COLORREF颜色值
; rbx=GDIX_LINEINFO结构地址
; rsi=步进变量地址
; rdi=计算变量地址
; r12=ALPHA_DISTR3结构数组地址
;出: EAX=nlen
; rsi所指变量的递增量为nlen
;==========================================================
Gdix_DrawLine_h23mS24 proc hdc:QWORD,nlen:DWORD,ucolor:QWORD
LOCAL ss_r13:QWORD
LOCAL ss_n0:DWORD
LOCAL ss_n2:DWORD
LOCAL ss_4z1:GDIX_LINEMEAN
LOCAL ss_pAlpha:QWORD
mov ss_r13,r13
mov r13d,[rbx.GDIX_LINEINFO].hSeg.alen1 ;基本水平段长度
;---将长度转换为以"基本水平段长度为单位"的长度---
mov eax,edx
xor edx,edx
div r13d
test eax,eax
jnz ss_1
inc eax
ss_1:
mov ss_n0,eax ;水平子线段的段数
;---将斜线段数分为4等分---
invoke Line_Average,ADDR ss_4z1,ss_n0,4
ss_lp1:
;---取1/4段数---
invoke Gdixline_GetNextSegment,ADDR ss_4z1,ss_n0
test eax,eax
jnz ss_2
inc eax
ss_2:
;-------------------------------
;绘制水平(垂直)线的1/4段
;-------------------------------
sub ss_n0,eax
mov ss_n2,eax
;--------------------------
;绘制1/4段的首个子线段
;--------------------------
;---先绘制首2-3个起始点---
mov r13d,[rbx.GDIX_LINEINFO].hSeg.alen1 ;基本水平段长度
ss_lpb:
invoke GdixLine_SetPixel3,hdc,ucolor,r12 ;绘线段首点
mov eax,[rbx.GDIX_LINEINFO].xinc
add [rsi],eax
add r12,SIZEOF ALPHA_DISTR3
dec r13d
jnz ss_lpb
mov ss_pAlpha,r12 ;指向填充段颜色数据
jmp ss_nt2
;---绘1/4段的填充点---
ss_lp2:
mov r13d,[rbx.GDIX_LINEINFO].hSeg.alen1 ;基本水平段长度
mov r12,ss_pAlpha
ss_lpfill:
invoke GdixLine_SetPixel3,hdc,ucolor,r12 ;绘填充首点
mov eax,[rbx.GDIX_LINEINFO].xinc
add [rsi],eax
add r12,SIZEOF ALPHA_DISTR3
dec r13d
jnz ss_lpfill
ss_nt2:
mov ecx,[rbx.GDIX_LINEINFO].yinc
add [rdi],ecx
dec ss_n2
jg ss_lp2
;---下一个1/4段---
ss_nt1:
cmp ss_n0,0
jg ss_lp1
ss_out:
mov eax,nlen
mov r13,ss_r13
ret
Gdix_DrawLine_h23mS24 endp
;=======================================================
;绘制抗锯齿直线---使用三段模型
;入: hdc=DC句柄
; argb=ARGB颜色
; zFlag=0: 保留
; rbx=GDIX_LINEINFO结构。包含直线特征参数。
; rsi=指向步进变量(x或y)
; rdi=指向计算变量(y或x)
;出: EAX=1: 成功
;-----------------------------------------
;注: rbx,rsi,rdi,r12寄存器由调用者保护。
;-----------------------------
;适用条件: dx/dy =100/29 - 100/49
; 不包括dx/dy能整除的直线
;=======================================================
Gdix_DrawLine_h23m proc hdc:QWORD,argb:QWORD,zFlag:DWORD
LOCAL ss_alp:ALPHA_LINE3S
LOCAL ss_a1:ALPHA_DISTR3
LOCAL ss_n:DWORD
LOCAL ss_n2:DWORD
LOCAL ss_n1:DWORD
LOCAL ss_n1a:DWORD
LOCAL ss_slen1:DWORD
LOCAL ss_slen2:DWORD
LOCAL ss_call:QWORD
mov eax,[rbx.GDIX_LINEINFO].nlen ;步进长度
mov ss_n,eax
mov eax,[rbx.GDIX_LINEINFO].hSeg.alen1
mov ss_slen1,eax ;首个水平线段长度
mov eax,[rbx.GDIX_LINEINFO].hSeg.alen2
mov ss_slen2,eax ;过渡水平线段长度
;---取首个斜线段长度(连续的几个ss_slen1水平子线段总长度)---
invoke Gdixline_GetNextSegmentX,ADDR [rbx.GDIX_LINEINFO].hSeg,ss_n
sub ss_n,eax
mov ss_n1,eax
;---读入模型数据---
invoke Gdix_LoadLineAlphaEP,ADDR ss_alp,argb,rbx ;取起止端点模型
invoke Gdix_LoadLineAlpha_h23m,ADDR ss_alp,ss_alp.alpha,rbx,ss_n1 ;装入模型
lea rcx,Gdix_DrawLine_h23mS
cmp ss_n1,12
jbe ss_1
lea rcx,Gdix_DrawLine_h23mS24
ss_1:
mov ss_call,rcx
;---绘基本段起始点---
invoke Gdix_CopyAlpha,ADDR ss_a1,ss_alp.pAlpha1,1 ;保护首点
invoke Gdix_CopyAlpha,ss_alp.pAlpha1,ADDR ss_alp.b,1 ;更换起始点值
mov r12,ss_alp.pAlpha1
invoke ss_call,hdc,ss_n1,ss_alp.color
invoke Gdix_CopyAlpha,ss_alp.pAlpha1,ADDR ss_a1,1 ;恢复首点
jmp ss_nt
ss_lp1:
invoke Gdixline_GetNextSegmentX,ADDR [rbx.GDIX_LINEINFO].hSeg,ss_n
mov ss_n1a,eax
sub ss_n,eax
cmp eax,ss_n1
jbe ss_3
sub eax,ss_n1 ;减去基本段后的长度
ss_3:
;---绘制过渡段---
mov r12,ss_alp.pAlpha3
invoke ss_call,hdc,eax,ss_alp.color
sub ss_n1a,eax
jz ss_nt
;---绘制基本段---
mov r12,ss_alp.pAlpha1
invoke ss_call,hdc,ss_n1,ss_alp.color
ss_nt:
;---绘制间隔段---
mov r12,ss_alp.pAlpha2
mov eax,ss_slen2
cmp eax,ss_n
jbe ss_5
mov eax,ss_n
test eax,eax
jz ss_out
ss_5:
mov ss_n2,eax
sub ss_n,eax
ss_lp2:
invoke GdixLine_SetPixel3,hdc,ss_alp.color,r12
add r12,SIZEOF ALPHA_DISTR3
mov eax,[rbx.GDIX_LINEINFO].xinc
add [rsi],eax ;X递增
dec ss_n2
jnz ss_lp2
mov ecx,[rbx.GDIX_LINEINFO].yinc
add [rdi],ecx
cmp ss_n,0
jg ss_lp1
ss_out:
;---绘结尾点---
invoke GdixLine_SetPixel3,hdc,ss_alp.color,ADDR ss_alp.e
mov eax,1
ss_0:
ret
Gdix_DrawLine_h23m endp
;================================================
;Gdi抗锯齿直线绘制测试
;入: hdc=设备上下文句柄
;================================================
Gdpx_LineTest41 proc hdc:QWORD
;-------------------
;绘制dx>dy的3条直线
;-------------------
;---绘直线1---
invoke Gdix_DrawLine,hdc,10,10,210,68,0ffff0000h ;Gdi方法
invoke Gdip_DrawLine,hdc,10,20,210,78,0ff0000ffh ;Gdi+方法
;---绘直线2---
invoke Gdix_DrawLine,hdc,10,30,210,108,0ffff0000h ;Gdi方法
invoke Gdip_DrawLine,hdc,10,40,210,118,0ff0000ffh ;Gdi+方法
;---绘直线3---
invoke Gdix_DrawLine,hdc,10,50,210,148,0ffff0000h ;Gdi方法
invoke Gdip_DrawLine,hdc,10,60,210,158,0ff0000ffh ;Gdi+方法
;-------------------
;绘制dx<dy的3条直线
;-------------------
;---绘直线4---
invoke Gdix_DrawLine,hdc,10,90,68,290,0ffff0000h ;Gdi方法
invoke Gdip_DrawLine,hdc,20,90,78,290,0ff0000ffh ;Gdi+方法
;---绘直线5---
invoke Gdix_DrawLine,hdc,30,90,108,290,0ffff0000h ;Gdi方法
invoke Gdip_DrawLine,hdc,40,90,118,290,0ff0000ffh ;Gdi+方法
;---绘直线6---
invoke Gdix_DrawLine,hdc,50,90,148,290,0ffff0000h ;Gdi方法
invoke Gdip_DrawLine,hdc,60,90,158,290,0ff0000ffh ;Gdi+方法
ret
Gdpx_LineTest41 endp
直线绘制效果见图示10。
4. Ld-2t3类直线的抗锯齿绘制
绘制函数共有5个,其中测试函数1个:
(1)Gdix_LoadLineAlpha_d23m函数: 模型选择与装载。
(2)Gdix_DrawLine_d23mS函数: 使用有限模型绘制一段对称斜线。
(3)Gdix_DrawLine_d23mS24函数: 使用无限模型绘制一段对称斜线。
(4)Gdix_DrawLine_d23m函数: Lh-2t3直线绘制总函数。
(5)Gdpx_LineTest42函数: Lh-2t3直线绘制的测试函数。
.data
;-----------------------------------------------
;有限直线三段模型: Ld-2-3类型
;-----------------------------------------------
Linex_model_d3s51x db 3 ;段数
db 16 ;基本段模型点数
db 0, 223, 96, 159
db 0, 223, 96, 159
db 0, 215, 80, 175
db 0, 207, 80, 175
db 0, 207, 64, 191
db 0, 191, 64, 191
db 0, 191, 56, 199
db 0, 175, 48, 207
db 3 ;间隔段模型点数
db 0, 175, 40, 215, 159, 96
db 16 ;过渡段模型点数
db 32, 223, 159, 96
db 32, 223, 159, 96
db 24, 223, 143,112
db 24, 223, 143,112
db 24, 223, 128,127
db 16, 223, 128,127
db 16, 223, 120,135
db 8, 223, 112,143
;-----------------------------------------------
;有限直线三段模型: Ld-2-3类型
;-----------------------------------------------
Linex_model_d3s53x db 3 ;段数
db 6 ;基本段模型点数
db 8, 215, 96, 159
db 0, 215, 80, 175
db 0, 199, 64, 191
db 3 ;间隔段模型点数
db 0, 191, 48, 207, 175, 80
db 8 ;过渡段模型点数
db 32, 223, 159, 96
db 24, 223, 143,112
db 16, 223, 128,127
db 8, 223, 112,143
;-----------------------------------------------
;有限直线三段模型: Ld-2-3类型
;-----------------------------------------------
Linex_model_d3s54x db 3 ;段数
db 4 ;基本段模型点数
db 8, 215, 96, 159
db 0, 207, 72, 183
db 3 ;间隔段模型点数
db 0, 191, 56, 199, 175, 80
db 6 ;过渡段模型点数
db 32, 223, 143,112
db 24, 223, 128,127
db 16, 215, 112,143
;-----------------------------------------------
;有限直线三段模型: Ld-2-3类型
;-----------------------------------------------
Linex_model_d3s56x db 3 ;段数
db 2 ;基本段模型点数
db 8,215, 88,167
db 3 ;间隔段模型点数
db 0, 199, 56, 199, 175, 80
db 4 ;过渡段模型点数
db 32, 215, 135,120
db 16, 223, 112,143
;-----------------------------------------------
;无限直线三段模型: Ld-3-2类型
;-----------------------------------------------
Linex_model_d3s66x db 3 ;段数
db 24 ;基本段模型点数
db 8, 215, 72, 183, 159, 96
db 16, 215, 72, 183, 159, 96
db 16, 215, 72, 183, 159, 96
db 16, 215, 72, 183, 159, 96
db 16, 215, 72, 183, 183, 72
db 24, 215, 96, 159, 183, 72
db 24, 215, 96, 159, 183, 72
db 24, 215, 96, 159, 183, 72
db 2 ;间隔段模型点数
db 24, 215, 96, 159
db 24 ;过渡段模型点数
db 0, 183, 32, 215, 120, 135
db 0, 199, 40, 207, 120, 135
db 0, 199, 40, 207, 120, 135
db 0, 199, 40, 207, 120, 135
db 0, 199, 40, 207, 128, 127
db 8, 207, 56, 199, 135, 120
db 8, 207, 56, 199, 135, 120
db 8, 207, 56, 199, 135, 120
;-----------------------------------------------
;无限直线三段模型: Ld-3-4类型
;-----------------------------------------------
Linex_model_d3s67x db 3 ;段数
db 24 ;基本段模型点数
db 16 , 199, 56, 199, 135, 120
db 8, 207, 56, 199, 135, 120
db 8, 207, 56, 199, 135, 120
db 8, 207, 56, 199, 135, 120
db 8, 207, 48, 199, 120, 135
db 0, 199, 40, 207, 120, 135
db 0, 199, 40, 207, 120, 135
db 0, 199, 40, 207, 120, 135
db 4 ;间隔段模型点数
db 0, 199, 40, 207, 104, 151, 183, 72
db 24 ;过渡段模型点数
db 24, 215, 96, 159, 183, 72
db 24, 215, 96, 159, 183, 72
db 24, 215, 96, 159, 183, 72
db 24, 215, 96, 159, 183, 72
db 16, 215, 72, 183, 159, 96
db 16, 215, 72, 183, 159, 96
db 16, 215, 72, 183, 159, 96
db 16, 215, 72, 183, 159, 96
;-----------------------------------------------
;有限直线三段模型: Ld-2-3类型
;-----------------------------------------------
Linex_model_d3s51y db 3 ;段数
db 16 ;基本段模型点数
db 24, 223, 112, 143
db 8, 223, 112, 143
db 8, 223, 112, 143
db 8, 223, 112, 143
db 8, 223, 88, 167
db 0, 207, 80, 175
db 0, 207, 80, 175
db 0, 207, 80, 175
db 3 ;间隔段模型点数
db 0, 207, 72, 183, 175, 80
db 16 ;过渡段模型点数
db 48, 207, 175, 80
db 48, 207, 175, 80
db 48, 207, 175, 80
db 48, 207, 175, 80
db 48, 207, 151, 104
db 24, 223, 143, 112
db 24, 223, 143, 112
db 24, 223, 143, 112
;-----------------------------------------------
;有限直线三段模型: Ld-2-3类型
;-----------------------------------------------
Linex_model_d3s53y db 3 ;段数
db 6 ;基本段模型点数
db 24, 223, 112, 143
db 8, 223, 112, 143
db 8, 215, 80, 175
db 3 ;间隔段模型点数
db 0, 207, 80, 175, 207, 48
db 8 ;过渡段模型点数
db 48, 207, 175, 80
db 48, 207, 175, 80
db 32, 215, 143, 112
db 24, 223, 143, 112
;-----------------------------------------------
;有限直线三段模型: Ld-2-3类型
;-----------------------------------------------
Linex_model_d3s54y db 3 ;段数
db 4 ;基本段模型点数
db 24, 223, 112, 143
db 8, 223, 104, 151
db 3 ;间隔段模型点数
db 0, 207, 80, 175, 207, 48
db 6 ;过渡段模型点数
db 48, 207, 175, 80
db 48, 207, 143, 112
db 24, 223, 143, 112
;-----------------------------------------------
;有限直线三段模型: Ld-2-3类型
;-----------------------------------------------
Linex_model_d3s56y db 3 ;段数
db 2 ;基本段模型点数
db 24, 215, 112, 143
db 3 ;间隔段模型点数
db 8, 215, 80, 175, 199, 56
db 4 ;过渡段模型点数
db 48, 207, 175, 80
db 24, 223, 143, 112
;-----------------------------------------------
;无限直线三段模型: Ld-3-2类型
;-----------------------------------------------
Linex_model_d3s66y db 3 ;段数
db 24 ;基本段模型点数
db 24, 215, 96, 159, 183, 72
db 24, 215, 96, 159, 183, 72
db 24, 215, 104, 151, 191, 64
db 32, 215, 104, 151, 191, 64
db 32, 215, 112, 143, 199, 56
db 40, 207, 120, 135, 199, 56
db 40, 207, 120, 135, 207, 48
db 48, 199, 128, 127, 167, 88
db 2 ;间隔段模型点数
db 48, 199, 128, 127
db 24 ;过渡段模型点数
db 8, 199, 56, 199, 135, 120
db 8, 207, 56, 199, 135, 120
db 8, 207, 56, 199, 151, 104
db 8, 215, 64, 191, 151, 104
db 8, 215, 64, 191, 159, 96
db 16, 215, 72, 183, 159, 96
db 16, 215, 72, 183, 159, 96
db 24, 207, 88, 167, 167, 88
;-----------------------------------------------
;无限直线三段模型: Ld-3-4类型
;-----------------------------------------------
Linex_model_d3s67y db 3 ;段数
db 24 ;基本段模型点数
db 24, 215, 88, 167, 167, 88
db 24, 207, 88, 167, 167, 88
db 24, 207, 80, 175, 159, 96
db 16, 215, 72, 183, 159, 96
db 16, 215, 72, 183, 151, 104
db 8, 215, 64, 191, 151, 104
db 8, 215, 64, 191, 143, 112
db 8, 207, 56, 199, 135, 120
db 4 ;间隔段模型点数
db 8, 207, 56, 199, 135, 120, 199, 48
db 24 ;过渡段模型点数
db 48, 199, 128, 127, 199, 48
db 48, 199, 128, 127, 199, 48
db 40, 207, 120, 135, 199, 56
db 40, 207, 120, 135, 199, 56
db 32, 215, 104, 151, 191, 64
db 32, 215, 104, 151, 191, 64
db 32, 207, 96, 159, 183, 72
db 24, 215, 96, 159, 183, 72
;-------------------------------------------
;Ld-2-3类直线模型检索表---X方向
;-------------------------------------------
Linex_model_dx23 dd 2 ;首段斜线长度<=该值时
dq Linex_model_d3s56x
dd 4
dq Linex_model_d3s54x
dd 6
dq Linex_model_d3s53x
dd -1 ;最后1项必须为-1
dq Linex_model_d3s51x
;-------------------------------------------
;Ld-3-2类直线模型检索表---X方向
;-------------------------------------------
Linex_model_dx32 dd -1 ;首段斜线长度<=该值时
dq Linex_model_d3s66x
;-------------------------------------------
;Ld-3-4类直线模型检索表---X方向
;-------------------------------------------
Linex_model_dx34 dd -1 ;首段斜线长度<=该值时
dq Linex_model_d3s67x
;-------------------------------------------
;Ld-2-3类直线模型检索表---Y方向
;-------------------------------------------
Linex_model_dy23 dd 2 ;首段斜线长度<=该值时
dq Linex_model_d3s56y
dd 4
dq Linex_model_d3s54y
dd 6
dq Linex_model_d3s53y
dd -1 ;最后1项必须为-1
dq Linex_model_d3s51y
;-------------------------------------------
;Ld-3-2类直线模型检索表---Y方向
;-------------------------------------------
Linex_model_dy32 dd -1
dq Linex_model_d3s66y
;-------------------------------------------
;Ld-3-4类直线模型检索表---Y方向
;-------------------------------------------
Linex_model_dy34 dd -1
dq Linex_model_d3s67y
.code
;==========================================================
;装入3段模型。
;入: pAlpha=ALPHA_LINE3S结构地址
; alpha=源颜色通量(透明度)
; pLine=GDIX_LINEINFO结构地址。
; xlen=直线特征值,即首个斜线段长度。
; 由Gdixline_GetNextSegmentX函数计算求得。
;出: RAX=NO
;==========================================================
Gdix_LoadLineAlpha_d23m proc pAlpha:QWORD,alpha:DWORD,\
pLine:QWORD,xlen:DWORD
mov eax,[r8.GDIX_LINEINFO].dSeg.alen1
shl ax,8
or eax,[r8.GDIX_LINEINFO].dSeg.alen2
test [r8.GDIX_LINEINFO].zFlag,GDIX_LINESTEPX
jnz ss_xx ;直线绘制方向为X
lea r10,Linex_model_dy34
cmp ax,304h
jz ss_1
lea r10,Linex_model_dy32
cmp ax,302h
jz ss_1
lea r10,Linex_model_dy23
jmp ss_1
ss_xx:
lea r10,Linex_model_dx34
cmp ax,304h
jz ss_1
lea r10,Linex_model_dx32
cmp ax,302h
jz ss_1
lea r10,Linex_model_dx23
jmp ss_1
ss_lp1:
add r10,12 ;4+8
ss_1:
cmp r9d,[r10]
jnbe ss_lp1
ss_ot1:
add r10,4
mov r10,[r10]
invoke Gdix_LoadLineAlpha,rcx,alpha,r10
ret
Gdix_LoadLineAlpha_d23m endp
;==================================================================
;绘制一段斜线---由Gdix_DrawLine_d23m调用。
;入: hdc=DC句柄
; nlen=绘制长度。必是nbase的位数。
; ucolor=COLORREF颜色值
; rbx=GDIX_LINEINFO结构地址
; rsi=步进变量地址
; rdi=计算变量地址
; r12=ALPHA_DISTR3结构数组地址
;出: EAX=nlen
; rsi所指变量的递增量为nlen
;==================================================================
Gdix_DrawLine_d23mS proc hdc:QWORD,nlen:DWORD,ucolor:QWORD
LOCAL ss_r13:QWORD
LOCAL ss_n1:DWORD
mov ss_r13,r13
mov r13d,[rbx.GDIX_LINEINFO].dSeg.alen1
mov eax,edx
xor edx,edx
div r13d
mov ss_n1,eax ;水平子线段的段数
ss_lp1:
mov r13d,[rbx.GDIX_LINEINFO].dSeg.alen1
ss_lp2:
invoke GdixLine_SetPixel3,hdc,ucolor,r12 ;绘线段首点
mov eax,[rbx.GDIX_LINEINFO].xinc
add [rsi],eax ;X递增
mov ecx,[rbx.GDIX_LINEINFO].yinc
add [rdi],ecx
add r12,SIZEOF ALPHA_DISTR3
dec r13d
jnz ss_lp2
mov ecx,[rbx.GDIX_LINEINFO].yinc
sub [rdi],ecx
ss_nt1:
dec ss_n1
jg ss_lp1
ss_out:
mov eax,nlen
mov r13,ss_r13
ret
Gdix_DrawLine_d23mS endp
;==========================================================
;绘制一段斜线---由Gdix_DrawLine_d23m调用。
;入: hdc=DC句柄
; nlen=绘制长度。必是nbase的位数。
; ucolor=COLORREF颜色值
; rbx=GDIX_LINEINFO结构地址
; rsi=步进变量地址
; rdi=计算变量地址
; r12=ALPHA_DISTR3结构数组地址
;出: EAX=nlen
; rsi所指变量的递增量为nlen
;==========================================================
Gdix_DrawLine_d23mS24 proc hdc:QWORD,nlen:DWORD,ucolor:QWORD
LOCAL ss_r13:QWORD
LOCAL ss_n0:DWORD
LOCAL ss_n2:DWORD
LOCAL ss_4z1:GDIX_LINEMEAN
LOCAL ss_pAlpha:QWORD
mov ss_r13,r13
mov r13d,[rbx.GDIX_LINEINFO].dSeg.alen1 ;基本水平段长度
;---将长度转换为以"基本水平段长度为单位"的长度---
mov eax,edx
xor edx,edx
div r13d
test eax,eax
jnz ss_1
inc eax
ss_1:
mov ss_n0,eax ;水平子线段的段数
;---将斜线段数分为4等分---
invoke Line_Average,ADDR ss_4z1,ss_n0,4
ss_lp1:
;---取1/4段数---
invoke Gdixline_GetNextSegment,ADDR ss_4z1,ss_n0
test eax,eax
jnz ss_2
inc eax
ss_2:
;-------------------------------
;绘制水平(垂直)线的1/4段
;-------------------------------
sub ss_n0,eax
mov ss_n2,eax
;--------------------------
;绘制1/4段的首个子线段
;--------------------------
;---先绘制首2-3个起始点---
mov r13d,[rbx.GDIX_LINEINFO].dSeg.alen1 ;基本水平段长度
ss_lpb:
invoke GdixLine_SetPixel3,hdc,ucolor,r12 ;绘线段首点
mov eax,[rbx.GDIX_LINEINFO].xinc
add [rsi],eax
mov ecx,[rbx.GDIX_LINEINFO].yinc
add [rdi],ecx
add r12,SIZEOF ALPHA_DISTR3
dec r13d
jnz ss_lpb
mov ss_pAlpha,r12 ;指向填充段颜色数据
jmp ss_nt2
;---绘1/4段的填充点---
ss_lp2:
mov r13d,[rbx.GDIX_LINEINFO].dSeg.alen1 ;基本水平段长度
mov r12,ss_pAlpha
ss_lpfill:
invoke GdixLine_SetPixel3,hdc,ucolor,r12 ;绘填充首点
mov eax,[rbx.GDIX_LINEINFO].xinc
add [rsi],eax
mov ecx,[rbx.GDIX_LINEINFO].yinc
add [rdi],ecx
add r12,SIZEOF ALPHA_DISTR3
dec r13d
jnz ss_lpfill
ss_nt2:
mov ecx,[rbx.GDIX_LINEINFO].yinc
sub [rdi],ecx
dec ss_n2
jg ss_lp2
;---下一个1/4段---
ss_nt1:
cmp ss_n0,0
jg ss_lp1
ss_out:
mov eax,nlen
mov r13,ss_r13
ret
Gdix_DrawLine_d23mS24 endp
;=======================================================
;绘制抗锯齿直线---使用三段模型
;入: hdc=DC句柄
; argb=ARGB颜色
; zFlag=0: 保留
; rbx=GDIX_LINEINFO结构。包含直线特征参数。
; rsi=指向步进变量(x或y)
; rdi=指向计算变量(y或x)
;出: EAX=1: 成功
;-----------------------------------------
;注: rbx,rsi,rdi,r12寄存器由调用者保护。
;-----------------------------
;适用条件: dx/dy =100/51 - 100/71
; 不包括dx/dy能整除的直线
;=======================================================
Gdix_DrawLine_d23m proc hdc:QWORD,argb:QWORD,zFlag:DWORD
LOCAL ss_alp:ALPHA_LINE3S
LOCAL ss_a1:ALPHA_DISTR3
LOCAL ss_n:DWORD
LOCAL ss_n2:DWORD
LOCAL ss_n1:DWORD
LOCAL ss_n1a:DWORD
LOCAL ss_slen1:DWORD
LOCAL ss_slen2:DWORD
LOCAL ss_call:QWORD
mov eax,[rbx.GDIX_LINEINFO].nlen ;步进长度
mov ss_n,eax
mov eax,[rbx.GDIX_LINEINFO].dSeg.alen1
mov ss_slen1,eax ;首个水平线段长度
mov eax,[rbx.GDIX_LINEINFO].dSeg.alen2
mov ss_slen2,eax ;过渡水平线段长度
;---取首个斜线段长度(连续的几个ss_slen1水平子线段总长度)---
invoke Gdixline_GetNextSegmentX,ADDR [rbx.GDIX_LINEINFO].dSeg,ss_n
sub ss_n,eax
mov ss_n1,eax
;---读入模型数据---
invoke Gdix_LoadLineAlphaEP,ADDR ss_alp,argb,rbx ;取起止端点模型
invoke Gdix_LoadLineAlpha_d23m,ADDR ss_alp,ss_alp.alpha,rbx,ss_n1 ;装入模型
lea rcx,Gdix_DrawLine_d23mS
cmp ss_n1,12
jbe ss_1
lea rcx,Gdix_DrawLine_d23mS24
ss_1:
mov ss_call,rcx
;---绘基本段起始点---
invoke Gdix_CopyAlpha,ADDR ss_a1,ss_alp.pAlpha1,1 ;保护首点
invoke Gdix_CopyAlpha,ss_alp.pAlpha1,ADDR ss_alp.b,1 ;更换起始点值
mov r12,ss_alp.pAlpha1
invoke ss_call,hdc,ss_n1,ss_alp.color
invoke Gdix_CopyAlpha,ss_alp.pAlpha1,ADDR ss_a1,1 ;恢复首点+
jmp ss_nt
ss_lp1:
invoke Gdixline_GetNextSegmentX,ADDR [rbx.GDIX_LINEINFO].dSeg,ss_n
mov ss_n1a,eax
sub ss_n,eax
cmp eax,ss_n1
jbe ss_3
sub eax,ss_n1 ;减去基本段后的长度
ss_3:
;---绘制过渡段---
mov r12,ss_alp.pAlpha3
invoke ss_call,hdc,eax,ss_alp.color
sub ss_n1a,eax
jz ss_nt
;---绘制基本段---
mov r12,ss_alp.pAlpha1
invoke ss_call,hdc,ss_n1,ss_alp.color
ss_nt:
;---绘制间隔段---
mov r12,ss_alp.pAlpha2
mov eax,ss_slen2
cmp eax,ss_n
jbe ss_5
mov eax,ss_n
test eax,eax
jz ss_out
ss_5:
mov ss_n2,eax
sub ss_n,eax
ss_lp2:
invoke GdixLine_SetPixel3,hdc,ss_alp.color,r12
add r12,SIZEOF ALPHA_DISTR3
mov eax,[rbx.GDIX_LINEINFO].xinc
add [rsi],eax ;X递增
mov ecx,[rbx.GDIX_LINEINFO].yinc
add [rdi],ecx
dec ss_n2
jnz ss_lp2
mov ecx,[rbx.GDIX_LINEINFO].yinc
sub [rdi],ecx
cmp ss_n,0
jg ss_lp1
ss_out:
;---绘结尾点---
invoke GdixLine_SetPixel3,hdc,ss_alp.color,ADDR ss_alp.e
mov eax,1
ss_0:
ret
Gdix_DrawLine_d23m endp
;================================================
;Gdi抗锯齿直线绘制测试
;入: hdc=设备上下文句柄
;================================================
Gdpx_LineTest5 proc hdc:QWORD
;-------------------
;绘制dx>dy的3条直线
;-------------------
;---绘直线1---
invoke Gdix_DrawLine,hdc,10,10,210,112,0ffff0000h ;Gdi方法
invoke Gdip_DrawLine,hdc,10,20,210,122,0ff0000ffh ;Gdi+方法
;---绘直线2---
invoke Gdix_DrawLine,hdc,10,30,210,152,0ffff0000h ;Gdi方法
invoke Gdip_DrawLine,hdc,10,40,210,162,0ff0000ffh ;Gdi+方法
;---绘直线3---
invoke Gdix_DrawLine,hdc,10,50,210,192,0ffff0000h ;Gdi方法
invoke Gdip_DrawLine,hdc,10,60,210,202,0ff0000ffh ;Gdi+方法
;-------------------
;绘制dx<dy的3条直线
;-------------------
;---绘直线4---
invoke Gdix_DrawLine,hdc,10,70,192,270,0ffff0000h ;Gdi方法
invoke Gdip_DrawLine,hdc,10,80,192,280,0ff0000ffh ;Gdi+方法
;---绘直线5---
invoke Gdix_DrawLine,hdc,10,90,152,290,0ffff0000h ;Gdi方法
invoke Gdip_DrawLine,hdc,10,100,152,300,0ff0000ffh ;Gdi+方法
;---绘直线6---
invoke Gdix_DrawLine,hdc,10,110,112,310,0ffff0000h ;Gdi方法
invoke Gdip_DrawLine,hdc,10,120,112,320,0ff0000ffh ;Gdi+方法
ret
Gdpx_LineTest5 endp
直线绘制效果见图示11。
至此全部类型直线的抗锯齿绘制方法已介绍完,下一篇将介绍如何提高绘图速度。
(未完待续)