1 /*- 2 * Copyright (c) 2024 Netflix, Inc 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7 /* Copied from a file that likely shoulve have had this at the top */ 8 /*- 9 * SPDX-License-Identifier: BSD-2-Clause 10 * 11 * Copyright 2020 Toomas Soome 12 * Copyright 2020 RackTop Systems, Inc. 13 * 14 * Redistribution and use in source and binary forms, with or without 15 * modification, are permitted provided that the following conditions 16 * are met: 17 * 1. Redistributions of source code must retain the above copyright 18 * notice, this list of conditions and the following disclaimer. 19 * 2. Redistributions in binary form must reproduce the above copyright 20 * notice, this list of conditions and the following disclaimer in the 21 * documentation and/or other materials provided with the distribution. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36 /******************************************************************* 37 ** g f x _ l o a d e r . c 38 ** Additional FICL words designed for FreeBSD's loader 39 ** for graphics 40 *******************************************************************/ 41 42 #include <stand.h> 43 #include "bootstrap.h" 44 #include <gfx_fb.h> 45 #include <pnglite.h> 46 #include "ficl.h" 47 48 /* FreeBSD's loader interaction words and extras 49 * for graphics 50 * fb-bezier ( x0 y0 x1 y1 x2 y2 wd -- ) 51 * fb-drawrect ( x1 y1 x2 y2 fill -- ) 52 * fb-line ( x0 y0 x1 y1 wd -- ) 53 * fb-putimage ( flags x1 y1 x2 y2 -- flag ) 54 * fb-setpixel ( x y -- ) 55 * term-drawrect ( x1 y1 x2 y2 fill -- ) 56 * term-putimage ( flags x1 y1 x2 y2 -- flag ) 57 */ 58 59 /* ( flags x1 y1 x2 y2 -- flag ) */ 60 void 61 ficl_term_putimage(FICL_VM *pVM) 62 { 63 char *namep, *name; 64 int names; 65 unsigned long ret = FICL_FALSE; 66 uint32_t x1, y1, x2, y2, f; 67 png_t png; 68 int error; 69 70 #if FICL_ROBUST > 1 71 vmCheckStack(pVM, 7, 1); 72 #endif 73 names = stackPopINT(pVM->pStack); 74 namep = (char *) stackPopPtr(pVM->pStack); 75 y2 = stackPopINT(pVM->pStack); 76 x2 = stackPopINT(pVM->pStack); 77 y1 = stackPopINT(pVM->pStack); 78 x1 = stackPopINT(pVM->pStack); 79 f = stackPopINT(pVM->pStack); 80 81 x1 = gfx_state.tg_origin.tp_col + x1 * gfx_state.tg_font.vf_width; 82 y1 = gfx_state.tg_origin.tp_row + y1 * gfx_state.tg_font.vf_height; 83 if (x2 != 0) { 84 x2 = gfx_state.tg_origin.tp_col + 85 x2 * gfx_state.tg_font.vf_width; 86 } 87 if (y2 != 0) { 88 y2 = gfx_state.tg_origin.tp_row + 89 y2 * gfx_state.tg_font.vf_height; 90 } 91 92 name = ficlMalloc(names + 1); 93 if (!name) 94 vmThrowErr(pVM, "Error: out of memory"); 95 (void) strncpy(name, namep, names); 96 name[names] = '\0'; 97 98 if ((error = png_open(&png, name)) != PNG_NO_ERROR) { 99 if (f & FL_PUTIMAGE_DEBUG) 100 printf("%s\n", png_error_string(error)); 101 } else { 102 if (gfx_fb_putimage(&png, x1, y1, x2, y2, f) == 0) 103 ret = FICL_TRUE; /* success */ 104 (void) png_close(&png); 105 } 106 ficlFree(name); 107 stackPushUNS(pVM->pStack, ret); 108 } 109 110 /* ( flags x1 y1 x2 y2 -- flag ) */ 111 void 112 ficl_fb_putimage(FICL_VM *pVM) 113 { 114 char *namep, *name; 115 int names; 116 unsigned long ret = FICL_FALSE; 117 uint32_t x1, y1, x2, y2, f; 118 png_t png; 119 int error; 120 121 #if FICL_ROBUST > 1 122 vmCheckStack(pVM, 7, 1); 123 #endif 124 names = stackPopINT(pVM->pStack); 125 namep = (char *) stackPopPtr(pVM->pStack); 126 y2 = stackPopINT(pVM->pStack); 127 x2 = stackPopINT(pVM->pStack); 128 y1 = stackPopINT(pVM->pStack); 129 x1 = stackPopINT(pVM->pStack); 130 f = stackPopINT(pVM->pStack); 131 132 name = ficlMalloc(names + 1); 133 if (!name) 134 vmThrowErr(pVM, "Error: out of memory"); 135 (void) strncpy(name, namep, names); 136 name[names] = '\0'; 137 138 if ((error = png_open(&png, name)) != PNG_NO_ERROR) { 139 if (f & FL_PUTIMAGE_DEBUG) 140 printf("%s\n", png_error_string(error)); 141 } else { 142 if (gfx_fb_putimage(&png, x1, y1, x2, y2, f) == 0) 143 ret = FICL_TRUE; /* success */ 144 (void) png_close(&png); 145 } 146 ficlFree(name); 147 stackPushUNS(pVM->pStack, ret); 148 } 149 150 void 151 ficl_fb_setpixel(FICL_VM *pVM) 152 { 153 FICL_UNS x, y; 154 155 #if FICL_ROBUST > 1 156 vmCheckStack(pVM, 2, 0); 157 #endif 158 159 y = stackPopUNS(pVM->pStack); 160 x = stackPopUNS(pVM->pStack); 161 gfx_fb_setpixel(x, y); 162 } 163 164 void 165 ficl_fb_line(FICL_VM *pVM) 166 { 167 FICL_UNS x0, y0, x1, y1, wd; 168 169 #if FICL_ROBUST > 1 170 vmCheckStack(pVM, 5, 0); 171 #endif 172 173 wd = stackPopUNS(pVM->pStack); 174 y1 = stackPopUNS(pVM->pStack); 175 x1 = stackPopUNS(pVM->pStack); 176 y0 = stackPopUNS(pVM->pStack); 177 x0 = stackPopUNS(pVM->pStack); 178 gfx_fb_line(x0, y0, x1, y1, wd); 179 } 180 181 void 182 ficl_fb_bezier(FICL_VM *pVM) 183 { 184 FICL_UNS x0, y0, x1, y1, x2, y2, width; 185 186 #if FICL_ROBUST > 1 187 vmCheckStack(pVM, 7, 0); 188 #endif 189 190 width = stackPopUNS(pVM->pStack); 191 y2 = stackPopUNS(pVM->pStack); 192 x2 = stackPopUNS(pVM->pStack); 193 y1 = stackPopUNS(pVM->pStack); 194 x1 = stackPopUNS(pVM->pStack); 195 y0 = stackPopUNS(pVM->pStack); 196 x0 = stackPopUNS(pVM->pStack); 197 gfx_fb_bezier(x0, y0, x1, y1, x2, y2, width); 198 } 199 200 void 201 ficl_fb_drawrect(FICL_VM *pVM) 202 { 203 FICL_UNS x1, x2, y1, y2, fill; 204 205 #if FICL_ROBUST > 1 206 vmCheckStack(pVM, 5, 0); 207 #endif 208 209 fill = stackPopUNS(pVM->pStack); 210 y2 = stackPopUNS(pVM->pStack); 211 x2 = stackPopUNS(pVM->pStack); 212 y1 = stackPopUNS(pVM->pStack); 213 x1 = stackPopUNS(pVM->pStack); 214 gfx_fb_drawrect(x1, y1, x2, y2, fill); 215 } 216 217 void 218 ficl_term_drawrect(FICL_VM *pVM) 219 { 220 FICL_UNS x1, x2, y1, y2; 221 222 #if FICL_ROBUST > 1 223 vmCheckStack(pVM, 4, 0); 224 #endif 225 226 y2 = stackPopUNS(pVM->pStack); 227 x2 = stackPopUNS(pVM->pStack); 228 y1 = stackPopUNS(pVM->pStack); 229 x1 = stackPopUNS(pVM->pStack); 230 gfx_term_drawrect(x1, y1, x2, y2); 231 } 232 233 /************************************************************************** 234 f i c l C o m p i l e G f x 235 ** Build FreeBSD platform extensions into the system dictionary 236 ** for gfx 237 **************************************************************************/ 238 static void ficlCompileGfx(FICL_SYSTEM *pSys) 239 { 240 ficlCompileFcn **fnpp; 241 FICL_DICT *dp = pSys->dp; 242 assert (dp); 243 244 dictAppendWord(dp, "fb-setpixel", ficl_fb_setpixel, FW_DEFAULT); 245 dictAppendWord(dp, "fb-line", ficl_fb_line, FW_DEFAULT); 246 dictAppendWord(dp, "fb-bezier", ficl_fb_bezier, FW_DEFAULT); 247 dictAppendWord(dp, "fb-drawrect", ficl_fb_drawrect, FW_DEFAULT); 248 dictAppendWord(dp, "fb-putimage", ficl_fb_putimage, FW_DEFAULT); 249 dictAppendWord(dp, "term-drawrect", ficl_term_drawrect, FW_DEFAULT); 250 dictAppendWord(dp, "term-putimage", ficl_term_putimage, FW_DEFAULT); 251 252 return; 253 } 254 FICL_COMPILE_SET(ficlCompileGfx); 255 256 void 257 gfx_interp_ref(void) 258 { 259 } 260