2 // This file is based in part on modified source code from `WDL/eel2/eel_lice.h`.
3 // The zlib license from the WDL applies to this source file.
5 //------------------------------------------------------------------------------
7 // Copyright (C) 2021 and later Jean Pierre Cimalando
8 // Copyright (C) 2005 and later Cockos Incorporated
11 // Portions copyright other contributors, see each source file for more information
13 // This software is provided 'as-is', without any express or implied
14 // warranty. In no event will the authors be held liable for any damages
15 // arising from the use of this software.
17 // Permission is granted to anyone to use this software for any purpose,
18 // including commercial applications, and to alter it and redistribute it
19 // freely, subject to the following restrictions:
21 // 1. The origin of this software must not be misrepresented; you must not
22 // claim that you wrote the original software. If you use this software
23 // in a product, an acknowledgment in the product documentation would be
24 // appreciated but is not required.
25 // 2. Altered source versions must be plainly marked as such, and must not be
26 // misrepresented as being the original software.
27 // 3. This notice may not be removed or altered from any source distribution.
29 // SPDX-License-Identifier: Zlib
33 #include "ysfx_api_eel.hpp"
34 #include "WDL/wdlstring.h"
35 #include "WDL/wdlcstring.h"
36 #include "WDL/wdlutf8.h"
42 // help clangd to figure things out
43 #if defined(__CLANGD__)
44 # include "ysfx_api_gfx.cpp"
47 #define EEL_LICE_GET_CONTEXT(opaque) ((opaque) ? ((ysfx_t *)(opaque))->gfx.state->lice.get() : nullptr)
49 //------------------------------------------------------------------------------
51 #define LICE_FUNCTION_VALID(x) (sizeof(int) > 0)
53 static HDC
LICE__GetDC(LICE_IBitmap
*bm
)
57 static int LICE__GetWidth(LICE_IBitmap
*bm
)
59 return bm
->getWidth();
61 static int LICE__GetHeight(LICE_IBitmap
*bm
)
63 return bm
->getHeight();
65 static void LICE__Destroy(LICE_IBitmap
*bm
)
69 static void LICE__SetFromHFont(LICE_IFont
* ifont
, HFONT font
, int flags
)
71 if (ifont
) ifont
->SetFromHFont(font
,flags
);
73 static LICE_pixel
LICE__SetTextColor(LICE_IFont
* ifont
, LICE_pixel color
)
75 if (ifont
) return ifont
->SetTextColor(color
);
78 static void LICE__SetTextCombineMode(LICE_IFont
* ifont
, int mode
, float alpha
)
80 if (ifont
) ifont
->SetCombineMode(mode
, alpha
);
82 static int LICE__DrawText(LICE_IFont
* ifont
, LICE_IBitmap
*bm
, const char *str
, int strcnt
, RECT
*rect
, UINT dtFlags
)
84 if (ifont
) return ifont
->DrawText(bm
, str
, strcnt
, rect
, dtFlags
);
89 static LICE_IFont
*LICE_CreateFont()
91 return new LICE_CachedFont();
93 static void LICE__DestroyFont(LICE_IFont
*bm
)
97 static bool LICE__resize(LICE_IBitmap
*bm
, int w
, int h
)
99 return bm
->resize(w
,h
);
102 static LICE_IBitmap
*__LICE_CreateBitmap(int mode
, int w
, int h
)
104 if (mode
==1) return new LICE_SysBitmap(w
,h
);
105 return new LICE_MemBitmap(w
,h
);
112 eel_lice_state(NSEEL_VMCTX vm
, void *ctx
, int image_slots
, int font_slots
);
115 LICE_IBitmap
*m_framebuffer
, *m_framebuffer_extra
;
116 int m_framebuffer_dirty
;
117 WDL_TypedBuf
<LICE_IBitmap
*> m_gfx_images
;
118 struct gfxFontStruct
{
120 char last_fontname
[128];
121 char actual_fontname
[128];
127 WDL_TypedBuf
<gfxFontStruct
> m_gfx_fonts
;
129 EELFONT_FLAG_BOLD
= (1<<24),
130 EELFONT_FLAG_ITALIC
= (2<<24),
131 EELFONT_FLAG_UNDERLINE
= (4<<24),
132 EELFONT_FLAG_MASK
= EELFONT_FLAG_BOLD
|EELFONT_FLAG_ITALIC
|EELFONT_FLAG_UNDERLINE
135 int m_gfx_font_active
; // -1 for default, otherwise index into gfx_fonts (NOTE: this differs from the exposed API, which defines 0 as default, 1-n)
136 LICE_IFont
*GetActiveFont() { return m_gfx_font_active
>=0&&m_gfx_font_active
<m_gfx_fonts
.GetSize() && m_gfx_fonts
.Get()[m_gfx_font_active
].use_fonth
? m_gfx_fonts
.Get()[m_gfx_font_active
].font
: NULL
; }
138 LICE_IBitmap
*GetImageForIndex(EEL_F idx
, const char *callername
)
142 if (idx
< 0.0) return m_framebuffer
;
144 const int a
= (int)idx
;
145 if (a
>= 0 && a
< m_gfx_images
.GetSize()) return m_gfx_images
.Get()[a
];
150 void SetImageDirty(LICE_IBitmap
*bm
)
152 if (bm
== m_framebuffer
&& !m_framebuffer_dirty
)
154 if (m_gfx_clear
&& *m_gfx_clear
> -1.0)
156 const int a
=(int)*m_gfx_clear
;
157 if (LICE_FUNCTION_VALID(LICE_Clear
)) LICE_Clear(m_framebuffer
,LICE_RGBA((a
&0xff),((a
>>8)&0xff),((a
>>16)&0xff),0));
159 m_framebuffer_dirty
=1;
163 // R, G, B, A, w, h, x, y, mode(1=add,0=copy)
164 EEL_F
*m_gfx_r
, *m_gfx_g
, *m_gfx_b
, *m_gfx_w
, *m_gfx_h
, *m_gfx_a
, *m_gfx_x
, *m_gfx_y
, *m_gfx_mode
, *m_gfx_clear
, *m_gfx_texth
,*m_gfx_dest
, *m_gfx_a2
;
165 EEL_F
*m_mouse_x
, *m_mouse_y
, *m_mouse_cap
, *m_mouse_wheel
, *m_mouse_hwheel
;
166 EEL_F
*m_gfx_ext_retina
;
171 void gfx_lineto(EEL_F xpos
, EEL_F ypos
, EEL_F aaflag
);
172 void gfx_rectto(EEL_F xpos
, EEL_F ypos
);
173 void gfx_line(int np
, EEL_F
**parms
);
174 void gfx_rect(int np
, EEL_F
**parms
);
175 void gfx_roundrect(int np
, EEL_F
**parms
);
176 void gfx_arc(int np
, EEL_F
**parms
);
177 void gfx_set(int np
, EEL_F
**parms
);
178 void gfx_grad_or_muladd_rect(int mode
, int np
, EEL_F
**parms
);
179 void gfx_setpixel(EEL_F r
, EEL_F g
, EEL_F b
);
180 void gfx_getpixel(EEL_F
*r
, EEL_F
*g
, EEL_F
*b
);
181 void gfx_drawnumber(EEL_F n
, EEL_F ndigits
);
182 void gfx_drawchar(EEL_F ch
);
183 void gfx_getimgdim(EEL_F img
, EEL_F
*w
, EEL_F
*h
);
184 EEL_F
gfx_setimgdim(int img
, EEL_F
*w
, EEL_F
*h
);
185 void gfx_blurto(EEL_F x
, EEL_F y
);
186 void gfx_blitext(EEL_F img
, EEL_F
*coords
, EEL_F angle
);
187 void gfx_blitext2(int np
, EEL_F
**parms
, int mode
); // 0=blit, 1=deltablit
188 void gfx_transformblit(EEL_F
**parms
, int div_w
, int div_h
, EEL_F
*tab
); // parms[0]=src, 1-4=x,y,w,h
189 void gfx_circle(float x
, float y
, float r
, bool fill
, bool aaflag
);
190 void gfx_triangle(EEL_F
** parms
, int nparms
);
191 void gfx_drawstr(void *opaque
, EEL_F
**parms
, int nparms
, int formatmode
); // formatmode=1 for format, 2 for purely measure no format, 3 for measure char
192 EEL_F
gfx_loadimg(void *opaque
, int img
, EEL_F loadFrom
);
193 EEL_F
gfx_setfont(void *opaque
, int np
, EEL_F
**parms
);
194 EEL_F
gfx_getfont(void *opaque
, int np
, EEL_F
**parms
);
196 LICE_pixel
getCurColor();
198 int getCurModeForBlit(bool isFBsrc
);
200 // these have to be **parms because of the hack for getting string from parm index
201 EEL_F
gfx_setcursor(void* opaque
, EEL_F
** parms
, int nparms
);
204 eel_lice_state::eel_lice_state(NSEEL_VMCTX vm
, void *ctx
, int image_slots
, int font_slots
)
208 m_gfx_font_active
=-1;
209 m_gfx_fonts
.Resize(font_slots
);
210 memset(m_gfx_fonts
.Get(),0,m_gfx_fonts
.GetSize()*sizeof(m_gfx_fonts
.Get()[0]));
212 m_gfx_images
.Resize(image_slots
);
213 memset(m_gfx_images
.Get(),0,m_gfx_images
.GetSize()*sizeof(m_gfx_images
.Get()[0]));
214 m_framebuffer
=m_framebuffer_extra
=0;
215 m_framebuffer_dirty
=0;
217 m_gfx_r
= NSEEL_VM_regvar(vm
,"gfx_r");
218 m_gfx_g
= NSEEL_VM_regvar(vm
,"gfx_g");
219 m_gfx_b
= NSEEL_VM_regvar(vm
,"gfx_b");
220 m_gfx_a
= NSEEL_VM_regvar(vm
,"gfx_a");
221 m_gfx_a2
= NSEEL_VM_regvar(vm
,"gfx_a2");
223 m_gfx_w
= NSEEL_VM_regvar(vm
,"gfx_w");
224 m_gfx_h
= NSEEL_VM_regvar(vm
,"gfx_h");
225 m_gfx_x
= NSEEL_VM_regvar(vm
,"gfx_x");
226 m_gfx_y
= NSEEL_VM_regvar(vm
,"gfx_y");
227 m_gfx_mode
= NSEEL_VM_regvar(vm
,"gfx_mode");
228 m_gfx_clear
= NSEEL_VM_regvar(vm
,"gfx_clear");
229 m_gfx_texth
= NSEEL_VM_regvar(vm
,"gfx_texth");
230 m_gfx_dest
= NSEEL_VM_regvar(vm
,"gfx_dest");
231 m_gfx_ext_retina
= NSEEL_VM_regvar(vm
,"gfx_ext_retina");
233 m_mouse_x
= NSEEL_VM_regvar(vm
,"mouse_x");
234 m_mouse_y
= NSEEL_VM_regvar(vm
,"mouse_y");
235 m_mouse_cap
= NSEEL_VM_regvar(vm
,"mouse_cap");
236 m_mouse_wheel
=NSEEL_VM_regvar(vm
,"mouse_wheel");
237 m_mouse_hwheel
=NSEEL_VM_regvar(vm
,"mouse_hwheel");
239 if (m_gfx_texth
) *m_gfx_texth
=8;
241 eel_lice_state::~eel_lice_state()
243 if (LICE_FUNCTION_VALID(LICE__Destroy
))
245 LICE__Destroy(m_framebuffer_extra
);
246 LICE__Destroy(m_framebuffer
);
248 for (x
=0;x
<m_gfx_images
.GetSize();x
++)
250 LICE__Destroy(m_gfx_images
.Get()[x
]);
253 if (LICE_FUNCTION_VALID(LICE__DestroyFont
))
256 for (x
=0;x
<m_gfx_fonts
.GetSize();x
++)
258 if (m_gfx_fonts
.Get()[x
].font
) LICE__DestroyFont(m_gfx_fonts
.Get()[x
].font
);
263 int eel_lice_state::getCurMode()
265 const int gmode
= (int) (*m_gfx_mode
);
266 const int sm
=(gmode
>>4)&0xf;
267 if (sm
> LICE_BLIT_MODE_COPY
&& sm
<= LICE_BLIT_MODE_HSVADJ
) return sm
;
269 return (gmode
&1) ? LICE_BLIT_MODE_ADD
: LICE_BLIT_MODE_COPY
;
271 int eel_lice_state::getCurModeForBlit(bool isFBsrc
)
273 const int gmode
= (int) (*m_gfx_mode
);
275 const int sm
=(gmode
>>4)&0xf;
278 if (sm
> LICE_BLIT_MODE_COPY
&& sm
<= LICE_BLIT_MODE_HSVADJ
) mode
=sm
;
279 else mode
=((gmode
&1) ? LICE_BLIT_MODE_ADD
: LICE_BLIT_MODE_COPY
);
282 if (!isFBsrc
&& !(gmode
&2)) mode
|=LICE_BLIT_USE_ALPHA
;
283 if (!(gmode
&4)) mode
|=LICE_BLIT_FILTER_BILINEAR
;
287 LICE_pixel
eel_lice_state::getCurColor()
289 int red
=(int) (*m_gfx_r
*255.0);
290 int green
=(int) (*m_gfx_g
*255.0);
291 int blue
=(int) (*m_gfx_b
*255.0);
292 int a2
=(int) (*m_gfx_a2
*255.0);
293 if (red
<0) red
=0;else if (red
>255)red
=255;
294 if (green
<0) green
=0;else if (green
>255)green
=255;
295 if (blue
<0) blue
=0; else if (blue
>255) blue
=255;
296 if (a2
<0) a2
=0; else if (a2
>255) a2
=255;
297 return LICE_RGBA(red
,green
,blue
,a2
);
301 static EEL_F
* NSEEL_CGEN_CALL
ysfx_api_gfx_lineto(void *opaque
, EEL_F
*xpos
, EEL_F
*ypos
, EEL_F
*useaa
)
303 eel_lice_state
*ctx
=EEL_LICE_GET_CONTEXT(opaque
);
304 if (ctx
) ctx
->gfx_lineto(*xpos
, *ypos
, *useaa
);
307 static EEL_F
* NSEEL_CGEN_CALL
ysfx_api_gfx_lineto2(void *opaque
, EEL_F
*xpos
, EEL_F
*ypos
)
309 eel_lice_state
*ctx
=EEL_LICE_GET_CONTEXT(opaque
);
310 if (ctx
) ctx
->gfx_lineto(*xpos
, *ypos
, 1.0f
);
314 static EEL_F
* NSEEL_CGEN_CALL
ysfx_api_gfx_rectto(void *opaque
, EEL_F
*xpos
, EEL_F
*ypos
)
316 eel_lice_state
*ctx
=EEL_LICE_GET_CONTEXT(opaque
);
317 if (ctx
) ctx
->gfx_rectto(*xpos
, *ypos
);
321 static EEL_F NSEEL_CGEN_CALL
ysfx_api_gfx_line(void *opaque
, INT_PTR np
, EEL_F
**parms
)
323 eel_lice_state
*ctx
=EEL_LICE_GET_CONTEXT(opaque
);
324 if (ctx
) ctx
->gfx_line((int)np
,parms
);
328 static EEL_F NSEEL_CGEN_CALL
ysfx_api_gfx_rect(void *opaque
, INT_PTR np
, EEL_F
**parms
)
330 eel_lice_state
*ctx
=EEL_LICE_GET_CONTEXT(opaque
);
331 if (ctx
) ctx
->gfx_rect((int)np
,parms
);
334 static EEL_F NSEEL_CGEN_CALL
ysfx_api_gfx_roundrect(void *opaque
, INT_PTR np
, EEL_F
**parms
)
336 eel_lice_state
*ctx
=EEL_LICE_GET_CONTEXT(opaque
);
337 if (ctx
) ctx
->gfx_roundrect((int)np
,parms
);
340 static EEL_F NSEEL_CGEN_CALL
ysfx_api_gfx_arc(void *opaque
, INT_PTR np
, EEL_F
**parms
)
342 eel_lice_state
*ctx
=EEL_LICE_GET_CONTEXT(opaque
);
343 if (ctx
) ctx
->gfx_arc((int)np
,parms
);
346 static EEL_F NSEEL_CGEN_CALL
ysfx_api_gfx_set(void *opaque
, INT_PTR np
, EEL_F
**parms
)
348 eel_lice_state
*ctx
=EEL_LICE_GET_CONTEXT(opaque
);
349 if (ctx
) ctx
->gfx_set((int)np
,parms
);
352 static EEL_F NSEEL_CGEN_CALL
ysfx_api_gfx_gradrect(void *opaque
, INT_PTR np
, EEL_F
**parms
)
354 eel_lice_state
*ctx
=EEL_LICE_GET_CONTEXT(opaque
);
355 if (ctx
) ctx
->gfx_grad_or_muladd_rect(0,(int)np
,parms
);
359 static EEL_F NSEEL_CGEN_CALL
ysfx_api_gfx_muladdrect(void *opaque
, INT_PTR np
, EEL_F
**parms
)
361 eel_lice_state
*ctx
=EEL_LICE_GET_CONTEXT(opaque
);
362 if (ctx
) ctx
->gfx_grad_or_muladd_rect(1,(int)np
,parms
);
366 static EEL_F NSEEL_CGEN_CALL
ysfx_api_gfx_deltablit(void *opaque
, INT_PTR np
, EEL_F
**parms
)
368 eel_lice_state
*ctx
=EEL_LICE_GET_CONTEXT(opaque
);
369 if (ctx
) ctx
->gfx_blitext2((int)np
,parms
,1);
373 static EEL_F NSEEL_CGEN_CALL
ysfx_api_gfx_transformblit(void *opaque
, INT_PTR np
, EEL_F
**parms
)
375 eel_lice_state
*ctx
=EEL_LICE_GET_CONTEXT(opaque
);
378 #ifndef EEL_LICE_NO_RAM
379 const int divw
= (int) (parms
[5][0]+0.5);
380 const int divh
= (int) (parms
[6][0]+0.5);
381 if (divw
< 1 || divh
< 1) return 0.0;
382 const int sz
= divw
*divh
*2;
384 #ifdef EEL_LICE_RAMFUNC
385 EEL_F
*d
= EEL_LICE_RAMFUNC(opaque
,7,sz
);
388 EEL_F
**blocks
= ctx
->m_vmref
? ((compileContext
*)ctx
->m_vmref
)->ram_state
->blocks
: 0;
389 if (!blocks
|| np
< 8) return 0.0;
391 const int addr1
= (int) (parms
[7][0]+0.5);
392 EEL_F
*d
=__NSEEL_RAMAlloc(blocks
,addr1
);
393 if (sz
>NSEEL_RAM_ITEMSPERBLOCK
)
396 for(x
=NSEEL_RAM_ITEMSPERBLOCK
;x
<sz
-1;x
+=NSEEL_RAM_ITEMSPERBLOCK
)
397 if (__NSEEL_RAMAlloc(blocks
,addr1
+x
) != d
+x
) return 0.0;
399 EEL_F
*end
=__NSEEL_RAMAlloc(blocks
,addr1
+sz
-1);
400 if (end
!= d
+sz
-1) return 0.0; // buffer not contiguous
403 ctx
->gfx_transformblit(parms
,divw
,divh
,d
);
409 static EEL_F NSEEL_CGEN_CALL
ysfx_api_gfx_circle(void *opaque
, INT_PTR np
, EEL_F
**parms
)
411 eel_lice_state
*ctx
=EEL_LICE_GET_CONTEXT(opaque
);
412 bool aa
= true, fill
= false;
413 if (np
>3) fill
= parms
[3][0] > 0.5;
414 if (np
>4) aa
= parms
[4][0] > 0.5;
415 if (ctx
) ctx
->gfx_circle((float)parms
[0][0], (float)parms
[1][0], (float)parms
[2][0], fill
, aa
);
419 static EEL_F NSEEL_CGEN_CALL
ysfx_api_gfx_triangle(void* opaque
, INT_PTR np
, EEL_F
**parms
)
421 eel_lice_state
*ctx
=EEL_LICE_GET_CONTEXT(opaque
);
422 if (ctx
) ctx
->gfx_triangle(parms
, (int)np
);
426 static EEL_F
* NSEEL_CGEN_CALL
ysfx_api_gfx_drawnumber(void *opaque
, EEL_F
*n
, EEL_F
*nd
)
428 eel_lice_state
*ctx
=EEL_LICE_GET_CONTEXT(opaque
);
429 if (ctx
) ctx
->gfx_drawnumber(*n
, *nd
);
433 static EEL_F
* NSEEL_CGEN_CALL
ysfx_api_gfx_drawchar(void *opaque
, EEL_F
*n
)
435 eel_lice_state
*ctx
=EEL_LICE_GET_CONTEXT(opaque
);
436 if (ctx
) ctx
->gfx_drawchar(*n
);
440 static EEL_F
* NSEEL_CGEN_CALL
ysfx_api_gfx_measurestr(void *opaque
, EEL_F
*str
, EEL_F
*xOut
, EEL_F
*yOut
)
442 eel_lice_state
*ctx
=EEL_LICE_GET_CONTEXT(opaque
);
445 EEL_F
*p
[3]={str
,xOut
,yOut
};
446 ctx
->gfx_drawstr(opaque
,p
,3,2);
450 static EEL_F
* NSEEL_CGEN_CALL
ysfx_api_gfx_measurechar(void *opaque
, EEL_F
*str
, EEL_F
*xOut
, EEL_F
*yOut
)
452 eel_lice_state
*ctx
=EEL_LICE_GET_CONTEXT(opaque
);
455 EEL_F
*p
[3]={str
,xOut
,yOut
};
456 ctx
->gfx_drawstr(opaque
,p
,3,3);
461 static EEL_F NSEEL_CGEN_CALL
ysfx_api_gfx_drawstr(void *opaque
, INT_PTR nparms
, EEL_F
**parms
)
463 eel_lice_state
*ctx
=EEL_LICE_GET_CONTEXT(opaque
);
464 if (ctx
) ctx
->gfx_drawstr(opaque
,parms
,(int)nparms
,0);
468 static EEL_F NSEEL_CGEN_CALL
ysfx_api_gfx_printf(void *opaque
, INT_PTR nparms
, EEL_F
**parms
)
470 eel_lice_state
*ctx
=EEL_LICE_GET_CONTEXT(opaque
);
474 ctx
->gfx_drawstr(opaque
,parms
,(int)nparms
,1);
480 static EEL_F
* NSEEL_CGEN_CALL
ysfx_api_gfx_setpixel(void *opaque
, EEL_F
*r
, EEL_F
*g
, EEL_F
*b
)
482 eel_lice_state
*ctx
=EEL_LICE_GET_CONTEXT(opaque
);
483 if (ctx
) ctx
->gfx_setpixel(*r
, *g
, *b
);
487 static EEL_F
* NSEEL_CGEN_CALL
ysfx_api_gfx_getpixel(void *opaque
, EEL_F
*r
, EEL_F
*g
, EEL_F
*b
)
489 eel_lice_state
*ctx
=EEL_LICE_GET_CONTEXT(opaque
);
490 if (ctx
) ctx
->gfx_getpixel(r
, g
, b
);
494 static EEL_F NSEEL_CGEN_CALL
ysfx_api_gfx_setfont(void *opaque
, INT_PTR np
, EEL_F
**parms
)
496 eel_lice_state
*ctx
=EEL_LICE_GET_CONTEXT(opaque
);
497 if (ctx
) return ctx
->gfx_setfont(opaque
,(int)np
,parms
);
501 static EEL_F NSEEL_CGEN_CALL
ysfx_api_gfx_getfont(void *opaque
, INT_PTR np
, EEL_F
**parms
)
503 eel_lice_state
*ctx
=EEL_LICE_GET_CONTEXT(opaque
);
506 const int idx
=ctx
->m_gfx_font_active
;
507 if (idx
>=0 && idx
< ctx
->m_gfx_fonts
.GetSize())
509 eel_lice_state::gfxFontStruct
* f
=ctx
->m_gfx_fonts
.Get()+idx
;
511 EEL_STRING_MUTEXLOCK_SCOPE
513 #ifdef NOT_EEL_STRING_UPDATE_STRING
514 NOT_EEL_STRING_UPDATE_STRING(parms
[0][0],f
->actual_fontname
);
516 WDL_FastString
*fs
=NULL
;
517 EEL_STRING_GET_FOR_WRITE(parms
[0][0],&fs
);
518 if (fs
) fs
->Set(f
->actual_fontname
);
526 static EEL_F NSEEL_CGEN_CALL
ysfx_api_gfx_blit2(void *opaque
, INT_PTR np
, EEL_F
**parms
)
528 eel_lice_state
*ctx
=EEL_LICE_GET_CONTEXT(opaque
);
531 ctx
->gfx_blitext2((int)np
,parms
,0);
537 static EEL_F
* NSEEL_CGEN_CALL
ysfx_api_gfx_blitext(void *opaque
, EEL_F
*img
, EEL_F
*coordidx
, EEL_F
*rotate
)
539 eel_lice_state
*ctx
=EEL_LICE_GET_CONTEXT(opaque
);
542 #ifndef EEL_LICE_NO_RAM
543 #ifdef EEL_LICE_RAMFUNC
544 EEL_F
*buf
= EEL_LICE_RAMFUNC(opaque
,1,10);
545 if (!buf
) return img
;
547 EEL_F fc
= *coordidx
;
548 if (fc
< -0.5 || fc
>= NSEEL_RAM_BLOCKS
*NSEEL_RAM_ITEMSPERBLOCK
) return img
;
554 EEL_F
**blocks
= ctx
->m_vmref
? ((compileContext
*)ctx
->m_vmref
)->ram_state
->blocks
: 0;
555 if (!blocks
) return img
;
556 for (x
= 0;x
< 10; x
++)
558 EEL_F
*d
=__NSEEL_RAMAlloc(blocks
,a
++);
559 if (!d
|| d
==&nseel_ramalloc_onfail
) return img
;
564 ctx
->gfx_blitext(*img
,buf
,*rotate
);
571 static EEL_F
* NSEEL_CGEN_CALL
ysfx_api_gfx_blurto(void *opaque
, EEL_F
*x
, EEL_F
*y
)
573 eel_lice_state
*ctx
=EEL_LICE_GET_CONTEXT(opaque
);
574 if (ctx
) ctx
->gfx_blurto(*x
,*y
);
578 static EEL_F
* NSEEL_CGEN_CALL
ysfx_api_gfx_getimgdim(void *opaque
, EEL_F
*img
, EEL_F
*w
, EEL_F
*h
)
580 eel_lice_state
*ctx
=EEL_LICE_GET_CONTEXT(opaque
);
581 if (ctx
) ctx
->gfx_getimgdim(*img
,w
,h
);
585 static EEL_F NSEEL_CGEN_CALL
ysfx_api_gfx_loadimg(void *opaque
, EEL_F
*img
, EEL_F
*fr
)
587 eel_lice_state
*ctx
=EEL_LICE_GET_CONTEXT(opaque
);
588 if (ctx
) return ctx
->gfx_loadimg(opaque
,(int)*img
,*fr
);
592 static EEL_F NSEEL_CGEN_CALL
ysfx_api_gfx_setimgdim(void *opaque
, EEL_F
*img
, EEL_F
*w
, EEL_F
*h
)
594 eel_lice_state
*ctx
=EEL_LICE_GET_CONTEXT(opaque
);
595 if (ctx
) return ctx
->gfx_setimgdim((int)*img
,w
,h
);
599 static EEL_F NSEEL_CGEN_CALL
ysfx_api_gfx_getsyscol(void* ctxe
, INT_PTR np
, EEL_F
**parms
)
601 return (EEL_F
)LICE_RGBA_FROMNATIVE(GetSysColor(COLOR_3DFACE
));
604 void eel_lice_state::gfx_lineto(EEL_F xpos
, EEL_F ypos
, EEL_F aaflag
)
606 LICE_IBitmap
*dest
= GetImageForIndex(*m_gfx_dest
,"gfx_lineto");
609 int x1
=(int)floor(xpos
),y1
=(int)floor(ypos
),x2
=(int)floor(*m_gfx_x
), y2
=(int)floor(*m_gfx_y
);
610 if (LICE_FUNCTION_VALID(LICE__GetWidth
) && LICE_FUNCTION_VALID(LICE__GetHeight
) && LICE_FUNCTION_VALID(LICE_Line
) &&
611 LICE_FUNCTION_VALID(LICE_ClipLine
) &&
612 LICE_ClipLine(&x1
,&y1
,&x2
,&y2
,0,0,LICE__GetWidth(dest
),LICE__GetHeight(dest
)))
615 LICE_Line(dest
,x1
,y1
,x2
,y2
,getCurColor(),(float) *m_gfx_a
,getCurMode(),aaflag
> 0.5);
622 void eel_lice_state::gfx_circle(float x
, float y
, float r
, bool fill
, bool aaflag
)
624 LICE_IBitmap
*dest
= GetImageForIndex(*m_gfx_dest
,"gfx_circle");
627 if (LICE_FUNCTION_VALID(LICE_Circle
) && LICE_FUNCTION_VALID(LICE_FillCircle
))
631 LICE_FillCircle(dest
, x
, y
, r
, getCurColor(), (float) *m_gfx_a
, getCurMode(), aaflag
);
633 LICE_Circle(dest
, x
, y
, r
, getCurColor(), (float) *m_gfx_a
, getCurMode(), aaflag
);
637 void eel_lice_state::gfx_triangle(EEL_F
** parms
, int np
)
639 LICE_IBitmap
*dest
= GetImageForIndex(*m_gfx_dest
, "gfx_triangle");
646 if (!LICE_FUNCTION_VALID(LICE_FillTriangle
)) return;
648 LICE_FillTriangle(dest
, (int)parms
[0][0], (int)parms
[1][0], (int)parms
[2][0], (int)parms
[3][0],
649 (int)parms
[4][0], (int)parms
[5][0], getCurColor(), (float)*m_gfx_a
, getCurMode());
653 if (!LICE_FUNCTION_VALID(LICE_FillConvexPolygon
)) return;
655 const int maxpt
= 512;
656 const int n
= wdl_min(np
/2, maxpt
);
658 int x
[maxpt
], y
[maxpt
];
659 for (i
=0; i
< n
; i
++)
661 x
[i
]=(int)parms
[rdi
++][0];
662 y
[i
]=(int)parms
[rdi
++][0];
665 LICE_FillConvexPolygon(dest
, x
, y
, n
, getCurColor(), (float)*m_gfx_a
, getCurMode());
670 void eel_lice_state::gfx_rectto(EEL_F xpos
, EEL_F ypos
)
672 LICE_IBitmap
*dest
= GetImageForIndex(*m_gfx_dest
,"gfx_rectto");
675 EEL_F x1
=xpos
,y1
=ypos
,x2
=*m_gfx_x
, y2
=*m_gfx_y
;
676 if (x2
<x1
) { x1
=x2
; x2
=xpos
; }
677 if (y2
<y1
) { y1
=y2
; y2
=ypos
; }
679 if (LICE_FUNCTION_VALID(LICE_FillRect
) && x2
-x1
> 0.5 && y2
-y1
> 0.5)
682 LICE_FillRect(dest
,(int)x1
,(int)y1
,(int)(x2
-x1
),(int)(y2
-y1
),getCurColor(),(float)*m_gfx_a
,getCurMode());
689 void eel_lice_state::gfx_line(int np
, EEL_F
**parms
)
691 LICE_IBitmap
*dest
= GetImageForIndex(*m_gfx_dest
,"gfx_line");
694 int x1
=(int)floor(parms
[0][0]),y1
=(int)floor(parms
[1][0]),x2
=(int)floor(parms
[2][0]), y2
=(int)floor(parms
[3][0]);
695 if (LICE_FUNCTION_VALID(LICE__GetWidth
) &&
696 LICE_FUNCTION_VALID(LICE__GetHeight
) &&
697 LICE_FUNCTION_VALID(LICE_Line
) &&
698 LICE_FUNCTION_VALID(LICE_ClipLine
) && LICE_ClipLine(&x1
,&y1
,&x2
,&y2
,0,0,LICE__GetWidth(dest
),LICE__GetHeight(dest
)))
701 LICE_Line(dest
,x1
,y1
,x2
,y2
,getCurColor(),(float)*m_gfx_a
,getCurMode(),np
< 5 || parms
[4][0] > 0.5);
705 void eel_lice_state::gfx_rect(int np
, EEL_F
**parms
)
707 LICE_IBitmap
*dest
= GetImageForIndex(*m_gfx_dest
,"gfx_rect");
710 int x1
=(int)floor(parms
[0][0]),y1
=(int)floor(parms
[1][0]),w
=(int)floor(parms
[2][0]),h
=(int)floor(parms
[3][0]);
711 int filled
=(np
< 5 || parms
[4][0] > 0.5);
713 if (LICE_FUNCTION_VALID(LICE_FillRect
) && LICE_FUNCTION_VALID(LICE_DrawRect
) && w
>0 && h
>0)
716 if (filled
) LICE_FillRect(dest
,x1
,y1
,w
,h
,getCurColor(),(float)*m_gfx_a
,getCurMode());
717 else LICE_DrawRect(dest
, x1
, y1
, w
-1, h
-1, getCurColor(), (float)*m_gfx_a
, getCurMode());
721 void eel_lice_state::gfx_roundrect(int np
, EEL_F
**parms
)
723 LICE_IBitmap
*dest
= GetImageForIndex(*m_gfx_dest
,"gfx_roundrect");
726 const bool aa
= np
<= 5 || parms
[5][0]>0.5;
728 if (LICE_FUNCTION_VALID(LICE_RoundRect
) && parms
[2][0]>0 && parms
[3][0]>0)
731 LICE_RoundRect(dest
, (float)parms
[0][0], (float)parms
[1][0], (float)parms
[2][0], (float)parms
[3][0], (int)parms
[4][0], getCurColor(), (float)*m_gfx_a
, getCurMode(), aa
);
735 void eel_lice_state::gfx_arc(int np
, EEL_F
**parms
)
737 LICE_IBitmap
*dest
= GetImageForIndex(*m_gfx_dest
,"gfx_arc");
740 const bool aa
= np
<= 5 || parms
[5][0]>0.5;
742 if (LICE_FUNCTION_VALID(LICE_Arc
))
745 LICE_Arc(dest
, (float)parms
[0][0], (float)parms
[1][0], (float)parms
[2][0], (float)parms
[3][0], (float)parms
[4][0], getCurColor(), (float)*m_gfx_a
, getCurMode(), aa
);
749 void eel_lice_state::gfx_grad_or_muladd_rect(int whichmode
, int np
, EEL_F
**parms
)
751 LICE_IBitmap
*dest
= GetImageForIndex(*m_gfx_dest
,whichmode
==0?"gfx_gradrect":"gfx_muladdrect");
754 const int x1
=(int)floor(parms
[0][0]),y1
=(int)floor(parms
[1][0]),w
=(int)floor(parms
[2][0]), h
=(int)floor(parms
[3][0]);
759 if (whichmode
==0 && LICE_FUNCTION_VALID(LICE_GradRect
) && np
> 7)
761 LICE_GradRect(dest
,x1
,y1
,w
,h
,(float)parms
[4][0],(float)parms
[5][0],(float)parms
[6][0],(float)parms
[7][0],
762 np
> 8 ? (float)parms
[8][0]:0.0f
, np
> 9 ? (float)parms
[9][0]:0.0f
, np
> 10 ? (float)parms
[10][0]:0.0f
, np
> 11 ? (float)parms
[11][0]:0.0f
,
763 np
> 12 ? (float)parms
[12][0]:0.0f
, np
> 13 ? (float)parms
[13][0]:0.0f
, np
> 14 ? (float)parms
[14][0]:0.0f
, np
> 15 ? (float)parms
[15][0]:0.0f
,
766 else if (whichmode
==1 && LICE_FUNCTION_VALID(LICE_MultiplyAddRect
) && np
> 6)
768 const double sc
= 255.0;
769 LICE_MultiplyAddRect(dest
,x1
,y1
,w
,h
,(float)parms
[4][0],(float)parms
[5][0],(float)parms
[6][0],np
>7 ? (float)parms
[7][0]:1.0f
,
770 (float)(np
> 8 ? sc
*parms
[8][0]:0.0), (float)(np
> 9 ? sc
*parms
[9][0]:0.0), (float)(np
> 10 ? sc
*parms
[10][0]:0.0), (float)(np
> 11 ? sc
*parms
[11][0]:0.0));
777 void eel_lice_state::gfx_setpixel(EEL_F r
, EEL_F g
, EEL_F b
)
779 LICE_IBitmap
*dest
= GetImageForIndex(*m_gfx_dest
,"gfx_setpixel");
782 int red
=(int) (r
*255.0);
783 int green
=(int) (g
*255.0);
784 int blue
=(int) (b
*255.0);
785 if (red
<0) red
=0;else if (red
>255)red
=255;
786 if (green
<0) green
=0;else if (green
>255)green
=255;
787 if (blue
<0) blue
=0; else if (blue
>255) blue
=255;
789 if (LICE_FUNCTION_VALID(LICE_PutPixel
))
792 LICE_PutPixel(dest
,(int)*m_gfx_x
, (int)*m_gfx_y
,LICE_RGBA(red
,green
,blue
,255), (float)*m_gfx_a
,getCurMode());
796 void eel_lice_state::gfx_getimgdim(EEL_F img
, EEL_F
*w
, EEL_F
*h
)
800 if (!LICE__GetWidth
|| !LICE__GetHeight
) return;
803 LICE_IBitmap
*bm
=GetImageForIndex(img
,"gfx_getimgdim");
806 *w
=LICE__GetWidth(bm
);
807 *h
=LICE__GetHeight(bm
);
811 EEL_F
eel_lice_state::gfx_loadimg(void *opaque
, int img
, EEL_F loadFrom
)
814 if (!__LICE_LoadImage
|| !LICE__Destroy
) return 0.0;
817 if (img
>= 0 && img
< m_gfx_images
.GetSize())
820 bool ok
= EEL_LICE_GET_FILENAME_FOR_STRING(loadFrom
,&fs
,0);
822 if (ok
&& fs
.GetLength())
824 LICE_IBitmap
*bm
= LICE_LoadImage(fs
.Get(),NULL
,false);
827 LICE__Destroy(m_gfx_images
.Get()[img
]);
828 m_gfx_images
.Get()[img
]=bm
;
837 EEL_F
eel_lice_state::gfx_setimgdim(int img
, EEL_F
*w
, EEL_F
*h
)
841 if (!LICE__resize
||!LICE__GetWidth
|| !LICE__GetHeight
||!__LICE_CreateBitmap
) return 0.0;
846 if (use_w
<1 || use_h
< 1) use_w
=use_h
=0;
847 if (use_w
> 8192) use_w
=8192;
848 if (use_h
> 8192) use_h
=8192;
850 LICE_IBitmap
*bm
=NULL
;
851 if (img
>= 0 && img
< m_gfx_images
.GetSize())
853 bm
=m_gfx_images
.Get()[img
];
856 m_gfx_images
.Get()[img
] = bm
= __LICE_CreateBitmap(1,use_w
,use_h
);
861 rv
=LICE__resize(bm
,use_w
,use_h
);
868 void eel_lice_state::gfx_blurto(EEL_F x
, EEL_F y
)
870 LICE_IBitmap
*dest
= GetImageForIndex(*m_gfx_dest
,"gfx_blurto");
881 int srcw
=(int) (*m_gfx_x
-x
);
882 int srch
=(int) (*m_gfx_y
-y
);
883 if (srch
< 0) { srch
=-srch
; srcy
= (int)*m_gfx_y
; }
884 if (srcw
< 0) { srcw
=-srcw
; srcx
= (int)*m_gfx_x
; }
885 LICE_Blur(dest
,dest
,srcx
,srcy
,srcx
,srcy
,srcw
,srch
);
890 static bool CoordsSrcDestOverlap(EEL_F
*coords
)
892 if (coords
[0]+coords
[2] < coords
[4]) return false;
893 if (coords
[0] > coords
[4] + coords
[6]) return false;
894 if (coords
[1]+coords
[3] < coords
[5]) return false;
895 if (coords
[1] > coords
[5] + coords
[7]) return false;
899 void eel_lice_state::gfx_transformblit(EEL_F
**parms
, int div_w
, int div_h
, EEL_F
*tab
)
901 LICE_IBitmap
*dest
= GetImageForIndex(*m_gfx_dest
,"gfx_transformblit");
905 ||!LICE_ScaledBlit
|| !LICE_TransformBlit2
||!LICE__GetWidth
||!LICE__GetHeight
909 LICE_IBitmap
*bm
=GetImageForIndex(parms
[0][0],"gfx_transformblit:src");
912 const int bmw
=LICE__GetWidth(bm
);
913 const int bmh
=LICE__GetHeight(bm
);
915 const bool isFromFB
= bm
==m_framebuffer
;
921 if (!m_framebuffer_extra
&& LICE_FUNCTION_VALID(__LICE_CreateBitmap
)) m_framebuffer_extra
=__LICE_CreateBitmap(0,bmw
,bmh
);
922 if (m_framebuffer_extra
)
925 LICE__resize(bm
=m_framebuffer_extra
,bmw
,bmh
);
926 LICE_ScaledBlit(bm
,dest
, // copy the entire image
928 0.0f
,0.0f
,(float)bmw
,(float)bmh
,
929 1.0f
,LICE_BLIT_MODE_COPY
);
932 LICE_TransformBlit2(dest
,bm
,(int)floor(parms
[1][0]),(int)floor(parms
[2][0]),(int)floor(parms
[3][0]),(int)floor(parms
[4][0]),tab
,div_w
,div_h
, (float)*m_gfx_a
,getCurModeForBlit(isFromFB
));
935 EEL_F
eel_lice_state::gfx_setfont(void *opaque
, int np
, EEL_F
**parms
)
937 int a
= np
>0 ? ((int)floor(parms
[0][0]))-1 : -1;
939 if (a
>=0 && a
< m_gfx_fonts
.GetSize())
941 gfxFontStruct
*s
= m_gfx_fonts
.Get()+a
;
942 if (np
>1 && LICE_FUNCTION_VALID(LICE_CreateFont
) && LICE_FUNCTION_VALID(LICE__SetFromHFont
))
944 const int sz
=np
>2 ? (int)parms
[2][0] : 10;
948 if (!s
->font
) s
->actual_fontname
[0]=0;
951 EEL_STRING_MUTEXLOCK_SCOPE
953 const char *face
=EEL_STRING_GET_FOR_INDEX(parms
[1][0],NULL
);
954 #ifdef EEL_STRING_DEBUGOUT
955 if (!face
) EEL_STRING_DEBUGOUT("gfx_setfont: invalid string identifier %f",parms
[1][0]);
957 if (!face
|| !*face
) face
="Arial";
960 unsigned int c
= np
> 3 ? (unsigned int) parms
[3][0] : 0;
963 switch (toupper(c
&0xff))
965 case 'B': fontflag
|=EELFONT_FLAG_BOLD
; break;
966 case 'I': fontflag
|=EELFONT_FLAG_ITALIC
; break;
967 case 'U': fontflag
|=EELFONT_FLAG_UNDERLINE
; break;
968 case 'R': fontflag
|=16; break; //LICE_FONT_FLAG_FX_BLUR
969 case 'V': fontflag
|=32; break; //LICE_FONT_FLAG_FX_INVERT
970 case 'M': fontflag
|=64; break; //LICE_FONT_FLAG_FX_MONO
971 case 'S': fontflag
|=128; break; //LICE_FONT_FLAG_FX_SHADOW
972 case 'O': fontflag
|=256; break; //LICE_FONT_FLAG_FX_OUTLINE
973 case 'Z': fontflag
|=1; break; //LICE_FONT_FLAG_VERTICAL
974 case 'Y': fontflag
|=1|2; break; //LICE_FONT_FLAG_VERTICAL|LICE_FONT_FLAG_VERTICAL_BOTTOMUP
981 if (fontflag
!= s
->last_fontflag
|| sz
!=s
->last_fontsize
|| strncmp(s
->last_fontname
,face
,sizeof(s
->last_fontname
)-1))
983 lstrcpyn_safe(s
->last_fontname
,face
,sizeof(s
->last_fontname
));
985 s
->last_fontflag
=fontflag
;
992 s
->actual_fontname
[0]=0;
993 if (!s
->font
) s
->font
=LICE_CreateFont();
996 const int fw
= (fontflag
&EELFONT_FLAG_BOLD
) ? FW_BOLD
: FW_NORMAL
;
997 const bool italic
= !!(fontflag
&EELFONT_FLAG_ITALIC
);
998 const bool underline
= !!(fontflag
&EELFONT_FLAG_UNDERLINE
);
1000 #if defined(_WIN32) && !defined(WDL_NO_SUPPORT_UTF8)
1002 if (WDL_DetectUTF8(s
->last_fontname
)>0 &&
1003 GetVersion()<0x80000000 &&
1004 MultiByteToWideChar(CP_UTF8
,MB_ERR_INVALID_CHARS
,s
->last_fontname
,-1,wf
,256))
1006 hf
= CreateFontW(sz
,0,0,0,fw
,italic
,underline
,FALSE
,DEFAULT_CHARSET
,OUT_DEFAULT_PRECIS
,CLIP_DEFAULT_PRECIS
,DEFAULT_QUALITY
,DEFAULT_PITCH
,wf
);
1009 if (!hf
) hf
= CreateFont(sz
,0,0,0,fw
,italic
,underline
,FALSE
,DEFAULT_CHARSET
,OUT_DEFAULT_PRECIS
,CLIP_DEFAULT_PRECIS
,DEFAULT_QUALITY
,DEFAULT_PITCH
,s
->last_fontname
);
1013 s
->use_fonth
=0; // disable this font
1020 if (!m_framebuffer
&& LICE_FUNCTION_VALID(__LICE_CreateBitmap
)) m_framebuffer
=__LICE_CreateBitmap(1,64,64);
1022 if (m_framebuffer
&& LICE_FUNCTION_VALID(LICE__GetDC
))
1024 HGDIOBJ oldFont
= 0;
1025 HDC hdc
=LICE__GetDC(m_framebuffer
);
1028 oldFont
= SelectObject(hdc
,hf
);
1029 GetTextMetrics(hdc
,&tm
);
1031 #if defined(_WIN32) && !defined(WDL_NO_SUPPORT_UTF8)
1032 if (GetVersion()<0x80000000 &&
1033 GetTextFaceW(hdc
,sizeof(wf
)/sizeof(wf
[0]),wf
) &&
1034 WideCharToMultiByte(CP_UTF8
,0,wf
,-1,s
->actual_fontname
,sizeof(s
->actual_fontname
),NULL
,NULL
))
1036 s
->actual_fontname
[sizeof(s
->actual_fontname
)-1]=0;
1040 GetTextFace(hdc
, sizeof(s
->actual_fontname
), s
->actual_fontname
);
1041 SelectObject(hdc
,oldFont
);
1045 s
->use_fonth
=wdl_max(tm
.tmHeight
,1);
1046 LICE__SetFromHFont(s
->font
,hf
, (fontflag
& ~EELFONT_FLAG_MASK
) | 512 /*LICE_FONT_FLAG_OWNS_HFONT*/);
1053 if (s
->font
&& s
->use_fonth
)
1055 m_gfx_font_active
=a
;
1056 if (m_gfx_texth
) *m_gfx_texth
=s
->use_fonth
;
1059 // try to init this font
1061 #ifdef EEL_STRING_DEBUGOUT
1062 if (a
>= m_gfx_fonts
.GetSize()) EEL_STRING_DEBUGOUT("gfx_setfont: invalid font %d specified",a
);
1065 if (a
<0||a
>=m_gfx_fonts
.GetSize()||!m_gfx_fonts
.Get()[a
].font
)
1067 m_gfx_font_active
=-1;
1068 if (m_gfx_texth
) *m_gfx_texth
=8;
1074 void eel_lice_state::gfx_blitext2(int np
, EEL_F
**parms
, int blitmode
)
1076 LICE_IBitmap
*dest
= GetImageForIndex(*m_gfx_dest
,"gfx_blitext2");
1080 ||!LICE_ScaledBlit
|| !LICE_RotatedBlit
||!LICE__GetWidth
||!LICE__GetHeight
1084 LICE_IBitmap
*bm
=GetImageForIndex(parms
[0][0],"gfx_blitext2:src");
1087 const int bmw
=LICE__GetWidth(bm
);
1088 const int bmh
=LICE__GetHeight(bm
);
1090 // 0=img, 1=scale, 2=rotate
1092 const double sc
= blitmode
==0 && np
> 1 ? parms
[1][0] : 1.0,
1093 angle
= blitmode
==0 && np
> 2 ? parms
[2][0] : 0.0;
1100 coords
[0]=np
> 1 ? parms
[1][0] : 0.0f
;
1101 coords
[1]=np
> 2 ? parms
[2][0] : 0.0f
;
1102 coords
[2]=np
> 3 ? parms
[3][0] : bmw
;
1103 coords
[3]=np
> 4 ? parms
[4][0] : bmh
;
1104 coords
[4]=np
> 5 ? parms
[5][0] : *m_gfx_x
;
1105 coords
[5]=np
> 6 ? parms
[6][0] : *m_gfx_y
;
1106 coords
[6]=np
> 7 ? parms
[7][0] : coords
[2]*sc
;
1107 coords
[7]=np
> 8 ? parms
[8][0] : coords
[3]*sc
;
1109 const bool isFromFB
= bm
== m_framebuffer
;
1110 SetImageDirty(dest
);
1113 (blitmode
!= 0 || np
> 1) && // legacy behavior to matech previous gfx_blit(3parm), do not use temp buffer
1114 CoordsSrcDestOverlap(coords
))
1116 if (!m_framebuffer_extra
&& LICE_FUNCTION_VALID(__LICE_CreateBitmap
)) m_framebuffer_extra
=__LICE_CreateBitmap(0,bmw
,bmh
);
1117 if (m_framebuffer_extra
)
1120 LICE__resize(bm
=m_framebuffer_extra
,bmw
,bmh
);
1121 LICE_ScaledBlit(bm
,dest
, // copy the source portion
1122 (int)coords
[0],(int)coords
[1],(int)coords
[2],(int)coords
[3],
1123 (float)coords
[0],(float)coords
[1],(float)coords
[2],(float)coords
[3],
1124 1.0f
,LICE_BLIT_MODE_COPY
);
1130 if (LICE_FUNCTION_VALID(LICE_DeltaBlit
))
1131 LICE_DeltaBlit(dest
,bm
,(int)coords
[4],(int)coords
[5],(int)coords
[6],(int)coords
[7],
1132 (float)coords
[0],(float)coords
[1],(float)coords
[2],(float)coords
[3],
1133 np
> 9 ? (float)parms
[9][0]:1.0f
, // dsdx
1134 np
> 10 ? (float)parms
[10][0]:0.0f
, // dtdx
1135 np
> 11 ? (float)parms
[11][0]:0.0f
, // dsdy
1136 np
> 12 ? (float)parms
[12][0]:1.0f
, // dtdy
1137 np
> 13 ? (float)parms
[13][0]:0.0f
, // dsdxdy
1138 np
> 14 ? (float)parms
[14][0]:0.0f
, // dtdxdy
1139 np
<= 15 || parms
[15][0] > 0.5, (float)*m_gfx_a
,getCurModeForBlit(isFromFB
));
1141 else if (fabs(angle
)>0.000000001)
1143 LICE_RotatedBlit(dest
,bm
,(int)coords
[4],(int)coords
[5],(int)coords
[6],(int)coords
[7],
1144 (float)coords
[0],(float)coords
[1],(float)coords
[2],(float)coords
[3],
1145 (float)angle
,true, (float)*m_gfx_a
,getCurModeForBlit(isFromFB
),
1146 np
> 9 ? (float)parms
[9][0] : 0.0f
,
1147 np
> 10 ? (float)parms
[10][0] : 0.0f
);
1151 LICE_ScaledBlit(dest
,bm
,(int)coords
[4],(int)coords
[5],(int)coords
[6],(int)coords
[7],
1152 (float)coords
[0],(float)coords
[1],(float)coords
[2],(float)coords
[3], (float)*m_gfx_a
,getCurModeForBlit(isFromFB
));
1156 void eel_lice_state::gfx_blitext(EEL_F img
, EEL_F
*coords
, EEL_F angle
)
1158 LICE_IBitmap
*dest
= GetImageForIndex(*m_gfx_dest
,"gfx_blitext");
1162 ||!LICE_ScaledBlit
|| !LICE_RotatedBlit
||!LICE__GetWidth
||!LICE__GetHeight
1166 LICE_IBitmap
*bm
=GetImageForIndex(img
,"gfx_blitext:src");
1169 SetImageDirty(dest
);
1170 const bool isFromFB
= bm
== m_framebuffer
;
1172 int bmw
=LICE__GetWidth(bm
);
1173 int bmh
=LICE__GetHeight(bm
);
1175 if (bm
== dest
&& CoordsSrcDestOverlap(coords
))
1177 if (!m_framebuffer_extra
&& LICE_FUNCTION_VALID(__LICE_CreateBitmap
)) m_framebuffer_extra
=__LICE_CreateBitmap(0,bmw
,bmh
);
1178 if ( m_framebuffer_extra
)
1181 LICE__resize(bm
=m_framebuffer_extra
,bmw
,bmh
);
1182 LICE_ScaledBlit(bm
,dest
, // copy the source portion
1183 (int)coords
[0],(int)coords
[1],(int)coords
[2],(int)coords
[3],
1184 (float)coords
[0],(float)coords
[1],(float)coords
[2],(float)coords
[3],
1185 1.0f
,LICE_BLIT_MODE_COPY
);
1189 if (fabs(angle
)>0.000000001)
1191 LICE_RotatedBlit(dest
,bm
,(int)coords
[4],(int)coords
[5],(int)coords
[6],(int)coords
[7],
1192 (float)coords
[0],(float)coords
[1],(float)coords
[2],(float)coords
[3],(float)angle
,
1193 true, (float)*m_gfx_a
,getCurModeForBlit(isFromFB
),
1194 (float)coords
[8],(float)coords
[9]);
1198 LICE_ScaledBlit(dest
,bm
,(int)coords
[4],(int)coords
[5],(int)coords
[6],(int)coords
[7],
1199 (float)coords
[0],(float)coords
[1],(float)coords
[2],(float)coords
[3], (float)*m_gfx_a
,getCurModeForBlit(isFromFB
));
1203 void eel_lice_state::gfx_set(int np
, EEL_F
**parms
)
1206 if (m_gfx_r
) *m_gfx_r
= parms
[0][0];
1207 if (m_gfx_g
) *m_gfx_g
= np
> 1 ? parms
[1][0] : parms
[0][0];
1208 if (m_gfx_b
) *m_gfx_b
= np
> 2 ? parms
[2][0] : parms
[0][0];
1209 if (m_gfx_a
) *m_gfx_a
= np
> 3 ? parms
[3][0] : 1.0;
1210 if (m_gfx_mode
) *m_gfx_mode
= np
> 4 ? parms
[4][0] : 0;
1211 if (np
> 5 && m_gfx_dest
) *m_gfx_dest
= parms
[5][0];
1212 if (m_gfx_a2
) *m_gfx_a2
= np
> 6 ? parms
[6][0] : 1.0;
1215 void eel_lice_state::gfx_getpixel(EEL_F
*r
, EEL_F
*g
, EEL_F
*b
)
1217 LICE_IBitmap
*dest
= GetImageForIndex(*m_gfx_dest
,"gfx_getpixel");
1220 int ret
=LICE_FUNCTION_VALID(LICE_GetPixel
)?LICE_GetPixel(dest
,(int)*m_gfx_x
, (int)*m_gfx_y
):0;
1222 *r
=LICE_GETR(ret
)/255.0;
1223 *g
=LICE_GETG(ret
)/255.0;
1224 *b
=LICE_GETB(ret
)/255.0;
1229 static int __drawTextWithFont(LICE_IBitmap
*dest
, const RECT
*rect
, LICE_IFont
*font
, const char *buf
, int buflen
,
1230 int fg
, int mode
, float alpha
, int flags
, EEL_F
*wantYoutput
, EEL_F
**measureOnly
)
1232 if (font
&& LICE_FUNCTION_VALID(LICE__DrawText
))
1235 LICE__SetTextColor(font
,fg
);
1236 LICE__SetTextCombineMode(font
,mode
,alpha
);
1239 RECT r
={0,0,tr
.left
,0};
1243 while (thislen
< buflen
&& buf
[thislen
] != '\n') thislen
++;
1244 memset(&r
,0,sizeof(r
));
1245 int lineh
= LICE__DrawText(font
,dest
,buf
,thislen
?thislen
:1,&r
,DT_SINGLELINE
|DT_NOPREFIX
|DT_CALCRECT
);
1249 lineh
= LICE__DrawText(font
,dest
,buf
,thislen
?thislen
:1,&tr
,DT_SINGLELINE
|DT_NOPREFIX
|flags
);
1250 if (wantYoutput
) *wantYoutput
= tr
.top
;
1254 if (r
.right
> maxx
) maxx
=r
.right
;
1258 buflen
-= thislen
+1;
1263 measureOnly
[0][0] = maxx
;
1264 measureOnly
[1][0] = tr
.top
;
1270 int xpos
=rect
->left
, ypos
=rect
->top
;
1276 (LICE_IBitmap_disabledAPI
*)
1278 dest
,rect
->left
,rect
->top
,rect
->right
-rect
->left
,rect
->bottom
-rect
->top
);
1282 if (!(flags
& DT_NOCLIP
))
1284 if (rect
->right
<= rect
->left
|| rect
->bottom
<= rect
->top
) return 0; // invalid clip rect hm
1289 if (flags
& (DT_RIGHT
|DT_BOTTOM
|DT_CENTER
|DT_VCENTER
))
1292 EEL_F
*mo
[2] = { &w
,&h
};
1294 __drawTextWithFont(dest
,&tr
,NULL
,buf
,buflen
,0,0,0.0f
,0,NULL
,mo
);
1296 if (flags
& DT_RIGHT
) xpos
+= (rect
->right
-rect
->left
) - (int)floor(w
);
1297 else if (flags
& DT_CENTER
) xpos
+= (rect
->right
-rect
->left
)/2 - (int)floor(w
*.5);
1299 if (flags
& DT_BOTTOM
) ypos
+= (rect
->bottom
-rect
->top
) - (int)floor(h
);
1300 else if (flags
& DT_VCENTER
) ypos
+= (rect
->bottom
-rect
->top
)/2 - (int)floor(h
*.5);
1303 const int sxpos
= xpos
;
1305 if (LICE_FUNCTION_VALID(LICE_DrawChar
)) for(x
=0;x
<buflen
;x
++)
1314 case ' ': xpos
+= 8; break;
1315 case '\t': xpos
+= 8*5; break;
1317 if (!measureOnly
) LICE_DrawChar(dest
,xpos
,ypos
,buf
[x
], fg
,alpha
,mode
);
1319 if (xpos
> maxx
) maxx
=xpos
;
1326 measureOnly
[0][0]=maxx
;
1327 measureOnly
[1][0]=maxy
;
1331 if (wantYoutput
) *wantYoutput
=ypos
;
1337 void eel_lice_state::gfx_drawstr(void *opaque
, EEL_F
**parms
, int nparms
, int formatmode
)// formatmode=1 for format, 2 for purely measure no format
1339 int nfmtparms
= nparms
-1;
1340 EEL_F
**fmtparms
= parms
+1;
1341 const char *funcname
= formatmode
==1?"gfx_printf":
1342 formatmode
==2?"gfx_measurestr":
1343 formatmode
==3?"gfx_measurechar" : "gfx_drawstr";
1345 LICE_IBitmap
*dest
= GetImageForIndex(*m_gfx_dest
,funcname
);
1349 if (!LICE__GetWidth
|| !LICE__GetHeight
) return;
1352 EEL_STRING_MUTEXLOCK_SCOPE
1354 WDL_FastString
*fs
=NULL
;
1361 s_len
= WDL_MakeUTFChar(buf
, (int)parms
[0][0], sizeof(buf
));
1366 s
=EEL_STRING_GET_FOR_INDEX(parms
[0][0],&fs
);
1367 #ifdef EEL_STRING_DEBUGOUT
1368 if (!s
) EEL_STRING_DEBUGOUT("gfx_%s: invalid string identifier %f",funcname
,parms
[0][0]);
1375 else if (formatmode
==1)
1377 extern int eel_format_strings(void *, const char *s
, const char *ep
, char *, int, int, EEL_F
**);
1378 s_len
= eel_format_strings(opaque
,s
,fs
?(s
+fs
->GetLength()):NULL
,buf
,sizeof(buf
),nfmtparms
,fmtparms
);
1379 if (s_len
<1) return;
1384 s_len
= fs
?fs
->GetLength():(int)strlen(s
);
1390 SetImageDirty(dest
);
1396 __drawTextWithFont(dest
,&r
,GetActiveFont(),s
,s_len
,
1397 getCurColor(),getCurMode(),(float)*m_gfx_a
,0,NULL
,fmtparms
);
1402 RECT r
={(int)floor(*m_gfx_x
),(int)floor(*m_gfx_y
),0,0};
1403 int flags
=DT_NOCLIP
;
1404 if (formatmode
== 0 && nparms
>= 4)
1406 flags
=(int)*parms
[1];
1407 flags
&= (DT_CENTER
|DT_RIGHT
|DT_VCENTER
|DT_BOTTOM
|DT_NOCLIP
);
1408 r
.right
=(int)*parms
[2];
1409 r
.bottom
=(int)*parms
[3];
1411 *m_gfx_x
=__drawTextWithFont(dest
,&r
,GetActiveFont(),s
,s_len
,
1412 getCurColor(),getCurMode(),(float)*m_gfx_a
,flags
,m_gfx_y
,NULL
);
1417 void eel_lice_state::gfx_drawchar(EEL_F ch
)
1419 LICE_IBitmap
*dest
= GetImageForIndex(*m_gfx_dest
,"gfx_drawchar");
1422 SetImageDirty(dest
);
1424 int a
=(int)(ch
+0.5);
1425 if (a
== '\r' || a
=='\n') a
=' ';
1428 const int buflen
= WDL_MakeUTFChar(buf
, a
, sizeof(buf
));
1430 RECT r
={(int)floor(*m_gfx_x
),(int)floor(*m_gfx_y
),0,0};
1431 *m_gfx_x
= __drawTextWithFont(dest
,&r
,
1432 GetActiveFont(),buf
,buflen
,
1433 getCurColor(),getCurMode(),(float)*m_gfx_a
,DT_NOCLIP
,NULL
,NULL
);
1438 void eel_lice_state::gfx_drawnumber(EEL_F n
, EEL_F ndigits
)
1440 LICE_IBitmap
*dest
= GetImageForIndex(*m_gfx_dest
,"gfx_drawnumber");
1443 SetImageDirty(dest
);
1446 int a
=(int)(ndigits
+0.5);
1448 else if (a
> 16) a
=16;
1449 snprintf(buf
,sizeof(buf
),"%.*f",a
,n
);
1451 RECT r
={(int)floor(*m_gfx_x
),(int)floor(*m_gfx_y
),0,0};
1452 *m_gfx_x
= __drawTextWithFont(dest
,&r
,
1453 GetActiveFont(),buf
,(int)strlen(buf
),
1454 getCurColor(),getCurMode(),(float)*m_gfx_a
,DT_NOCLIP
,NULL
,NULL
);