xref: /freebsd-src/stand/ficl/gfx_loader.c (revision 6faf55c86d9b86f40de8d19970e42cb42a892c47)
19c8bf69aSWarner Losh /*-
29c8bf69aSWarner Losh  * Copyright (c) 2024 Netflix, Inc
39c8bf69aSWarner Losh  *
49c8bf69aSWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
59c8bf69aSWarner Losh  */
69c8bf69aSWarner Losh 
79c8bf69aSWarner Losh /* Copied from a file that likely shoulve have had this at the top */
89c8bf69aSWarner Losh /*-
99c8bf69aSWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
109c8bf69aSWarner Losh  *
119c8bf69aSWarner Losh  * Copyright 2020 Toomas Soome
129c8bf69aSWarner Losh  * Copyright 2020 RackTop Systems, Inc.
139c8bf69aSWarner Losh  *
149c8bf69aSWarner Losh  * Redistribution and use in source and binary forms, with or without
159c8bf69aSWarner Losh  * modification, are permitted provided that the following conditions
169c8bf69aSWarner Losh  * are met:
179c8bf69aSWarner Losh  * 1. Redistributions of source code must retain the above copyright
189c8bf69aSWarner Losh  *    notice, this list of conditions and the following disclaimer.
199c8bf69aSWarner Losh  * 2. Redistributions in binary form must reproduce the above copyright
209c8bf69aSWarner Losh  *    notice, this list of conditions and the following disclaimer in the
219c8bf69aSWarner Losh  *    documentation and/or other materials provided with the distribution.
229c8bf69aSWarner Losh  *
239c8bf69aSWarner Losh  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
249c8bf69aSWarner Losh  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
259c8bf69aSWarner Losh  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
269c8bf69aSWarner Losh  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
279c8bf69aSWarner Losh  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
289c8bf69aSWarner Losh  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
299c8bf69aSWarner Losh  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
309c8bf69aSWarner Losh  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
319c8bf69aSWarner Losh  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
329c8bf69aSWarner Losh  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
339c8bf69aSWarner Losh  * SUCH DAMAGE.
349c8bf69aSWarner Losh  */
359c8bf69aSWarner Losh 
369c8bf69aSWarner Losh /*******************************************************************
379c8bf69aSWarner Losh ** g f x _ l o a d e r . c
389c8bf69aSWarner Losh ** Additional FICL words designed for FreeBSD's loader
399c8bf69aSWarner Losh ** for graphics
409c8bf69aSWarner Losh *******************************************************************/
419c8bf69aSWarner Losh 
429c8bf69aSWarner Losh #include <stand.h>
439c8bf69aSWarner Losh #include "bootstrap.h"
449c8bf69aSWarner Losh #include <gfx_fb.h>
459c8bf69aSWarner Losh #include <pnglite.h>
469c8bf69aSWarner Losh #include "ficl.h"
479c8bf69aSWarner Losh 
489c8bf69aSWarner Losh /*		FreeBSD's loader interaction words and extras
499c8bf69aSWarner Losh  *		for graphics
509c8bf69aSWarner Losh  *		fb-bezier	( x0 y0 x1 y1 x2 y2 wd -- )
519c8bf69aSWarner Losh  *		fb-drawrect	( x1 y1 x2 y2 fill -- )
529c8bf69aSWarner Losh  *		fb-line		( x0 y0 x1 y1 wd -- )
539c8bf69aSWarner Losh  * 		fb-putimage	( flags x1 y1 x2 y2 -- flag )
549c8bf69aSWarner Losh  *		fb-setpixel	( x y -- )
559c8bf69aSWarner Losh  *		term-drawrect	( x1 y1 x2 y2 fill -- )
569c8bf69aSWarner Losh  *		term-putimage	( flags x1 y1 x2 y2 -- flag )
579c8bf69aSWarner Losh  */
589c8bf69aSWarner Losh 
599c8bf69aSWarner Losh /* ( flags x1 y1 x2 y2 -- flag ) */
609c8bf69aSWarner Losh void
ficl_term_putimage(FICL_VM * pVM)619c8bf69aSWarner Losh ficl_term_putimage(FICL_VM *pVM)
629c8bf69aSWarner Losh {
639c8bf69aSWarner Losh         char *namep, *name;
649c8bf69aSWarner Losh         int names;
659c8bf69aSWarner Losh         unsigned long ret = FICL_FALSE;
669c8bf69aSWarner Losh         uint32_t x1, y1, x2, y2, f;
679c8bf69aSWarner Losh         png_t png;
689c8bf69aSWarner Losh 	int error;
699c8bf69aSWarner Losh 
709c8bf69aSWarner Losh #if FICL_ROBUST > 1
719c8bf69aSWarner Losh 	vmCheckStack(pVM, 7, 1);
729c8bf69aSWarner Losh #endif
739c8bf69aSWarner Losh         names = stackPopINT(pVM->pStack);
749c8bf69aSWarner Losh         namep = (char *) stackPopPtr(pVM->pStack);
759c8bf69aSWarner Losh         y2 = stackPopINT(pVM->pStack);
769c8bf69aSWarner Losh         x2 = stackPopINT(pVM->pStack);
779c8bf69aSWarner Losh         y1 = stackPopINT(pVM->pStack);
789c8bf69aSWarner Losh         x1 = stackPopINT(pVM->pStack);
799c8bf69aSWarner Losh         f = stackPopINT(pVM->pStack);
809c8bf69aSWarner Losh 
819c8bf69aSWarner Losh 	x1 = gfx_state.tg_origin.tp_col + x1 * gfx_state.tg_font.vf_width;
829c8bf69aSWarner Losh 	y1 = gfx_state.tg_origin.tp_row + y1 * gfx_state.tg_font.vf_height;
839c8bf69aSWarner Losh 	if (x2 != 0) {
849c8bf69aSWarner Losh 		x2 = gfx_state.tg_origin.tp_col +
859c8bf69aSWarner Losh 		    x2 * gfx_state.tg_font.vf_width;
869c8bf69aSWarner Losh 	}
879c8bf69aSWarner Losh 	if (y2 != 0) {
889c8bf69aSWarner Losh 		y2 = gfx_state.tg_origin.tp_row +
899c8bf69aSWarner Losh 		    y2 * gfx_state.tg_font.vf_height;
909c8bf69aSWarner Losh 	}
919c8bf69aSWarner Losh 
929c8bf69aSWarner Losh         name = ficlMalloc(names + 1);
939c8bf69aSWarner Losh         if (!name)
949c8bf69aSWarner Losh 		vmThrowErr(pVM, "Error: out of memory");
959c8bf69aSWarner Losh         (void) strncpy(name, namep, names);
969c8bf69aSWarner Losh         name[names] = '\0';
979c8bf69aSWarner Losh 
989c8bf69aSWarner Losh         if ((error = png_open(&png, name)) != PNG_NO_ERROR) {
999c8bf69aSWarner Losh 		if (f & FL_PUTIMAGE_DEBUG)
1009c8bf69aSWarner Losh 			printf("%s\n", png_error_string(error));
1019c8bf69aSWarner Losh 	} else {
1029c8bf69aSWarner Losh                 if (gfx_fb_putimage(&png, x1, y1, x2, y2, f) == 0)
1039c8bf69aSWarner Losh                         ret = FICL_TRUE;        /* success */
1049c8bf69aSWarner Losh                 (void) png_close(&png);
1059c8bf69aSWarner Losh 	}
1069c8bf69aSWarner Losh         ficlFree(name);
1079c8bf69aSWarner Losh 	stackPushUNS(pVM->pStack, ret);
1089c8bf69aSWarner Losh }
1099c8bf69aSWarner Losh 
1109c8bf69aSWarner Losh /* ( flags x1 y1 x2 y2 -- flag ) */
1119c8bf69aSWarner Losh void
ficl_fb_putimage(FICL_VM * pVM)1129c8bf69aSWarner Losh ficl_fb_putimage(FICL_VM *pVM)
1139c8bf69aSWarner Losh {
1149c8bf69aSWarner Losh         char *namep, *name;
1159c8bf69aSWarner Losh         int names;
1169c8bf69aSWarner Losh         unsigned long ret = FICL_FALSE;
1179c8bf69aSWarner Losh         uint32_t x1, y1, x2, y2, f;
1189c8bf69aSWarner Losh         png_t png;
1199c8bf69aSWarner Losh 	int error;
1209c8bf69aSWarner Losh 
1219c8bf69aSWarner Losh #if FICL_ROBUST > 1
1229c8bf69aSWarner Losh 	vmCheckStack(pVM, 7, 1);
1239c8bf69aSWarner Losh #endif
1249c8bf69aSWarner Losh         names = stackPopINT(pVM->pStack);
1259c8bf69aSWarner Losh         namep = (char *) stackPopPtr(pVM->pStack);
1269c8bf69aSWarner Losh         y2 = stackPopINT(pVM->pStack);
1279c8bf69aSWarner Losh         x2 = stackPopINT(pVM->pStack);
1289c8bf69aSWarner Losh         y1 = stackPopINT(pVM->pStack);
1299c8bf69aSWarner Losh         x1 = stackPopINT(pVM->pStack);
1309c8bf69aSWarner Losh         f = stackPopINT(pVM->pStack);
1319c8bf69aSWarner Losh 
1329c8bf69aSWarner Losh         name = ficlMalloc(names + 1);
1339c8bf69aSWarner Losh         if (!name)
1349c8bf69aSWarner Losh 		vmThrowErr(pVM, "Error: out of memory");
1359c8bf69aSWarner Losh         (void) strncpy(name, namep, names);
1369c8bf69aSWarner Losh         name[names] = '\0';
1379c8bf69aSWarner Losh 
1389c8bf69aSWarner Losh         if ((error = png_open(&png, name)) != PNG_NO_ERROR) {
1399c8bf69aSWarner Losh 		if (f & FL_PUTIMAGE_DEBUG)
1409c8bf69aSWarner Losh 			printf("%s\n", png_error_string(error));
1419c8bf69aSWarner Losh 	} else {
1429c8bf69aSWarner Losh                 if (gfx_fb_putimage(&png, x1, y1, x2, y2, f) == 0)
1439c8bf69aSWarner Losh                         ret = FICL_TRUE;        /* success */
1449c8bf69aSWarner Losh                 (void) png_close(&png);
1459c8bf69aSWarner Losh 	}
1469c8bf69aSWarner Losh         ficlFree(name);
1479c8bf69aSWarner Losh 	stackPushUNS(pVM->pStack, ret);
1489c8bf69aSWarner Losh }
1499c8bf69aSWarner Losh 
1509c8bf69aSWarner Losh void
ficl_fb_setpixel(FICL_VM * pVM)1519c8bf69aSWarner Losh ficl_fb_setpixel(FICL_VM *pVM)
1529c8bf69aSWarner Losh {
1539c8bf69aSWarner Losh         FICL_UNS x, y;
1549c8bf69aSWarner Losh 
1559c8bf69aSWarner Losh #if FICL_ROBUST > 1
1569c8bf69aSWarner Losh 	vmCheckStack(pVM, 2, 0);
1579c8bf69aSWarner Losh #endif
1589c8bf69aSWarner Losh 
1599c8bf69aSWarner Losh         y = stackPopUNS(pVM->pStack);
1609c8bf69aSWarner Losh         x = stackPopUNS(pVM->pStack);
1619c8bf69aSWarner Losh         gfx_fb_setpixel(x, y);
1629c8bf69aSWarner Losh }
1639c8bf69aSWarner Losh 
1649c8bf69aSWarner Losh void
ficl_fb_line(FICL_VM * pVM)1659c8bf69aSWarner Losh ficl_fb_line(FICL_VM *pVM)
1669c8bf69aSWarner Losh {
1679c8bf69aSWarner Losh 	FICL_UNS x0, y0, x1, y1, wd;
1689c8bf69aSWarner Losh 
1699c8bf69aSWarner Losh #if FICL_ROBUST > 1
1709c8bf69aSWarner Losh 	vmCheckStack(pVM, 5, 0);
1719c8bf69aSWarner Losh #endif
1729c8bf69aSWarner Losh 
1739c8bf69aSWarner Losh 	wd = stackPopUNS(pVM->pStack);
1749c8bf69aSWarner Losh 	y1 = stackPopUNS(pVM->pStack);
1759c8bf69aSWarner Losh 	x1 = stackPopUNS(pVM->pStack);
1769c8bf69aSWarner Losh 	y0 = stackPopUNS(pVM->pStack);
1779c8bf69aSWarner Losh 	x0 = stackPopUNS(pVM->pStack);
1789c8bf69aSWarner Losh 	gfx_fb_line(x0, y0, x1, y1, wd);
1799c8bf69aSWarner Losh }
1809c8bf69aSWarner Losh 
1819c8bf69aSWarner Losh void
ficl_fb_bezier(FICL_VM * pVM)1829c8bf69aSWarner Losh ficl_fb_bezier(FICL_VM *pVM)
1839c8bf69aSWarner Losh {
1849c8bf69aSWarner Losh 	FICL_UNS x0, y0, x1, y1, x2, y2, width;
1859c8bf69aSWarner Losh 
1869c8bf69aSWarner Losh #if FICL_ROBUST > 1
1879c8bf69aSWarner Losh 	vmCheckStack(pVM, 7, 0);
1889c8bf69aSWarner Losh #endif
1899c8bf69aSWarner Losh 
1909c8bf69aSWarner Losh 	width = stackPopUNS(pVM->pStack);
1919c8bf69aSWarner Losh 	y2 = stackPopUNS(pVM->pStack);
1929c8bf69aSWarner Losh 	x2 = stackPopUNS(pVM->pStack);
1939c8bf69aSWarner Losh 	y1 = stackPopUNS(pVM->pStack);
1949c8bf69aSWarner Losh 	x1 = stackPopUNS(pVM->pStack);
1959c8bf69aSWarner Losh 	y0 = stackPopUNS(pVM->pStack);
1969c8bf69aSWarner Losh 	x0 = stackPopUNS(pVM->pStack);
1979c8bf69aSWarner Losh 	gfx_fb_bezier(x0, y0, x1, y1, x2, y2, width);
1989c8bf69aSWarner Losh }
1999c8bf69aSWarner Losh 
2009c8bf69aSWarner Losh void
ficl_fb_drawrect(FICL_VM * pVM)2019c8bf69aSWarner Losh ficl_fb_drawrect(FICL_VM *pVM)
2029c8bf69aSWarner Losh {
2039c8bf69aSWarner Losh 	FICL_UNS x1, x2, y1, y2, fill;
2049c8bf69aSWarner Losh 
2059c8bf69aSWarner Losh #if FICL_ROBUST > 1
2069c8bf69aSWarner Losh 	vmCheckStack(pVM, 5, 0);
2079c8bf69aSWarner Losh #endif
2089c8bf69aSWarner Losh 
2099c8bf69aSWarner Losh 	fill = stackPopUNS(pVM->pStack);
2109c8bf69aSWarner Losh 	y2 = stackPopUNS(pVM->pStack);
2119c8bf69aSWarner Losh 	x2 = stackPopUNS(pVM->pStack);
2129c8bf69aSWarner Losh 	y1 = stackPopUNS(pVM->pStack);
2139c8bf69aSWarner Losh 	x1 = stackPopUNS(pVM->pStack);
2149c8bf69aSWarner Losh 	gfx_fb_drawrect(x1, y1, x2, y2, fill);
2159c8bf69aSWarner Losh }
2169c8bf69aSWarner Losh 
2179c8bf69aSWarner Losh void
ficl_term_drawrect(FICL_VM * pVM)2189c8bf69aSWarner Losh ficl_term_drawrect(FICL_VM *pVM)
2199c8bf69aSWarner Losh {
2209c8bf69aSWarner Losh 	FICL_UNS x1, x2, y1, y2;
2219c8bf69aSWarner Losh 
2229c8bf69aSWarner Losh #if FICL_ROBUST > 1
2239c8bf69aSWarner Losh 	vmCheckStack(pVM, 4, 0);
2249c8bf69aSWarner Losh #endif
2259c8bf69aSWarner Losh 
2269c8bf69aSWarner Losh 	y2 = stackPopUNS(pVM->pStack);
2279c8bf69aSWarner Losh 	x2 = stackPopUNS(pVM->pStack);
2289c8bf69aSWarner Losh 	y1 = stackPopUNS(pVM->pStack);
2299c8bf69aSWarner Losh 	x1 = stackPopUNS(pVM->pStack);
2309c8bf69aSWarner Losh 	gfx_term_drawrect(x1, y1, x2, y2);
2319c8bf69aSWarner Losh }
2329c8bf69aSWarner Losh 
2339c8bf69aSWarner Losh /**************************************************************************
2349c8bf69aSWarner Losh                         f i c l C o m p i l e G f x
2359c8bf69aSWarner Losh ** Build FreeBSD platform extensions into the system dictionary
2369c8bf69aSWarner Losh ** for gfx
2379c8bf69aSWarner Losh **************************************************************************/
ficlCompileGfx(FICL_SYSTEM * pSys)2389c8bf69aSWarner Losh static void ficlCompileGfx(FICL_SYSTEM *pSys)
2399c8bf69aSWarner Losh {
2409c8bf69aSWarner Losh     ficlCompileFcn **fnpp;
2419c8bf69aSWarner Losh     FICL_DICT *dp = pSys->dp;
2429c8bf69aSWarner Losh     assert (dp);
2439c8bf69aSWarner Losh 
2449c8bf69aSWarner Losh     dictAppendWord(dp, "fb-setpixel", ficl_fb_setpixel, FW_DEFAULT);
2459c8bf69aSWarner Losh     dictAppendWord(dp, "fb-line", ficl_fb_line, FW_DEFAULT);
2469c8bf69aSWarner Losh     dictAppendWord(dp, "fb-bezier", ficl_fb_bezier, FW_DEFAULT);
2479c8bf69aSWarner Losh     dictAppendWord(dp, "fb-drawrect", ficl_fb_drawrect, FW_DEFAULT);
2489c8bf69aSWarner Losh     dictAppendWord(dp, "fb-putimage", ficl_fb_putimage, FW_DEFAULT);
2499c8bf69aSWarner Losh     dictAppendWord(dp, "term-drawrect", ficl_term_drawrect, FW_DEFAULT);
2509c8bf69aSWarner Losh     dictAppendWord(dp, "term-putimage", ficl_term_putimage, FW_DEFAULT);
2519c8bf69aSWarner Losh 
2529c8bf69aSWarner Losh     return;
2539c8bf69aSWarner Losh }
2549c8bf69aSWarner Losh FICL_COMPILE_SET(ficlCompileGfx);
2559c8bf69aSWarner Losh 
2569c8bf69aSWarner Losh void
gfx_interp_ref(void)257*6faf55c8SWarner Losh gfx_interp_ref(void)
2589c8bf69aSWarner Losh {
2599c8bf69aSWarner Losh }
260