' ' This is an image loader plugin for the CANVAS context. It uses libXpm. PvE - MIT License 2017. ' ' XPM_IMAGE(data$, xpos, ypos) ' data$: array with XPM definition ' xpos: x position of the centre of the picture on the canvas ' ypos: y position of the centre of the picture on the canvas ' ' XPM_IMAGE_INFO(data$) ---> print information on console about picture ' data$: array with XPM definition ' ' XPM_IMAGE_WIDTH(data$) ' data$: array with XPM definition ' ' XPM_IMAGE_HEIGHT(data$) ' data$: array with XPM definition ' ' XPM_IMAGE_FREE ' Release resources ' ' No file API. When the SVG definition is kept in a file, then load it using PRAGMA and pass the array variable to XPM_IMAGE: ' ' PRAGMA INCLUDE file.xpm ' '----------------------------------------------------------------------------------------------------------------------------------- PROTO free DECLARE XPM_IMAGE_FUNCTION_FOUND : ' To remember if the XPM function was already found DECLARE XPM_IMAGE_DPY TYPE void* : ' Channel for Xserver RECORD XPM_XIMAGE : ' Type for loaded XPM images LOCAL width, height, xoffset, format TYPE int LOCAL data TYPE char* ENDRECORD SUB XPM_IMAGE_FIND_FUNC : ' Find libXpm library on the system and import function LOCAL lib$ LOCAL seq = -1 CATCH GOTO lib_import_retry lib$ = "libXpm.so.0" LABEL lib_import_retry INCR seq IF seq > 100 THEN EPRINT "libXpm not found! Cannot draw XPM. Exiting..." END ENDIF lib$ = LEFT$(lib$, INSTRREV(lib$, ".")) & STR$(seq) IMPORT "XpmCreateImageFromData" FROM lib$ TYPE void* CATCH RESET XPM_IMAGE_FUNCTION_FOUND = TRUE XPM_IMAGE_DPY = XOpenDisplay(NULL) END SUB SUB XPM_IMAGE(char **data, xpos, ypos) LOCAL img, clp TYPE XPM_XIMAGE_type* LOCAL width, height, texture TYPE int LOCAL xim, x, y IF NOT(XPM_IMAGE_FUNCTION_FOUND) THEN CALL XPM_IMAGE_FIND_FUNC() : ' Get XPM loader if needed xim = XpmCreateImageFromData(XPM_IMAGE_DPY, data, &img, &clp, NULL) : ' Convert the data to BGR values. We fill in alpha in the next step. width = img->width height = img->height IF clp <> NULL THEN OPTION MEMTYPE unsigned char FOR y = 0 TO height-1 : ' Fill in alpha channel by checking mask FOR x = 0 TO (width-1)*4 STEP 4 IF PEEK(clp->data+y*((width-1)/8+1)+(x/4)/8) & BIT((x/4) & 7) THEN : ' y offset in clipping is always at least 1 byte if width=0-7 POKE img->data+y*width*4+x+3, 255 ELSE POKE img->data+y*width*4+x+3, 0 ENDIF NEXT NEXT ENDIF CALL Draw_Prepare : ' Setup 2D canvas with (0,0) top left glPixelStorei(GL_UNPACK_ROW_LENGTH, width) : ' Set the row length of the data array glGenTextures(1, &texture) glBindTexture(GL_TEXTURE_2D, texture) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, img->data) glColor4ub(255,255,255,255) : ' Prevent color mixup with the texture glEnable(GL_TEXTURE_2D) glBegin(GL_QUADS) glTexCoord2f(0.0f, 0.0f) : glVertex2f(xpos-width/2, ypos-height/2) glTexCoord2f(0.0f, 1.0f) : glVertex2f(xpos-width/2, ypos+height/2-1) glTexCoord2f(1.0f, 1.0f) : glVertex2f(xpos+width/2, ypos+height/2-1) glTexCoord2f(1.0f, 0.0f) : glVertex2f(xpos+width/2, ypos-height/2) glEnd() glDisable(GL_TEXTURE_2D) glBindTexture(GL_TEXTURE_2D, 0) glDeleteTextures(1, &texture) glPixelStorei(GL_UNPACK_ROW_LENGTH, 0) : ' Restore the row length free(img->data) : ' Free image buffer free(clp->data) : ' Free clipping buffer XFree(img) : ' Free the record allocation (ximage) XFree(clp) : ' Free the record allocation (ximage) END SUB SUB XPM_IMAGE_INFO(char **data) LOCAL img TYPE XPM_XIMAGE_type* LOCAL xim IF NOT(XPM_IMAGE_FUNCTION_FOUND) THEN CALL XPM_IMAGE_FIND_FUNC() : ' Get XPM loader if needed xim = XpmCreateImageFromData(XPM_IMAGE_DPY, data, &img, NULL, NULL) : ' Convert the data to BGR values. PRINT "Dimensions: ", img->width, "x", img->height END SUB FUNCTION XPM_IMAGE_WIDTH(char **data) LOCAL img TYPE XPM_XIMAGE_type* LOCAL xim IF NOT(XPM_IMAGE_FUNCTION_FOUND) THEN CALL XPM_IMAGE_FIND_FUNC() : ' Get XPM loader if needed xim = XpmCreateImageFromData(XPM_IMAGE_DPY, data, &img, NULL, NULL) : ' Convert the data to BGR values. RETURN img->width ENDFUNCTION FUNCTION XPM_IMAGE_HEIGHT(char **data) LOCAL img TYPE XPM_XIMAGE_type* LOCAL xim IF NOT(XPM_IMAGE_FUNCTION_FOUND) THEN CALL XPM_IMAGE_FIND_FUNC() : ' Get XPM loader if needed xim = XpmCreateImageFromData(XPM_IMAGE_DPY, data, &img, NULL, NULL) : ' Convert the data to BGR values. RETURN img->height ENDFUNCTION SUB XPM_IMAGE_FREE XCloseDisplay(XPM_IMAGE_DPY) END SUB