@@ -83,8 +83,8 @@ namespace helper {
8383 const srcH = fximgHeightOf ( src ) ;
8484
8585 // คำนวณ scale factor (จริง ๆ คือ ratio)
86- const scaleX = wSrc / wSrc ;
87- const scaleY = hSrc / hSrc ;
86+ const scaleX = wSrc / wDst ;
87+ const scaleY = hSrc / hDst ;
8888
8989 // Clip rectangle ทั้ง src และ dst (เหมือนมาตรฐาน)
9090 let clipWDst = wDst ;
@@ -106,153 +106,37 @@ namespace helper {
106106
107107 // ถ้า transparent=false และ check=false → อาจ optimize เร็วขึ้น แต่เวอร์ชันนี้ทำแบบ general ก่อน
108108
109- const rowBuf = pins . createBuffer ( clipHDst ) ; // buffer ขนาดสูงสุดที่ copy จริง
110- const dstRow = pins . createBuffer ( dstH ) ; // buffer เต็ม column ของ dst
109+ const srcRow = pins . createBuffer ( clipHSrc ) ; // buffer ขนาดสูงสุดที่ copy จริง
110+ const dstRow = pins . createBuffer ( clipHDst ) ; // buffer เต็ม column ของ dst
111111
112112 let anyChange = false ;
113113
114- // วนทุกพิกเซลปลายทาง (nearest neighbor)
115- for ( let y = 0 ; y < dh ; y ++ ) {
116- const srcY_float = sy + y * scaleY ;
117- const srcY = Math . floor ( srcY_float + 0.5 ) ; // หรือ Math.round() ก็ได้
114+ for ( let x = 0 ; x < clipWDst ; x ++ ) {
115+ const sx_f = xSrc + x * scaleX ;
116+ const sx = Math . floor ( sx_f + 0.5 ) ; // หรือ Math.round() ก็ได้
117+
118+ if ( sx < 0 || sx >= clipWSrc ) continue ;
118119
119- if ( srcY < 0 || srcY >= srcH ) continue ;
120+ fximgGetRows ( src , sx , srcRow , srcRow . length ) ;
121+ fximgGetRows ( dst , xDst + x , dstRow , dstRow . length ) ;
120122
121- for ( let x = 0 ; x < dw ; x ++ ) {
122- const srcX_float = sx + x * scaleX ;
123- const srcX = Math . floor ( srcX_float + 0.5 ) ;
123+ for ( let y = 0 ; y < clipHDst ; y ++ ) {
124+ const sy_f = ySrc + y * scaleY ;
125+ const sy = Math . floor ( sy_f + 0.5 ) ;
124126
125- if ( srcX < 0 || srcX >= srcW ) continue ;
127+ if ( sy < 0 || sy >= clipHSrc ) continue ;
126128
127- const pixel = fximgGetPixel ( src , srcX , srcY ) ; // ต้องมี helper นี้ไหม? ถ้ายังไม่มีก็ implement ง่าย
129+ const pixel = srcRow [ sy ] ; // ต้องมี helper นี้ไหม? ถ้ายังไม่มีก็ implement ง่าย
128130
129131 if ( transparent && pixel < 1 ) continue ;
130132
131- const old = fximgGetPixel ( dst , dx + x , dy + y ) ;
133+ const old = dstRow [ yDst + y ] ;
132134 if ( old === pixel ) continue ;
133135
134- fximgSetPixel ( dst , dx + x , dy + y , pixel ) ;
136+ dstRow [ yDst ] = pixel ;
135137 anyChange = true ;
136138 }
137- }
138-
139- return check ? anyChange : true ;
140- }
141-
142- // 1. drawLine (Bresenham ปรับปรุงตามที่ภัทรแนะนำ - ใช้ sx/sy ตรวจทิศทาง ไม่เช็คจุดเริ่ม=จุดจบ)
143- export function fximgDrawLine ( fxpic : Buffer , x0 : number , y0 : number , x1 : number , y1 : number , color : number , idx ?: number ) {
144- if ( fximgRoCheck ( fxpic ) ) return ;
145- color &= 0xF ;
146- if ( x0 === x1 && y0 === y1 ) { fximgSetPixel ( fxpic , x0 , y0 , color , idx ) ; return ; }
147- idx = idx || 0 ;
148- if ( fximgIsOutOfRange ( idx , fximgLengthOf ( fxpic , ) ) ) return ;
149- const w = fximgWidthOf ( fxpic ) ;
150- const h = fximgHeightOf ( fxpic ) ;
151- const iw = idx * w ;
152- if ( ( x0 < 0 && x1 < 0 ) || ( x0 >= w && x1 >= w ) ||
153- ( y0 < 0 && y1 < 0 ) || ( y0 >= h && y1 >= h ) ) return ;
154-
155- let dx = Math . abs ( x1 - x0 ) ;
156- let dy = Math . abs ( y1 - y0 ) ;
157- let sx = Math . clamp ( - 1 , 1 , x1 - x0 ) ;
158- let sy = Math . clamp ( - 1 , 1 , y1 - y0 ) ;
159- let err = dx - dy ;
160-
161- while ( 1 ) {
162- if ( ( ( sx < 0 && x0 < 0 ) || ( sx > 0 && x0 >= w ) && sx !== 0 ) ||
163- ( ( sy < 0 && y0 < 0 ) || ( sy > 0 && y0 >= h ) && sy !== 0 ) ) break ;
164- const buf = pins . createBuffer ( hSrc ) ;
165-
166- // ดึง column จาก src (เริ่มจาก y=0 ของ buf)
167- fximgGetRows ( src , xSrc , buf , hSrc ) ;
168-
169- if ( yDst === 0 ) {
170- // Fast path: วางตรงหัว column
171- fximgSetRows ( dst , xDst , buf , hSrc ) ;
172- } else {
173- // Slow path: merge กับข้อมูลเดิมที่ yDst
174- const dstBuf = pins . createBuffer ( dstFullH ) ;
175- fximgGetRows ( dst , xDst , dstBuf , dstFullH ) ;
176-
177- // copy เข้าไปที่ offset yDst
178- for ( let i = 0 ; i < hSrc ; i ++ ) {
179- dstBuf [ yDst + i ] = buf [ i ] ;
180- }
181-
182- fximgSetRows ( dst , xDst , dstBuf , dstFullH ) ;
183- }
184- }
185-
186- export function fximgBlit (
187- dst : Buffer ,
188- xDst : number , yDst : number ,
189- wDst : number , hDst : number ,
190- src : Buffer ,
191- xSrc : number , ySrc : number ,
192- wSrc : number , hSrc : number ,
193- transparent ?: boolean ,
194- check ?: boolean
195- ) : boolean {
196- if ( fximgRoCheck ( dst ) ) return false ;
197-
198- const dstW = fximgWidthOf ( dst ) ;
199- const dstH = fximgHeightOf ( dst ) ;
200- const srcW = fximgWidthOf ( src ) ;
201- const srcH = fximgHeightOf ( src ) ;
202-
203- // คำนวณ scale factor (จริง ๆ คือ ratio)
204- const scaleX = wSrc / wDst ;
205- const scaleY = hSrc / hdst ;
206-
207- // Clip rectangle ทั้ง src และ dst (เหมือนมาตรฐาน)
208- let clipWDst = wDst ;
209- let clipHDst = hDst ;
210- let clipWSrc = wSrc ;
211- let clipHSrc = hSrc ;
212-
213- if ( xDst < 0 ) { clipWDst += xDst ; clipWSrc += xDst ; xSrc -= xDst ; xDst = 0 ; }
214- if ( yDst < 0 ) { clipHDst += yDst ; clipHSrc += yDst ; ySrc -= yDst ; yDst = 0 ; }
215- if ( xDst + clipWDst > dstW ) clipWDst = dstW - xDst ;
216- if ( yDst + clipHDst > dstH ) clipHDst = dstH - yDst ;
217-
218- if ( xSrc < 0 ) { clipWDst += xSrc ; clipWSrc += xSrc ; xSrc = 0 ; }
219- if ( ySrc < 0 ) { clipHDst += ySrc ; clipHSrc += ySrc ; ySrc = 0 ; }
220- if ( xSrc + clipWSrc > srcW ) clipWSrc = srcW - xSrc ;
221- if ( ySrc + clipHSrc > srcH ) clipHSrc = srcH - ySrc ;
222-
223- if ( clipWDst <= 0 || clipHDst <= 0 || clipWSrc <= 0 || clipHSrc <= 0 ) return false ;
224-
225- // ถ้า transparent=false และ check=false → อาจ optimize เร็วขึ้น แต่เวอร์ชันนี้ทำแบบ general ก่อน
226-
227- const rowBuf = pins . createBuffer ( clipHDst ) ; // buffer ขนาดสูงสุดที่ copy จริง
228- const dstRow = pins . createBuffer ( dstH ) ; // buffer เต็ม column ของ dst
229-
230- let anyChange = false ;
231-
232- for ( let dx = 0 ; dx < clipWDst ; dx ++ ) {
233- // วนทุกพิกเซลปลายทาง (nearest neighbor)
234- for ( let y = 0 ; y < dh ; y ++ ) {
235- const srcY_float = sy + y * scaleY ;
236- const srcY = Math . floor ( srcY_float + 0.5 ) ; // หรือ Math.round() ก็ได้
237-
238- if ( srcY < 0 || srcY >= srcH ) continue ;
239-
240- for ( let x = 0 ; x < dw ; x ++ ) {
241- const srcX_float = sx + x * scaleX ;
242- const srcX = Math . floor ( srcX_float + 0.5 ) ;
243-
244- if ( srcX < 0 || srcX >= srcW ) continue ;
245-
246- const pixel = fximgGetPixel ( src , srcX , srcY ) ; // ต้องมี helper นี้ไหม? ถ้ายังไม่มีก็ implement ง่าย
247-
248- if ( transparent && pixel < 1 ) continue ;
249-
250- const old = fximgGetPixel ( dst , dx + x , dy + y ) ;
251- if ( old === pixel ) continue ;
252-
253- fximgSetPixel ( dst , dx + x , dy + y , pixel ) ;
254- anyChange = true ;
255- }
139+ fximgSetRows ( dst , xDst + x , dstRow , dstRow . length ) ;
256140 }
257141
258142 return check ? anyChange : true ;
0 commit comments