20241230-抗锯齿直线绘制方法(四)

抗锯齿直线绘制方法(四)

到目前为止,还有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。
在这里插入图片描述

至此全部类型直线的抗锯齿绘制方法已介绍完,下一篇将介绍如何提高绘图速度。

(未完待续)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值