Skip to content

Commit 07eff93

Browse files
committed
Update fximg.utils.ts
1 parent 56898be commit 07eff93

File tree

1 file changed

+19
-135
lines changed

1 file changed

+19
-135
lines changed

fximg.utils.ts

Lines changed: 19 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)