32#include <system_fonts.h>
37#include <libFreeWRL.h>
39#include "../vrml_parser/Structs.h"
40#include "../input/InputFunctions.h"
41#include "../main/headers.h"
42#include "../scenegraph/Viewer.h"
43#include "../opengl/OpenGL_Utils.h"
44#include "../opengl/Textures.h"
47#include "LinearAlgebra.h"
48#include "Component_Shape.h"
49#include "../scenegraph/Tess.h"
50#include "../scenegraph/Polyrep.h"
51#include "../x3d_parser/Bindable.h"
61#define HAVE_COMPILED_IN_FONT 1
72#define TOPTOBOTTOM (fsparam & 0x04)
73#define LEFTTORIGHT (fsparam & 0x02)
74#define HORIZONTAL (fsparam & 0x01)
179#define OUT2GLB(a,s) ((double)(a) * p->size/64.0 / p->pointsize * (double)PPI/(double)XRES *s)
215 int iglyphstartindex;
235#if defined(_ANDROID) || defined(IPHONE)
239 FILE *androidFontFile;
247 FT_Face font_face[num_fonts];
248 int font_state[num_fonts];
252 #define MAX_GLYPHS 2048
253 FT_Glyph glyphs[MAX_GLYPHS];
260 FT_Outline_Funcs FW_outline_interface;
264 #define fp_name_len 256
265 char *font_directory;
266 char thisfontname[fp_name_len];
270 double shrink_x, shrink_y;
292 FT_Vector last_point;
297 GLfloat *textpanel_vert;
298 GLfloat *textpanel_tex;
299 GLuint *textpanel_ind;
301 int textpanel_vert_size;
302 int textpanel_tex_size;
303 int textpanel_ind_size;
304 struct Vector *font_table;
305 struct Vector *atlas_table;
314 GLuint projectionLoc;
315 GLuint programObject;
319void *Component_Text_constructor(){
324void Component_Text_init(
struct tComponent_Text *t){
327 t->prv = Component_Text_constructor();
329 ppComponent_Text p = (ppComponent_Text)t->prv;
331 p->TextVerbose = FALSE;
332 p->font_directory = NULL;
335 p->rowvec_allocn = 0;
338 p->textpanel_vert = NULL;
339 p->textpanel_tex = NULL;
340 p->textpanel_ind = NULL;
341 p->textpanel_size = 0;
342 p->font_table = NULL;
343 p->atlas_table = NULL;
345 p->programObject = 0;
353static void GUItablefree(
struct Vector **guitable);
354static void dug9gui_DrawSubImage(
float xpos,
float ypos,
float xsize,
float ysize,
int ix,
int iy,
int iw,
int ih,
int width,
int height,
int bpp,
unsigned char *buffer);
355void finishedWithGlobalShader(
void);
356void restoreGlobalShader();
357GLuint esLoadProgram (
const char *vertShaderSrc,
const char *fragShaderSrc );
358static int FW_Open_Face(FT_Library library,
char *thisfontname,
int faceIndex, FT_Face *face);
362void Component_Text_clear(
struct tComponent_Text *t){
366 ppComponent_Text p = (ppComponent_Text)t->prv;
367 FREE_IF_NZ(p->font_directory);
371 for(row=0;row<p->rowvec_allocn;row++){
372 FREE_IF_NZ(p->rowvec[row].str32);
373 FREE_IF_NZ(p->rowvec[row].chr);
375 FREE_IF_NZ(p->rowvec);
377 if(p->textpanel_size){
378 FREE_IF_NZ(p->textpanel_vert);
379 FREE_IF_NZ(p->textpanel_tex);
380 FREE_IF_NZ(p->textpanel_ind);
383 GUItablefree(&p->atlas_table);
386 GUItablefree(&p->font_table);
393void fwl_fontFileLocation(
char *fontFileLocation) {
395 ttglobal tg = gglobal();
396 p = (ppComponent_Text)tg->Component_Text.prv;
398 if (fontFileLocation){
399 char * lfontFileLocation = STRDUP(fontFileLocation);
400 if(strstr(lfontFileLocation,
".ttf")){
402 char * pend = strrchr(lfontFileLocation,
'/');
403 if(pend) *pend =
'\0';
405 if (do_dir_exists(lfontFileLocation)) {
406 FREE_IF_NZ(p->font_directory);
407 p->font_directory = lfontFileLocation;
413static void FW_NewVertexPoint();
414static int FW_moveto (FT_Vector* to,
void* user);
415static int FW_lineto(FT_Vector* to,
void* user);
416static int FW_conicto(FT_Vector* control, FT_Vector* to,
void* user);
417static int FW_cubicto(FT_Vector* control1, FT_Vector* control2, FT_Vector* to,
void* user);
418static void FW_make_fontname (
int num);
419static void render_screentext(
struct X3D_Text * node);
424static FT_Error FW_Load_Char(
unsigned int idx);
425static void FW_draw_outline(FT_OutlineGlyph oglyph);
426static void FW_draw_character(FT_Glyph glyph);
427static int open_font(
void);
429#if defined(_ANDROID) || defined(IPHONE)
431void fwg_AndroidFontFile(FILE *myFile,
int len) {
432 ppComponent_Text p = (ppComponent_Text)gglobal()->Component_Text.prv;
433 p->androidFontFile = myFile;
440void render_Text (
struct X3D_Text * node)
444 render_screentext(node);
447 if (!compile_poly_if_required(node, NULL, NULL, NULL, NULL, NULL))
return;
449 CULL_FACE(node->solid)
450 render_polyrep(node);
455static
void FW_NewVertexPoint ()
459 ttglobal tg = gglobal();
460 p = (ppComponent_Text)tg->Component_Text.prv;
506 p->FW_rep_->actualCoord[p->FW_pointctr*3+0] = (float) (OUT2GLB(p->last_point.x,p->shrink_x) + p->pen_x);
507 p->FW_rep_->actualCoord[p->FW_pointctr*3+1] = (float) (OUT2GLB(p->last_point.y,p->shrink_y) + p->pen_y);
508 p->FW_rep_->actualCoord[p->FW_pointctr*3+2] = p->TextZdist;
511 if (p->FW_RIA_indx >500) {
512 ConsoleMessage (
"Text, relative index too small\n");
513 freewrlDie(
"FW_NewVertexPoint: this should never happen...");
516 p->FW_RIA[p->FW_RIA_indx]=p->FW_pointctr;
517 v2[0]=p->FW_rep_->actualCoord[p->FW_pointctr*3+0];
518 v2[1]=p->FW_rep_->actualCoord[p->FW_pointctr*3+1];
519 v2[2]=p->FW_rep_->actualCoord[p->FW_pointctr*3+2];
522 FW_GLU_TESS_VERTEX(tg->Tess.text_tessobj,v2,&p->FW_RIA[p->FW_RIA_indx]);
524 if (p->TextVerbose) {
525 printf (
"FW_NewVertexPoint %f %f %f index %d\n",
526 p->FW_rep_->actualCoord[p->FW_pointctr*3+0],
527 p->FW_rep_->actualCoord[p->FW_pointctr*3+1],
528 p->FW_rep_->actualCoord[p->FW_pointctr*3+2],
534 if (p->FW_pointctr >= p->coordmaxsize) {
535 p->coordmaxsize+=800;
536 p->FW_rep_->actualCoord = (
float *)REALLOC(p->FW_rep_->actualCoord,
537 sizeof(*(p->FW_rep_->actualCoord))*p->coordmaxsize*3);
538 printf(
"realloc actualCoord=%p\n",p->FW_rep_->actualCoord);
541#define GLU_UNKNOWN 100124
542static int FW_moveto (FT_Vector* to,
void* user)
545 ttglobal tg = gglobal();
546 p = (ppComponent_Text)tg->Component_Text.prv;
550 if (p->contour_started) {
551 FW_GLU_NEXT_CONTOUR(tg->Tess.text_tessobj,GLU_UNKNOWN);
555 p->contour_started = TRUE;
557 p->last_point.x = to->x; p->last_point.y = to->y;
560 printf (
"FW_moveto tox %ld toy %ld\n",to->x, to->y);
567static int FW_lineto (FT_Vector* to,
void* user)
569 ppComponent_Text p = (ppComponent_Text)gglobal()->Component_Text.prv;
573 if ((p->last_point.x == to->x) && (p->last_point.y == to->y)) {
578 p->last_point.x = to->x;
579 p->last_point.y = to->y;
581 if (p->TextVerbose) {
582 printf (
"FW_lineto, going to %ld %ld\n",to->x, to->y);
592static int FW_conicto (FT_Vector* control, FT_Vector* to,
void* user)
595 ppComponent_Text p = (ppComponent_Text)gglobal()->Component_Text.prv;
602 printf (
"FW_conicto\n");
605 ncontrol.x = (int) ((
double) 0.25*p->last_point.x + 0.5*control->x + 0.25*to->x);
606 ncontrol.y = (int) ((
double) 0.25*p->last_point.y + 0.5*control->y + 0.25*to->y);
611 FW_lineto (&ncontrol,user);
619static int FW_cubicto (FT_Vector* control1, FT_Vector* control2, FT_Vector* to,
void* user)
621 ppComponent_Text p = (ppComponent_Text)gglobal()->Component_Text.prv;
624 printf (
"FW_cubicto\n");
626 FW_lineto (control1, user);
627 FW_lineto (control2, user);
628 FW_lineto (to, user);
648} font_name_table [] = {
650 {
"VeraSe",
"serif", NULL, NULL, 0x04,0,0,1},
651 {
"VeraSeBd",
"serif",
"bold", NULL, 0x05,1,0,1},
652 {
"VeraSe",
"serif",
"italic", NULL, 0x06,0,1,1},
653 {
"VeraSeBd",
"serif",
"bold italic",
"bold oblique", 0x07,1,1,1},
654 {
"Vera",
"sans", NULL, NULL, 0x08,0,0,2},
655 {
"VeraBd",
"sans",
"bold", NULL, 0x09,0,1,2},
656 {
"VeraIt",
"sans",
"italic", NULL, 0x0a,1,0,2},
657 {
"VeraBI",
"sans",
"bold italic",
"bold oblique", 0x0b,1,1,2},
658 {
"VeraMono",
"monospace",NULL, NULL, 0x10,0,0,4},
659 {
"VeraMoBd",
"monospace",
"bold", NULL, 0x11,1,0,4},
660 {
"VeraMoIt",
"monospace",
"italic", NULL, 0x12,0,1,4},
661 {
"VeraMoBI",
"monospace",
"bold italic",
"bold oblique", 0x13,1,1,4},
662 {NULL, NULL, NULL, NULL, 0,0,0,0},
664struct name_num *get_fontname_entry_by_num(
int num){
668 while(font_name_table[i].facename){
669 if(font_name_table[i].num == num) {
670 retval = &font_name_table[i];
677struct name_num *get_fontname_entry_by_facename(
char *facename){
681 while(font_name_table[i].facename){
682 if(!strcmp(font_name_table[i].facename,facename)) {
683 retval = &font_name_table[i];
690char *facename_from_num(
int num){
694 val = get_fontname_entry_by_num(num);
695 if(val) retval = val->facename;
700#ifdef HAVE_FONTCONFIG
701void FW_make_fontname(
int num) {
729 ppComponent_Text p = (ppComponent_Text)gglobal()->Component_Text.prv;
730 FcPattern *FW_fp=NULL;
731 FcChar8 *FW_file=NULL;
735 char* configfile = (
char*)FcConfigFilename(0);
736 FILE*fi = fopen(configfile,
"rb");
745 printf(
"<debug> FontConfig Initialization failed.\n");
747 FcConfig * config = FcConfigGetCurrent();
749 printf(
"<debug> FontConfig Config Initialization failed.\n");
752 FcFontSet *set = FcConfigGetFonts(config, FcSetSystem);
754 if(!set || !set->nfont) {
755 printf(
"<debug> FontConfig has found zero fonts. This is probably a bad thing.\n");
760 FW_fp=FcPatternBuild(NULL,FC_FAMILY,FcTypeString,
"serif",FC_OUTLINE,FcTypeBool,FcTrue,NULL);
763 FW_fp=FcPatternBuild(NULL,FC_FAMILY,FcTypeString,
"serif",FC_OUTLINE,FcTypeBool,FcTrue,NULL);
764 FcPatternAddString(FW_fp,FC_STYLE,(
const FcChar8*)
"bold");
767 FW_fp=FcPatternBuild(NULL,FC_FAMILY,FcTypeString,
"serif",FC_OUTLINE,FcTypeBool,FcTrue,NULL);
768 FcPatternAddString(FW_fp,FC_STYLE,(
const FcChar8*)
"italic");
769 FcPatternAddString(FW_fp,FC_STYLE,(
const FcChar8*)
"oblique");
772 FW_fp=FcPatternBuild(NULL,FC_FAMILY,FcTypeString,
"serif",FC_OUTLINE,FcTypeBool,FcTrue,NULL);
773 FcPatternAddString(FW_fp,FC_STYLE,(
const FcChar8*)
"bold italic");
774 FcPatternAddString(FW_fp,FC_STYLE,(
const FcChar8*)
"bold oblique");
777 FW_fp=FcPatternBuild(NULL,FC_FAMILY,FcTypeString,
"sans",FC_OUTLINE,FcTypeBool,FcTrue,NULL);
780 FW_fp=FcPatternBuild(NULL,FC_FAMILY,FcTypeString,
"sans",FC_OUTLINE,FcTypeBool,FcTrue,NULL);
781 FcPatternAddString(FW_fp,FC_STYLE,(
const FcChar8*)
"bold");
784 FW_fp=FcPatternBuild(NULL,FC_FAMILY,FcTypeString,
"sans",FC_OUTLINE,FcTypeBool,FcTrue,NULL);
785 FcPatternAddString(FW_fp,FC_STYLE,(
const FcChar8*)
"italic");
786 FcPatternAddString(FW_fp,FC_STYLE,(
const FcChar8*)
"oblique");
789 FW_fp=FcPatternBuild(NULL,FC_FAMILY,FcTypeString,
"sans",FC_OUTLINE,FcTypeBool,FcTrue,NULL);
790 FcPatternAddString(FW_fp,FC_STYLE,(
const FcChar8*)
"bold italic");
791 FcPatternAddString(FW_fp,FC_STYLE,(
const FcChar8*)
"bold oblique");
794 FW_fp=FcPatternBuild(NULL,FC_FAMILY,FcTypeString,
"monospace",FC_OUTLINE,FcTypeBool,FcTrue,NULL);
797 FW_fp=FcPatternBuild(NULL,FC_FAMILY,FcTypeString,
"monospace",FC_OUTLINE,FcTypeBool,FcTrue,NULL);
798 FcPatternAddString(FW_fp,FC_STYLE,(
const FcChar8*)
"bold");
801 FW_fp=FcPatternBuild(NULL,FC_FAMILY,FcTypeString,
"monospace",FC_OUTLINE,FcTypeBool,FcTrue,NULL);
802 FcPatternAddString(FW_fp,FC_STYLE,(
const FcChar8*)
"italic");
803 FcPatternAddString(FW_fp,FC_STYLE,(
const FcChar8*)
"oblique");
806 FW_fp=FcPatternBuild(NULL,FC_FAMILY,FcTypeString,
"monospace",FC_OUTLINE,FcTypeBool,FcTrue,NULL);
807 FcPatternAddString(FW_fp,FC_STYLE,(
const FcChar8*)
"bold italic");
808 FcPatternAddString(FW_fp,FC_STYLE,(
const FcChar8*)
"bold oblique");
811 printf (
"dont know how to handle font id %x\n",num);
815 FcConfigSubstitute(0,FW_fp,FcMatchPattern);
816 FcDefaultSubstitute(FW_fp);
817 set = FcFontSort(0, FW_fp, 1, 0, &result);
823 for(t=0;t<set->nfont;t++) {
824 FcPattern *match = set->fonts[t];
825 if (FcPatternGetString(match,FC_FILE,0,&FW_file) != FcResultMatch) {
826 printf(
"<debug> FontConfig: Couldn't get fontconfig's filename for font id %x\n", num);
831 memcpy(p->thisfontname,(
char *)FW_file,strlen((
char *)FW_file));
832 p->thisfontname[strlen((
char *)FW_file)] =
'\0';
837 printf(
"<debug> no set? wha?\n");
839 FcPatternDestroy(FW_fp);
841 if (set) FcFontSetSortDestroy(set);
846void FW_make_fontname(
int num) {
874 ppComponent_Text p = (ppComponent_Text)gglobal()->Component_Text.prv;
875 if (!p->font_directory) {
876 printf(
"Internal error: no font directory.\n");
880 fontname = facename_from_num(num);
882 printf (
"dont know how to handle font id %x\n",num);
883 p->thisfontname[0] = 0;
885 if(p->font_directory){
886 strcpy (p->thisfontname, p->font_directory);
887 strcat(p->thisfontname,
"/");
889 strcat(p->thisfontname,fontname);
890 strcat(p->thisfontname,
".ttf");
895static FT_Face FW_init_face0(FT_Library library,
char* thisfontname)
905 ppComponent_Text p = (ppComponent_Text)gglobal()->Component_Text.prv;
908 if ((p->fileLen == 0) || (p->androidFontFile ==NULL)) {
909 ConsoleMessage (
"FW_init_face, fileLen and/or androidFontFile issue");
917 ConsoleMessage (
"TEXT INITIALIZATION - checking on the font file before doing anything");
918 if (0 == fstat(fileno(p->androidFontFile), &buf)) {
919 ConsoleMessage(
"TEXT INITIALIZATION file size is %ld\n", buf.st_size);
920 ConsoleMessage(
"TEXT INITIALIZATION time modified is %s\n", ctime(&buf.st_atime));
928 unsigned char *myFileData = MALLOC(
void *, p->fileLen+1);
930 frv = fread (myFileData, (
size_t)p->fileLen, (
size_t)1, p->androidFontFile);
931 myArgs.flags = FT_OPEN_MEMORY;
932 myArgs.memory_base = myFileData;
933 myArgs.memory_size = p->fileLen;
935 err = FT_Open_Face(library, &
myArgs, 0, &ftface);
938 sprintf (line,
"FreeWRL - FreeType, can not set char size for font %s\n",thisfontname);
939 ConsoleMessage(line);
947 if (0 == fstat(fileno(p->androidFontFile), &buf)) {
948 ConsoleMessage(
"FIN TEXT INITIALIZATION file size is %ld\n", buf.st_size);
949 ConsoleMessage(
"FIN TEXT INITIALIZATION time modified is %s\n", ctime(&buf.st_atime));
954 fclose(p->androidFontFile);
955 p->androidFontFile = NULL;
959 err = FW_Open_Face(library, thisfontname, 0, &ftface);
964 printf (
"FreeType - can not use font %s\n",thisfontname);
970int FW_set_facesize(FT_Face ftface,
char *thisfontname,
double pointsize){
980 pt_dot6 = (int)(pointsize * 64.0 + .5);
981 err = FT_Set_Char_Size(ftface,
988 printf (
"FreeWRL - FreeType, can not set char size for font %s\n",thisfontname);
1002FT_Error FW_Load_Char(
unsigned int idx)
1004 FT_Glyph glyph = NULL;
1005 FT_UInt glyph_index;
1007 ppComponent_Text p = (ppComponent_Text)gglobal()->Component_Text.prv;
1009 if (p->cur_glyph >= MAX_GLYPHS) {
1014 glyph_index = FT_Get_Char_Index(p->font_face[p->myff],idx);
1018 error = FT_Load_Glyph(p->font_face[p->myff], glyph_index, FT_LOAD_DEFAULT) ||
1019 FT_Get_Glyph(p->font_face[p->myff]->glyph, &glyph);
1021 if (!error) { p->glyphs[p->cur_glyph++] = glyph; }
1028static void FW_draw_outline (FT_OutlineGlyph oglyph)
1034 ttglobal tg = gglobal();
1035 p = (ppComponent_Text)tg->Component_Text.prv;
1038 gluTessNormal(tg->Tess.text_tessobj,0.0,0.0,1.0);
1041 cbdata.coords = p->FW_rep_->actualCoord;
1042 cbdata.counter = &p->FW_pointctr;
1043 cbdata.ria = p->FW_RIA;
1044 cbdata.riaindex = &p->FW_RIA_indx;
1048 gluTessBeginPolygon( tg->Tess.text_tessobj, &cbdata );
1049 gluTessBeginContour( tg->Tess.text_tessobj );
1053 retval = FT_Outline_Decompose( &oglyph->outline, &p->FW_outline_interface, &thisptr);
1056 gluTessEndContour( tg->Tess.text_tessobj );
1057 gluTessEndPolygon( tg->Tess.text_tessobj );
1060 if (retval != FT_Err_Ok)
1061 printf(
"FT_Outline_Decompose, error %d\n",retval);
1065static void FW_draw_character (FT_Glyph glyph)
1067 ppComponent_Text p = (ppComponent_Text)gglobal()->Component_Text.prv;
1068 if (glyph->format == ft_glyph_format_outline) {
1069 FW_draw_outline ((FT_OutlineGlyph) glyph);
1070 p->pen_x += (glyph->advance.x >> 10);
1072 printf (
"FW_draw_character; glyphformat -- need outline for %s %s\n",
1073 p->font_face[p->myff]->family_name,p->font_face[p->myff]->style_name);
1075 if (p->TextVerbose) printf (
"done character\n");
1083 ppComponent_Text p = (ppComponent_Text)gglobal()->Component_Text.prv;
1086 printf (
"open_font called\n");
1088 p->FW_outline_interface.move_to = (FT_Outline_MoveTo_Func)FW_moveto;
1089 p->FW_outline_interface.line_to = (FT_Outline_LineTo_Func)FW_lineto;
1090 p->FW_outline_interface.conic_to = (FT_Outline_ConicTo_Func)FW_conicto;
1091 p->FW_outline_interface.cubic_to = (FT_Outline_CubicTo_Func)FW_cubicto;
1092 p->FW_outline_interface.shift = 0;
1093 p->FW_outline_interface.delta = 0;
1097#ifndef HAVE_FONTCONFIG
1099 if(!p->font_directory)
1100 p->font_directory = makeFontDirectory();
1103 if (p->font_directory == NULL) {
1105 ConsoleMessage (
"Have a Text node, but no font library or directory found; continuing with a default builtin font\n");
1112 for (len = 0; len < num_fonts; len++) {
1113 p->font_state[len] = FONTSTATE_NONE;
1116 if ((err = FT_Init_FreeType(&p->library))) {
1117 fprintf(stderr,
"FreeWRL FreeType Initialize error %d\n",err);
1123int open_FTlibrary_if_not_already(){
1124 ppComponent_Text p = (ppComponent_Text)gglobal()->Component_Text.prv;
1129 printf (
"Could not find System Fonts for Text nodes\n");
1134FT_Library getFontLibrary(){
1136 ppComponent_Text p = (ppComponent_Text)gglobal()->Component_Text.prv;
1138 if(open_FTlibrary_if_not_already())
1139 library = p->library;
1164static const unsigned int Replacement = ( 0xfffd );
1165static const unsigned char UTF8TailLengths[256] = {
1166 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1167 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1168 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1169 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1170 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1171 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1172 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1173 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1174 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1175 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1176 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1177 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1178 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1179 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1180 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
1181 3,3,3,3,3,3,3,3,4,4,4,4,5,5,0,0
1184static unsigned int utf8_to_utf32_char(
unsigned char *s,
unsigned char *end,
unsigned int *inc ) {
1185 unsigned int tail, i, c;
1191 tail = UTF8TailLengths[c];
1192 if( !tail || (s + tail > end))
1196 c &= ( 0x3f >> tail );
1197 for(i=0;i<tail;++i) {
1198 if( (s[i] & 0xc0) != 0x80 )
1200 c = (c << 6) + (s[i] & 0x3f);
1211unsigned int *utf8_to_utf32(
unsigned char *utf8string,
unsigned int *str32,
unsigned int *len32)
1217 unsigned int *to, *to0;
1218 unsigned char *start, *end;
1220 lenchar = (int)strlen((
const char *)utf8string);
1223 end = (
unsigned char *)&utf8string[lenchar];
1225 while ( start < end ) {
1226 while ( ( *start < 0x80 ) && ( start < end ) ) {
1230 if ( start < end ) {
1231 unsigned int inc = 0;
1232 *to++ = utf8_to_utf32_char(start,end,&inc);
1245Seems to be unused - JAS - April 2017
1247static unsigned int utf8_to_utf32_bytes(
unsigned char *s,
unsigned char *end)
1249 unsigned int tail, c;
1256 tail = UTF8TailLengths[c];
1257 tail = s + tail > end ? (
unsigned int)end - (
unsigned int)s : tail;
1265Seems to be unused - JAS - April 2017
1267static unsigned int len_utf8(
unsigned char *utf8string)
1269 unsigned char *start, *end;
1271 lenchar = (int)strlen((
const char *)utf8string);
1273 end = (
unsigned char *)&utf8string[lenchar];
1275 while ( start < end ) {
1276 while ( ( *start < 0x80 ) && ( start < end ) ) {
1280 if ( start < end ) {
1281 start += utf8_to_utf32_bytes(start,end);
1294void prep_screentext(
struct X3D_Text *tnode,
int num,
double screensize);
1304void FW_rendertext(
struct X3D_Text *tnode,
unsigned int numrows,
struct Uni_String **ptr,
1305 unsigned int nl,
float *length,
double maxext,
1306 double spacing,
double mysize,
unsigned int fsparam,
1309 unsigned char *str = NULL;
1310 unsigned int i,row,ii,irow;
1319 ttglobal tg = gglobal();
1320 p = (ppComponent_Text)tg->Component_Text.prv;
1352 p->TextZdist = 0.0f;
1356 if(!open_FTlibrary_if_not_already())
return;
1359 printf (
"entering FW_Render_text \n");
1367 p->myff = (fsparam >> 3) & 0x1F;
1368#if defined (ANDROID)
1378 if (p->font_state[p->myff] < FONTSTATE_TRIED) {
1381 FW_make_fontname(p->myff);
1382 fontface = FW_init_face0(p->library,p->thisfontname);
1384 p->font_face[p->myff] = fontface;
1385 p->font_state[p->myff] = FONTSTATE_LOADED;
1387 p->font_state[p->myff] = FONTSTATE_TRIED;
1390 if(!p->font_face[p->myff])
return;
1392 if(tnode->_isScreen){
1393 p->pointsize = mysize;
1394 p->size = mysize * (double)XRES/(
double)PPI;
1396 p->pointsize = POINTSIZE;
1400 FW_set_facesize(p->font_face[p->myff],p->thisfontname,p->pointsize);
1403 if(tnode->_isScreen){
1406 if(!tnode->_screendata)
1407 prep_screentext(tnode,p->myff, p->pointsize);
1409 rowvec_allocn = sdata->nalloc;
1410 rowvec = sdata->rowvec;
1413 rowvec_allocn = p->rowvec_allocn;
1417 rowvec = (
row32*)MALLOCV(numrows *
sizeof(
row32));
1418 memset(rowvec,0,numrows *
sizeof(
row32));
1420 if(rowvec_allocn < numrows){
1421 rowvec = REALLOC(rowvec,numrows *
sizeof(
row32));
1422 memset(&rowvec[rowvec_allocn],0,(numrows - rowvec_allocn)*
sizeof(
row32));
1423 rowvec_allocn = numrows;
1426 for (row=0; row<numrows; row++) {
1428 str = (
unsigned char *)ptr[row]->strptr;
1429 len = strlen((
const char *)str);
1430 if(rowvec[row].allocn < len){
1431 rowvec[row].str32 = (
unsigned int *)REALLOC(rowvec[row].str32,(len+1) *
sizeof(
unsigned int));
1432 rowvec[row].chr = (
chardata *) REALLOC(rowvec[row].chr,len*
sizeof(
chardata));
1433 rowvec[row].allocn = len;
1434 rowvec[row].len32 = 0;
1437 if(tnode->_isScreen){
1440 sdata->rowvec = rowvec;
1441 sdata->nalloc = rowvec_allocn;
1442 sdata->nrow = numrows;
1443 sdata->faceheight = (float)p->font_face[p->myff]->height;
1444 sdata->size = p->size;
1445 sdata->emsize = mysize;
1448 p->rowvec_allocn = rowvec_allocn;
1452 for (row=0; row<numrows; row++) {
1453 unsigned int len32, *str32;
1454 double total_row_advance, widest_char;
1455 str = (
unsigned char *)ptr[row]->strptr;
1460 str32 = rowvec[row].str32;
1461 utf8_to_utf32(str,str32,&len32);
1462 rowvec[row].iglyphstartindex = p->cur_glyph;
1463 rowvec[row].len32 = len32;
1464 rowvec[row].str32 = str32;
1465 total_row_advance = 0;
1467 for(i=0;i<len32;i++){
1469 FW_Load_Char(str32[i]);
1470 icount = p->cur_glyph -1;
1471 rowvec[row].chr[i].iglyph = icount;
1473 rowvec[row].chr[i].advance = OUT2GLB(p->glyphs[icount]->advance.x >> 10,1.0);
1474 total_row_advance += rowvec[row].chr[i].advance;
1475 widest_char = rowvec[row].chr[i].advance > widest_char ? rowvec[row].chr[i].advance : widest_char;
1478 rowvec[row].hrowsize = total_row_advance;
1479 rowvec[row].vcolsize = len32 * p->size;
1480 rowvec[row].widestchar = widest_char;
1481 char_count += len32;
1485 if (p->TextVerbose) {
1486 printf (
"Text: rows %d char_count %d\n",numrows,char_count);
1498 for(row = 0; row < numrows; row++) {
1500 hrowsize = rowvec[row].hrowsize;
1501 maxlen = hrowsize > maxlen ? hrowsize : maxlen;
1504 shrink = maxext / maxlen;
1516 if(fsparam & (0x400<<(4))){
1520 if(fsparam & (0x200<<(4))){
1524 if (fsparam & (0x800<<(4))) {
1525 p->pen_y = (double)(numrows)/2.0;
1528 if (fsparam & (0x1000<<(4))) {
1530 p->pen_y = (double)numrows;
1538 if(fsparam & (0x200<<(4)))
1540 p->pen_y = numrows - 1.0 - p->pen_y;
1544 for(irow = 0; irow < numrows; irow++) {
1545 unsigned int lenchars;
1549 if(!TOPTOBOTTOM) row = numrows - irow -1;
1551 str = (
unsigned char *)ptr[row]->strptr;
1553 printf (
"text2 row %d :%s:\n",row, str);
1556 rowlen = rowvec[row].hrowsize;
1557 lenchars = rowvec[row].len32;
1559 if((row < nl) && !(APPROX(length[row],0.0))) {
1560 rshrink = length[row] / rowlen;
1564 if (((fsparam & 0x200) || (fsparam & 0x400)) && !LEFTTORIGHT ) {
1570 if (fsparam & 0x800) {
1571 p->pen_x = -rowlen/2.0;
1576 if ((fsparam & 0x1000) && LEFTTORIGHT ) {
1581 for(ii=0; ii<lenchars; ii++) {
1585 i = lenchars - ii -1;
1586 rowvec[row].chr[i].x = p->pen_x;
1587 rowvec[row].chr[i].y = p->pen_y;
1588 rowvec[row].chr[i].sx = shrink*rshrink;
1589 rowvec[row].chr[i].sy = 1.0;
1590 p->pen_x += rowvec[row].chr[i].advance * shrink*rshrink;
1592 p->pen_y += -spacing * p->size;
1598 double widest_column, column_spacing;
1600 double maxlen = 0.0;
1602 for(row = 0; row < numrows; row++) {
1603 double vcolsize = rowvec[row].vcolsize;
1604 maxlen = vcolsize > maxlen ? vcolsize : maxlen;
1607 if(maxlen > maxext) shrink = maxext / maxlen;
1609 widest_column = 0.0;
1610 for(row=0;row<numrows;row++)
1611 widest_column = rowvec[row].widestchar > widest_column ? rowvec[row].widestchar : widest_column;
1614 column_spacing = spacing * p->size;
1624 if(fsparam & (0x200<<(4)) || fsparam & (0x400<<(4))){
1629 p->pen_x = -(double)numrows * column_spacing;
1633 if (fsparam & (0x800<<(4))) {
1634 p->pen_x = -(double)(numrows)/2.0 *column_spacing;
1637 if (fsparam & (0x1000<<(4))) {
1640 p->pen_x = -(double)numrows * column_spacing;
1646 for(irow = 0; irow < numrows; irow++) {
1647 unsigned int lenchars;
1652 if(!LEFTTORIGHT) row = numrows - irow -1;
1654 str = (
unsigned char *)ptr[row]->strptr;
1656 printf (
"text2 row %d :%s:\n",row, str);
1659 rowlen = rowvec[row].vcolsize;
1660 lenchars = rowvec[row].len32;
1662 if((row < nl) && !(APPROX(length[row],0.0))) {
1663 rshrink = length[row] / rowlen;
1666 starty = -1.0*shrink*rshrink*p->size;
1668 if ((fsparam & 0x200) || (fsparam & 0x400)){
1672 p->pen_y = rowlen + starty;
1676 if (fsparam & 0x800) {
1677 p->pen_y = rowlen/2.0 + starty;
1681 if (fsparam & 0x1000 ) {
1683 p->pen_y = rowlen + starty;
1688 for(ii=0; ii<lenchars; ii++) {
1695 i = lenchars - ii -1;
1698 penx = penx + column_spacing - rowvec[row].chr[i].advance;
1700 rowvec[row].chr[i].x = penx;
1701 rowvec[row].chr[i].y = p->pen_y;
1702 rowvec[row].chr[i].sx = 1.0;
1703 rowvec[row].chr[i].sy = shrink*rshrink;
1704 p->pen_y += -p->size * shrink * rshrink;
1707 p->pen_x += column_spacing;
1711 if(!tnode->_isScreen){
1720 p->contour_started = FALSE;
1723 est_tri = char_count*800;
1724 p->coordmaxsize=est_tri;
1725 p->cindexmaxsize=est_tri;
1726 p->FW_rep_->cindex=MALLOC(GLuint *,
sizeof(*(p->FW_rep_->cindex))*est_tri);
1727 p->FW_rep_->actualCoord = MALLOC(
float *,
sizeof(*(p->FW_rep_->actualCoord))*est_tri*3);
1728 for(row = 0; row < numrows; row++) {
1729 unsigned int lenchars = rowvec[row].len32;
1730 for(i=0; i<lenchars; i++) {
1734 chr = rowvec[row].chr[i];
1737 p->shrink_x = chr.sx;
1738 p->shrink_y = chr.sy;
1741 tg->Tess.text_IFS_Coord_count = 0;
1744 kk = rowvec[row].chr[i].iglyph;
1745 FW_draw_character (p->glyphs[kk]);
1746 FT_Done_Glyph (p->glyphs[kk]);
1750 for (x=0; x<tg->Tess.text_IFS_Coord_count; x++) {
1755 if ((tg->Tess.text_IFS_Coords[x] >= p->cindexmaxsize) ||
1756 (p->indx_count >= p->cindexmaxsize) ||
1757 (tg->Tess.text_IFS_Coords[x] < 0)) {
1759 printf (
"Tesselated index %d out of range; skipping indx_count, %d cindexmaxsize %d global_IFS_Coord_count %d\n",
1760 tg->Tess.text_IFS_Coords[x],p->indx_count,p->cindexmaxsize,tg->Tess.text_IFS_Coord_count);
1764 p->FW_rep_->cindex[p->indx_count] = p->FW_rep_->cindex[p->indx_count-1];
1765 if (p->indx_count < (p->cindexmaxsize-1)) p->indx_count ++;
1771 p->FW_rep_->cindex[p->indx_count++] = tg->Tess.text_IFS_Coords[x];
1775 if (p->indx_count > (p->cindexmaxsize-400)) {
1776 p->cindexmaxsize += 800;
1777 p->FW_rep_->cindex=(GLuint *)REALLOC(p->FW_rep_->cindex,
sizeof(*(p->FW_rep_->cindex))*p->cindexmaxsize);
1783 static int _once = 0;
1785 ntris = tg->Tess.text_IFS_Coord_count / 3;
1788 FILE *fptris = fopen(
"test_glyph_triangles.wrl",
"w+");
1789 fprintf(fptris,
"%s\n",
"#VRML V2.0 utf8");
1790 fprintf(fptris,
"Transform {\n children [\n Shape {\n appearance Appearance { material Material { diffuseColor .6 .6 .6 }}\n");
1791 fprintf(fptris,
" geometry IndexedFaceSet { solid FALSE \n");
1792 fprintf(fptris,
" coordIndex ");
1794 fprintf(fptris,
"[");
1795 for(ii=0;ii<ntris;ii++){
1796 for(jj=0;jj<3;jj++){
1797 fprintf(fptris,
" %d",p->FW_rep_->cindex[ii*3+jj]);
1799 fprintf(fptris,
" -1");
1801 fprintf(fptris,
"]\n");
1803 fprintf(fptris,
"coord Coordinate { \n");
1804 fprintf(fptris,
" point [");
1811 for(ii=0;ii<p->FW_RIA_indx;ii++){
1812 for(jj=0;jj<3;jj++){
1813 fprintf(fptris,
" %f",p->FW_rep_->actualCoord[ii*3 + jj]);
1815 fprintf(fptris,
",");
1818 fprintf(fptris,
" ] }}}\n");
1819 fprintf(fptris,
" ]}");
1822 fptris = fopen(
"test_glyph_polygon.wrl",
"w+");
1823 fprintf(fptris,
"%s\n",
"#VRML V2.0 utf8");
1824 fprintf(fptris,
"Transform {\n children [\n Shape {\n appearance Appearance { material Material { diffuseColor .5 .5 .5 }}\n");
1825 fprintf(fptris,
" geometry IndexedFaceSet { solid FALSE convex FALSE \n");
1826 fprintf(fptris,
" coordIndex ");
1828 fprintf(fptris,
"[");
1829 for(ii=0;ii<p->FW_RIA_indx;ii++){
1830 fprintf(fptris,
" %d",ii);
1832 fprintf(fptris,
" -1");
1833 fprintf(fptris,
"]\n");
1835 fprintf(fptris,
"coord Coordinate { \n");
1836 fprintf(fptris,
" point [");
1843 for(ii=0;ii<p->FW_RIA_indx;ii++){
1844 for(jj=0;jj<3;jj++){
1845 fprintf(fptris,
" %f",p->FW_rep_->actualCoord[ii*3 + jj]);
1847 fprintf(fptris,
",");
1850 fprintf(fptris,
" ] }}}\n");
1851 fprintf(fptris,
" ]}");
1856 fprintf(fptris,
"%s\n",
"#VRML V2.0 utf8");
1857 fprintf(fptris,
"Transform {\n translation 0 0 .1 children [\n Shape {\n appearance Appearance { material Material { emissiveColor .1 .8 .2 }}\n");
1858 fprintf(fptris,
" geometry Polyline2D { \n");
1859 fprintf(fptris,
" lineSegments [");
1866 for(ii=0;ii<p->FW_RIA_indx;ii++){
1867 for(jj=0;jj<2;jj++){
1868 fprintf(fptris,
" %f",p->FW_rep_->actualCoord[ii*3 + jj]);
1870 fprintf(fptris,
",");
1873 fprintf(fptris,
" ] }}\n");
1874 fprintf(fptris,
" ]}");
1885 p->FW_rep_->ntri=p->indx_count/3;
1887 p->FW_rep_->ccw=FALSE;
1890 if (p->indx_count !=0) {
1897 p->FW_rep_->normal = MALLOC(
float *,
sizeof(*(p->FW_rep_->normal))*p->indx_count*3);
1898 for (i = 0; i<(
unsigned int)p->indx_count; i++) {
1899 p->FW_rep_->normal[i*3+0] = 0.0f;
1900 p->FW_rep_->normal[i*3+1] = 0.0f;
1901 p->FW_rep_->normal[i*3+2] = 1.0f;
1905 if (HAVETODOTEXTURES) {
1906 p->FW_rep_->GeneratedTexCoords[0] = MALLOC(
float *,
sizeof(*(p->FW_rep_->GeneratedTexCoords[0]))*(p->FW_pointctr+1)*3);
1909 for (i=0; i<(
unsigned int)p->FW_pointctr; i++) {
1910 p->FW_rep_->GeneratedTexCoords[0][i*3+0] = p->FW_rep_->actualCoord[i*3+0]*1.66f;
1911 p->FW_rep_->GeneratedTexCoords[0][i*3+1] = 0.0f;
1912 p->FW_rep_->GeneratedTexCoords[0][i*3+2] = p->FW_rep_->actualCoord[i*3+1]*1.66f;
1918 if (p->TextVerbose) printf (
"exiting FW_Render_text\n");
1921int avatarCollisionVolumeIntersectMBBf(
double *modelMatrix,
float *minVals,
float *maxVals);
1923void collide_Text (
struct X3D_Text *node)
1926 GLDOUBLE awidth,atop,abottom,astep,modelMatrix[16];
1927 struct point_XYZ delta = {.x=0,.y=0,.z=-1};
1933 if(node->_isScreen > 0)
return;
1935 naviinfo = (
struct sNaviInfo*)tg->Bindable.naviinfo;
1937 awidth = naviinfo->width;
1938 atop = naviinfo->width;
1939 abottom = -naviinfo->height;
1940 astep = -naviinfo->height+naviinfo->step;
1949 if (node->_intern == NULL || node->_intern->itype != 2)
return;
1952 if (pr->ntri == 0)
return;
1955 change = pr->irep_change;
1958 if (!compile_poly_if_required(node, NULL, NULL, NULL, NULL, NULL))
return;
1959 pr->irep_change = change;
1967 if (pr->ntri == 0) {
1972 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, modelMatrix);
1974 matmultiplyAFFINE(modelMatrix,modelMatrix,FallInfo()->avatar2collision);
1977 if(!avatarCollisionVolumeIntersectMBBf(modelMatrix,pr->minVals,pr->maxVals) )
return;
1978 delta = planar_polyrep_disp(abottom,atop,astep,awidth,pr,modelMatrix,PR_DOUBLESIDED,delta);
1981 vecscale(&delta,&delta,-1);
1983 accumulate_disp(CollisionInfo(),delta);
1985#ifdef COLLISIONVERBOSE
1986 if((fabs(delta.x) != 0. || fabs(delta.y) != 0. || fabs(delta.z) != 0.)) {
1987 fprintf(stderr,
"COLLISION_TXT: (%f %f %f) (%f %f %f)\n",
1988 t_orig.x, t_orig.y, t_orig.z,
1989 delta.x, delta.y, delta.z);
1994void make_Text (
struct X3D_Text *node)
1997 double spacing = 1.0;
1999 int isScreenFontStyle;
2000 unsigned int fsparams = 0;
2002 isScreenFontStyle = FALSE;
2006 if (node->fontStyle) {
2037 unsigned char *lang;
2038 unsigned char *style;
2043 unsigned char *stmp;
2046 POSSIBLE_PROTO_EXPANSION(
struct X3D_FontStyle *, node->fontStyle,fsp);
2049 if (fsp->_nodeType != NODE_FontStyle && fsp->_nodeType != NODE_ScreenFontStyle) {
2050 ConsoleMessage (
"Text node has FontStyle of %s\n",stringNodeType(fsp->_nodeType));
2051 node->fontStyle = NULL;
2056 lang = (
unsigned char *)fsp->language->strptr;
2057 style = (
unsigned char *)fsp->style->strptr;
2059 family = fsp->family;
2060 justify = fsp->justify;
2063 spacing = fsp->spacing;
2065 if(fsp->_nodeType == NODE_ScreenFontStyle){
2069 size = fsps->pointSize;
2070 isScreenFontStyle = TRUE;
2074 fsparams = (fsp->horizontal)|(fsp->leftToRight<<1)|(fsp->topToBottom<<2);
2079 if (strlen((
const char *)style)) {
2080 if (!strcmp((
const char *)style,
"ITALIC")) {fsparams |= 0x10;}
2081 else if(!strcmp((
const char *)style,
"BOLD")) {fsparams |= 0x08;}
2082 else if (!strcmp((
const char *)style,
"BOLDITALIC")) {fsparams |= 0x18;}
2083 else if (strcmp((
const char *)style,
"PLAIN")) {
2084 printf (
"Warning - FontStyle style %s assuming PLAIN\n",style);}
2086 if (strlen((
const char *)lang)) {
2087 printf (
"Warning - FontStyle - language param unparsed\n");
2095 for (tmp = 0; tmp < family.n; tmp++) {
2096 stmp = (
unsigned char *)svptr[tmp]->strptr;
2097 if (strlen((
const char *)stmp) == 0) {fsparams |=0x20; }
2098 else if (!strcmp((
const char *)stmp,
"SERIF")) { fsparams |= 0x20;}
2099 else if(!strcmp((
const char *)stmp,
"SANS")) { fsparams |= 0x40;}
2100 else if (!strcmp((
const char *)stmp,
"TYPEWRITER")) { fsparams |= 0x80;}
2107 if (tx == 0) { fsparams |= 0x2400; }
2108 else if (tx == 1) { fsparams |= 0x2000; }
2110 printf (
"Warning - FontStyle, max 2 elements in Justify\n");
2114 for (tmp = 0; tmp < tx; tmp++) {
2115 stmp = (
unsigned char *)svptr[tmp]->strptr;
2116 if (strlen((
const char *)stmp) == 0) {
2123 else if (!strcmp((
const char *)stmp,
"FIRST")) { fsparams |= (0x200<<(tmp*4));}
2124 else if(!strcmp((
const char *)stmp,
"BEGIN")) { fsparams |= (0x400<<(tmp*4));}
2125 else if (!strcmp((
const char *)stmp,
"MIDDLE")) { fsparams |= (0x800<<(tmp*4));}
2126 else if (!strcmp((
const char *)stmp,
"END")) { fsparams |= (0x1000<<(tmp*4));}
2143 node->_isScreen = isScreenFontStyle;
2145 FW_rendertext(node,((node->string).n),((node->string).p),
2146 ((node->length).n),((node->length).p),
2147 (node->maxExtent),spacing,size,fsparams,rep_);
2206typedef struct _Atlas Atlas;
2213typedef enum GUIElementType
2217 GUI_ATLASENTRY = 11,
2218 GUI_ATLASENTRYSET = 12,
2236 AtlasEntry *ascii[128];
2266 unsigned char *texture;
2297typedef struct vec2 {
float X;
float Y;}
vec2;
2298typedef struct vec4 {
float X;
float Y;
float Z;
float W;}
vec4;
2303 GUIElementType type;
2317static void *GUImalloc(
struct Vector **guitable,
int type);
2318static AtlasEntry * AtlasAddIChar(AtlasFont *font,
AtlasEntrySet *entryset,
int ichar);
2322static void AtlasEntrySet_init(AtlasFont *font,
AtlasEntrySet *me,
char *name){
2325 me->type = GUI_ATLASENTRYSET;
2326 me->entries = newVector(AtlasEntry *,256);
2328 memset(me->ascii,0,128*
sizeof(
int));
2334Code appears to be unused - JAS April 2017
2336static void AtlasEntry_init1(AtlasEntry *me,
char *name,
int index,
int x,
int y,
int width,
int height){
2339 me->type = GUI_ATLASENTRY;
2343 me->size.Y = height;
2348static void Atlas_init(Atlas *me,
int size,
int rowheight){
2349 me->type = GUI_ATLAS;
2352 me->pen.X = me->pen.Y = 0;
2353 me->size.X = me->size.Y = size;
2354 me->rowheight = rowheight;
2356 me->bytesperpixel = 1;
2360 me->bytesperpixel = 1;
2365 me->bytesperpixel = 1;
2368 me->texture = (
unsigned char*)MALLOCV(me->size.X *me->size.Y*me->bytesperpixel);
2369 memset(me->texture,127,me->size.X *me->size.Y*me->bytesperpixel);
2382static void subimage_paste(
unsigned char *image,
ivec2 size,
unsigned char* subimage,
int bpp,
ivec2 ulpos,
ivec2 subsize ){
2384 int imrow, imcol, impos,bpp1;
2387 for(i=0;i<subsize.Y;i++ ){
2388 imrow = ulpos.Y + i;
2390 impos = (imrow * size.X + imcol)*bpp;
2393 ispos = (i*subsize.X + iscol)*bpp1;
2394 if(impos >= 0 && (impos+subsize.X*bpp <= size.X*size.Y*bpp))
2396 if(bpp == 1) memcpy(&image[impos],&subimage[ispos],subsize.X*bpp1);
2401 for(k=0;k<subsize.X;k++){
2404 if(j ==5) image[impos+k+j] = 255;
2405 else image[impos+k+j] = subimage[ispos+k];
2420 for(i=0;i<vectorSize(guitable);i++){
2423 if(!strcmp(name,el->name)){
2432static void Atlas_addEntry(Atlas *me, AtlasEntry *entry,
unsigned char *gray){
2441 if((me->pen.X + entry->size.X) > me->size.X){
2442 me->pen.Y += me->rowheight;
2445 if(me->pen.Y > me->size.Y){
2446 ConsoleMessage(
"Atlas too small, skipping %d\n",entry->ichar);
2451 pos.X = me->pen.X + entry->pos.X;
2452 pos.Y = me->pen.Y + entry->pos.Y;
2454 if(1) subimage_paste(me->texture,me->size,gray,me->bytesperpixel,me->pen,entry->size);
2455 if(0) subimage_paste(me->texture,me->size,gray,1,pos,entry->size);
2458 entry->apos.X = me->pen.X;
2459 entry->apos.Y = me->pen.Y;
2461 entry->apos.X = pos.X;
2462 entry->apos.Y = pos.Y;
2464 me->pen.X += entry->size.X;
2471Code appears to be unused - JAS April 2017
2473static void AtlasEntrySet_addEntry1(
AtlasEntrySet *me, AtlasEntry *entry){
2475 vector_pushBack(AtlasEntry*,me->entries,entry);
2476 if(entry->ichar > 0 && entry->ichar < 128){
2478 me->ascii[entry->ichar] = entry;
2479 me->lastascii = max(me->lastascii,me->entries->n);
2485static void AtlasEntrySet_addEntry(
AtlasEntrySet *me, AtlasEntry *entry,
unsigned char *gray){
2486 ppComponent_Text p = (ppComponent_Text)gglobal()->Component_Text.prv;
2487 vector_pushBack(AtlasEntry*,me->entries,entry);
2488 if(entry->ichar > 0 && entry->ichar < 128){
2490 me->ascii[entry->ichar] = entry;
2491 me->lastascii = max(me->lastascii,me->entries->n);
2494 me->atlas = (Atlas*)searchGUItable(p->atlas_table,me->atlasName);
2496 Atlas_addEntry(me->atlas, entry, gray);
2501Code appears to be unused - JAS April 2017
2503static AtlasEntry *AtlasEntrySet_getEntry1(
AtlasEntrySet *me,
char *name){
2506 for(i=0;i<vectorSize(me->entries);i++){
2507 AtlasEntry *entry = vector_get(AtlasEntry*,me->entries,i);
2508 if(!strcmp(entry->name,name))
2516static AtlasEntry *AtlasEntrySet_getEntry(
AtlasEntrySet *me,
int ichar){
2520 AtlasEntry *ae = NULL;
2521 if(ichar > 0 && ichar < 128){
2522 ae = me->ascii[ichar];
2526 for(i=me->lastascii;i<vectorSize(me->entries);i++){
2527 AtlasEntry *entry = vector_get(AtlasEntry*,me->entries,i);
2528 if(entry->ichar == ichar){
2536 ae = AtlasAddIChar(me->font, me, ichar);
2537 for(i=0;i<vectorSize(me->entries);i++){
2538 AtlasEntry *entry = vector_get(AtlasEntry*,me->entries,i);
2539 if(entry->ichar == ichar){
2545 printf(
"tried to add char %d to atlas, but didn't show up\n",ichar);
2555static void AtlasFont_init(AtlasFont *me,
char *facename,
int EMsize,
char* path){
2557 me->name = facename;
2558 me->type = GUI_FONT;
2560 me->fontFace = NULL;
2561 me->EMsize = EMsize;
2592static char *newstringfromchar(
char c){
2593 char *ret = MALLOCV(2);
2601static AtlasEntry * AtlasAddIChar(AtlasFont *font,
AtlasEntrySet *entryset,
int ichar){
2602 FT_Face fontFace = font->fontFace;
2609 c = FT_Get_Char_Index(fontFace, ichar);
2610 error = FT_Load_Glyph(fontFace, c, FT_LOAD_RENDER);
2617 glyph = fontFace->glyph;
2619 entry = MALLOCV(
sizeof(AtlasEntry));
2621 entry->ichar = ichar;
2622 entry->pos.X = glyph->bitmap_left;
2623 entry->pos.Y = glyph->bitmap_top;
2624 entry->advance.X = glyph->advance.x >> 6;
2625 entry->advance.Y = glyph->advance.y >> 6;
2626 entry->size.X = glyph->bitmap.width;
2627 entry->size.Y = glyph->bitmap.rows;
2629 AtlasEntrySet_addEntry(entryset,entry,glyph->bitmap.buffer);
2634static int RenderFontAtlas(AtlasFont *font,
AtlasEntrySet *entryset,
char * cText){
2640 FT_Face fontFace = font->fontFace;
2642 for (i = 0; i < strlen(cText); i++)
2649 c = FT_Get_Char_Index(fontFace, (
int) cText[i]);
2650 error = FT_Load_Glyph(fontFace, c, FT_LOAD_RENDER);
2657 glyph = fontFace->glyph;
2658 entry = MALLOCV(
sizeof(AtlasEntry));
2661 if( cText[i] > 31 && cText[i] < 128 ) entry->ichar = cText[i];
2662 entry->pos.X = glyph->bitmap_left;
2663 entry->pos.Y = glyph->bitmap_top;
2664 entry->advance.X = glyph->advance.x >> 6;
2665 entry->advance.Y = glyph->advance.y >> 6;
2666 entry->size.X = glyph->bitmap.width;
2667 entry->size.Y = glyph->bitmap.rows;
2668 entry->name = newstringfromchar(cText[i]);
2669 AtlasEntrySet_addEntry(entryset,entry,glyph->bitmap.buffer);
2678static int AtlasFont_LoadFont(AtlasFont *font){
2680 FT_Library fontlibrary;
2683 char thisfontname[2048];
2687 p = (ppComponent_Text)tg->Component_Text.prv;
2689 if(!p->font_directory)
2690 p->font_directory = makeFontDirectory();
2692 strcpy (thisfontname, p->font_directory);
2693 strcat(thisfontname,
"/");
2694 strcat(thisfontname,font->path);
2696 fontlibrary = getFontLibrary();
2700 fontname_entry = get_fontname_entry_by_facename(font->name);
2703 int num = fontname_entry->num;
2704 if(p->font_state[num] < FONTSTATE_TRIED){
2705 FW_make_fontname(num);
2706 fontface = FW_init_face0(fontlibrary,p->thisfontname);
2708 p->font_face[num] = fontface;
2709 p->font_state[num] = FONTSTATE_LOADED;
2710 font->fontFace = fontface;
2712 p->font_state[num] = FONTSTATE_TRIED;
2718 font->fontFace = p->font_face[num];
2722 err = FT_New_Face(fontlibrary, thisfontname, 0, &fontface);
2724 printf (
"FreeType - can not use font %s\n",thisfontname);
2727 font->fontFace = fontface;
2731 printf(
"fontface flags & Scalable? = %ld \n",font->fontFace->face_flags & FT_FACE_FLAG_SCALABLE );
2732 nsizes = font->fontFace->num_fixed_sizes;
2733 printf(
"num_fixed_sizes = %d\n",nsizes);
2739static int AtlasFont_setFontSize(AtlasFont *me,
int EMpixels,
int *rowheight,
int *maxadvancepx){
2741 FT_Face fontFace = me->fontFace;
2743 if(!fontFace)
return FALSE;
2754 err = FT_Set_Pixel_Sizes(
2766 *rowheight = fontFace->size->metrics.height >> 6;
2771 *maxadvancepx = fontFace->size->metrics.max_advance >> 6;
2773 printf (
"FreeWRL - FreeType, can not set char size for font %s\n",me->path);
2779static unsigned int upperPowerOfTwo(
unsigned int k){
2781 unsigned int kk = 1;
2782 for(ipow=2;ipow<32;ipow++){
2784 if(kk > k)
return kk;
2790static void AtlasFont_RenderFontAtlas(AtlasFont *me,
int EMpixels,
char* alphabet){
2793 int rowheight, maxadvancepx, pixelsNeeded;
2794 unsigned int dimension;
2797 Atlas *atlas = NULL;
2804 ppComponent_Text p = (ppComponent_Text)gglobal()->Component_Text.prv;
2808 if(!me->fontFace)
return;
2810 atlas = GUImalloc(&p->atlas_table,GUI_ATLAS);
2813 name = MALLOCV(strlen(me->name)+12);
2814 strcpy(name,me->name);
2815 sprintf(&name[strlen(me->name)],
"%d",EMpixels);
2817 AtlasEntrySet_init(me,aes,name);
2819 AtlasFont_setFontSize(me,EMpixels, &rowheight, &maxadvancepx);
2820 pixelsNeeded = rowheight * EMpixels / 2 * strlen(alphabet);
2821 dimension = (
unsigned int)sqrt((
double)pixelsNeeded);
2822 dimension = upperPowerOfTwo(dimension);
2824 Atlas_init(atlas,dimension,rowheight);
2826 aes->EMpixels = EMpixels;
2827 aes->maxadvancepx = maxadvancepx;
2828 aes->rowheight = rowheight;
2830 aes->atlasName = name;
2832 RenderFontAtlas(me,aes,alphabet);
2842static int bin2hex(
char *inpath,
char *outpath){
2849 fin = fopen(inpath,
"r+b");
2850 fout = fopen(outpath,
"w+");
2853 char *bufname, *bufdup, *ir, *sep;
2857 buf = MALLOCV(ncol + 1);
2859 bufname = bufdup = STRDUP(inpath);
2860 ir = strrchr(bufname,
'\\');
2861 if(ir) bufname = &ir[1];
2862 ir = strrchr(bufname,
'/');
2863 if(ir) bufname = &ir[1];
2864 ir = strrchr(bufname,
'.');
2867 fprintf(fout,
"unsigned char %s_data[] = \n",bufname);
2873 nc = fread(buf,1,nc,fin);
2874 if(nc < ncol) more = 0;
2876 fprintf(fout,
"%s",sep);
2878 fprintf(fout,
"0x%.2x",hh);
2881 if(more) fprintf(fout,
"\n");
2884 fprintf(fout,
"};\n");
2886 fprintf(fout,
"int %s_size = %d;\n",bufname,m);
2896static int AtlasFont_LoadFromDotC(AtlasFont *font,
unsigned char *start,
int size){
2898 FT_Library fontlibrary;
2902 fontname = font->path;
2904 if(!size || !start){
2905 printf(
"not compiled in C %s\n", font->name);
2909 fontlibrary = getFontLibrary();
2913 args.flags = FT_OPEN_MEMORY;
2914 args.memory_base = start;
2915 args.memory_size = size;
2916 err = FT_Open_Face(fontlibrary, &args, 0, &fontFace);
2919 printf (
"FreeType - can not use font %s\n",fontname);
2922 font->fontFace = fontFace;
2926 printf(
"fontface flags & Scalable? = %ld \n",fontFace->face_flags & FT_FACE_FLAG_SCALABLE );
2927 nsizes = fontFace->num_fixed_sizes;
2928 printf(
"num_fixed_sizes = %d\n",nsizes);
2935static AtlasFont *searchAtlasFontTable(
struct Vector* guitable,
char *name,
int EMsize){
2937 AtlasFont *retval = NULL;
2939 for(i=0;i<vectorSize(guitable);i++){
2940 AtlasFont *el = vector_get(AtlasFont *,guitable,i);
2942 if(!strcmp(name,el->name) && EMsize == el->EMsize){
2954#ifdef HAVE_COMPILED_IN_FONT
2955extern unsigned char VeraMono_ttf_data[];
2956extern int VeraMono_ttf_size;
2957extern unsigned char freewrl_wingding_ttf_data[];
2958extern int freewrl_wingding_ttf_size;
2960unsigned char *VeraMono_ttf_data = NULL;
2961int VeraMono_ttf_size = 0;
2965static int FW_Open_Face(FT_Library library,
char *thisfontname,
int faceIndex, FT_Face *face)
2972 if(VeraMono_ttf_size && strstr(thisfontname,
"VeraMono.ttf")){
2975 args.flags = FT_OPEN_MEMORY;
2976 args.memory_base = VeraMono_ttf_data;
2977 args.memory_size = VeraMono_ttf_size;
2978 err = FT_Open_Face(library, &args, 0, face);
2980 err = FT_New_Face(library, thisfontname, faceIndex, face);
2981 if(err && VeraMono_ttf_size)
2985 args.flags = FT_OPEN_MEMORY;
2986 args.memory_base = VeraMono_ttf_data;
2987 args.memory_size = VeraMono_ttf_size;
2988 err = FT_Open_Face(library, &args, faceIndex, face);
2996AtlasFont *searchAtlasTableOrLoad(
char *facename,
int EMpixels){
2998 ppComponent_Text p = (ppComponent_Text)gglobal()->Component_Text.prv;
2999 font = (AtlasFont*)searchAtlasFontTable(p->font_table,facename,EMpixels);
3001 static char * ascii32_126 =
" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQURSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
3002 int font_tactic, len;
3005 font = GUImalloc(&p->font_table,GUI_FONT);
3007 len = strlen(facename) + 7;
3008 facenamettf = MALLOCV(len);
3009 strcpy(facenamettf,facename);
3010 facenamettf = strcat(facenamettf,
".ttf");
3011 AtlasFont_init(font,facename,EMpixels,facenamettf);
3013 font_tactic = DOTC_NONE;
3014 if(!strcmp(facename,
"VeraMono")){
3017 if(0) font_tactic = DOTC_SAVE;
3018 else font_tactic = DOTC_LOAD;
3019 if(font_tactic == DOTC_LOAD)
3020 AtlasFont_LoadFromDotC(font, VeraMono_ttf_data, VeraMono_ttf_size);
3022 if(!strcmp(facename,
"freewrl_wingding")){
3025 if(0) font_tactic = DOTC_SAVE;
3026 else font_tactic = DOTC_LOAD;
3027 if(font_tactic == DOTC_LOAD)
3028 AtlasFont_LoadFromDotC(font, freewrl_wingding_ttf_data, freewrl_wingding_ttf_size);
3030 if(font_tactic == DOTC_SAVE) {
3034 facenamettfc = alloca(strlen(facenamettf)+3);
3035 strcpy(facenamettfc,facenamettf);
3036 facenamettfc[len-7] =
'_';
3037 strcat(facenamettfc,
".c");
3038 bin2hex(font->path, facenamettfc);
3040 if(font_tactic != DOTC_LOAD)
3041 AtlasFont_LoadFont(font);
3043 AtlasFont_RenderFontAtlas(font,EMpixels,ascii32_126);
3048 printf(
"dug9gui: Can't find font %s did you misname the fontface sb Vera or VeraMono etc?\n",facename);
3056vec4 vec4_init(
float x,
float y,
float z,
float w){
3058 ret.X = x, ret.Y = y; ret.Z = z; ret.W = w;
3063static vec2 vec2_init(
float x,
float y){
3065 ret.X = x, ret.Y = y;
3071typedef struct ivec4 {
int X;
int Y;
int W;
int H;}
ivec4;
3072ivec4 ivec4_init(
int x,
int y,
int w,
int h);
3082static vec2 pixel2normalizedViewportScale( GLfloat x, GLfloat y)
3087 ivec4 currentvp = stack_top(
ivec4,gglobal()->Mainloop._vportstack);
3090 xy.X = ((GLfloat)(x)/(GLfloat)currentvp.W) * 2.0f;
3091 xy.Y = ((GLfloat)(y)/(GLfloat)currentvp.H) * 2.0f;
3095static vec2 pixel2normalizedViewport( GLfloat x, GLfloat y){
3096 ivec4 currentvp = stack_top(
ivec4,gglobal()->Mainloop._vportstack);
3099 xy.X = ((GLfloat)(x - currentvp.X)/(GLfloat)currentvp.W) * 2.0f;
3100 xy.Y = ((GLfloat)(y - currentvp.Y)/(GLfloat)currentvp.H) * 2.0f;
3109Calls commented out, removing from active compile - JAS April 2017
3110static void printvpstacktop(Stack *vpstack,
int line){
3112 int n = ((
struct Vector*)vpstack)->n;
3113 int xx = ((
ivec4*)((
struct Vector*)vpstack)->data)[3].X;
3114 printf(
"vp top[%d] = [%d %d %d %d] line %d xx=%d\n",n,currentvp.X,currentvp.Y,currentvp.W,currentvp.H,line,xx);
3120Code appears not to be called - JAS April 2017
3122static vec2 pixel2normalizedScreenScale( GLfloat x, GLfloat y)
3127 xy.X = ((GLfloat)x/(GLfloat)screen.X) * 2.0f;
3128 xy.Y = ((GLfloat)y/(GLfloat)screen.Y) * 2.0f;
3136Code appears not to be called - JAS April 2017
3138static vec2 pixel2normalizedScreen( GLfloat x, GLfloat y){
3139 vec2 xy = pixel2normalizedScreenScale(x,y);
3149static GLbyte vShaderStr[] =
3150 "attribute vec4 a_position; \n"
3151 "attribute vec2 a_texCoord; \n"
3152 "uniform mat4 u_ModelViewMatrix; \n"
3153 "uniform mat4 u_ProjectionMatrix; \n"
3154 "varying vec2 v_texCoord; \n"
3157 " gl_Position = u_ProjectionMatrix * u_ModelViewMatrix * a_position; \n"
3158 " v_texCoord = a_texCoord; \n"
3175static GLbyte fShaderStr[] =
3176#ifdef GL_ES_VERSION_2_0
3177 "precision mediump float; \n"
3179 "varying vec2 v_texCoord; \n"
3180 "uniform sampler2D Texture0; \n"
3181 "uniform vec4 Color4f; \n"
3182 "uniform vec4 blend; \n"
3185 " vec4 texColor = texture2D( Texture0, v_texCoord ); \n"
3186 " vec4 one = vec4(1.0,1.0,1.0,1.0); \n"
3187 " vec4 omb = vec4(one.rgb - blend.rgb,1.0 - blend.a); \n"
3188 " vec4 tcolor = omb + (blend*texColor);\n"
3189 " float aa = omb.a*Color4f.a + blend.a*(1.0 -texColor.a);\n"
3190 " tcolor = Color4f * tcolor;\n"
3191 " vec4 finalColor = vec4(tcolor.rgb, 1.0 - aa ); \n"
3192 " gl_FragColor = finalColor; \n"
3201static GLfloat modelviewIdentityf[] = {
3202 1.0f, 0.0f, 0.0f, 0.0f,
3203 0.0f, 1.0f, 0.0f, 0.0f,
3204 0.0f, 0.0f, 1.0f, 0.0f,
3205 0.0f, 0.0f, 0.0f, 1.0f
3207static GLfloat projectionIdentityf[] = {
3208 1.0f, 0.0f, 0.0f, 0.0f,
3209 0.0f, 1.0f, 0.0f, 0.0f,
3210 0.0f, 0.0f, 1.0f, 0.0f,
3211 0.0f, 0.0f, 0.0f, 1.0f
3214static void initProgramObject(){
3216 ttglobal tg = gglobal();
3217 p = (ppComponent_Text)tg->Component_Text.prv;
3220 p->programObject = esLoadProgram ( (
const char*) vShaderStr, (
const char *)fShaderStr );
3222 p->positionLoc = glGetAttribLocation ( p->programObject,
"a_position" );
3223 p->texCoordLoc = glGetAttribLocation ( p->programObject,
"a_texCoord" );
3225 p->textureLoc = glGetUniformLocation ( p->programObject,
"Texture0" );
3226 p->color4fLoc = glGetUniformLocation ( p->programObject,
"Color4f" );
3227 p->blendLoc = glGetUniformLocation ( p->programObject,
"blend" );
3228 p->modelviewLoc = glGetUniformLocation ( p->programObject,
"u_ModelViewMatrix" );
3229 p->projectionLoc = glGetUniformLocation ( p->programObject,
"u_ProjectionMatrix" );
3235JAS - possibly unused - Apr 2017
3237static void dug9gui_DrawImage(
int xpos,
int ypos,
int width,
int height,
char *buffer){
3244GLfloat cursorVert[] = {
3253GLfloat cursorTex[] = {
3261 GLuint ind[] = {0,1,2,3,4,5};
3266 GLfloat cursorVert2[18];
3269 ttglobal tg = gglobal();
3270 p = (ppComponent_Text)tg->Component_Text.prv;
3273 if(0) glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, width, height, 0, GL_LUMINANCE , GL_UNSIGNED_BYTE, buffer);
3276 if(1) glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA , GL_UNSIGNED_BYTE, buffer);
3277 glUniform4f(p->blendLoc,0.0f,0.0f,0.0f,1.0f);
3281 fxy = pixel2normalizedScreen((GLfloat)xpos,(GLfloat)ypos);
3282 fwh = pixel2normalizedScreenScale((GLfloat)width,(GLfloat)height);
3284 fxy.Y = fxy.Y - fwh.Y;
3289 fxy = pixel2normalizedViewport((GLfloat)xpos,(GLfloat)ypos);
3291 fwh = pixel2normalizedViewportScale((GLfloat)width,(GLfloat)height);
3294 fxy.Y = fxy.Y - fwh.Y;
3299 memcpy(cursorVert2,cursorVert,2*3*3*
sizeof(GLfloat));
3303 cursorVert2[i*3 +0] *= fwh.X;
3304 cursorVert2[i*3 +0] += fxy.X;
3305 if(!iyup) cursorVert2[i*3 +1] = 1.0f - cursorVert2[i*3 +1];
3306 cursorVert2[i*3 +1] *= fwh.Y;
3307 cursorVert2[i*3 +1] += fxy.Y;
3313 glActiveTexture ( GL_TEXTURE0 );
3314 glBindTexture ( GL_TEXTURE_2D, p->textureID );
3315 glUniform1i ( p->textureLoc, 0 );
3317 glVertexAttribPointer (p->positionLoc, 3, GL_FLOAT,
3318 GL_FALSE, 0, cursorVert2 );
3320 glVertexAttribPointer (p->texCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, cursorTex );
3321 glEnableVertexAttribArray (p->positionLoc );
3322 glEnableVertexAttribArray (p->texCoordLoc);
3329 glDrawElements ( GL_TRIANGLES, 3*2, GL_UNSIGNED_INT, ind );
3339static void dug9gui_DrawSubImage(
float xpos,
float ypos,
float xsize,
float ysize,
3340 int ix,
int iy,
int iw,
int ih,
int width,
int height,
int bpp,
unsigned char *buffer){
3361GLfloat cursorVert[] = {
3369GLfloat cursorTex[] = {
3376 GLuint ind[] = {0,1,2,3,4,5};
3381 GLfloat cursorVert2[18];
3382 GLfloat cursorTex2[12];
3384 ttglobal tg = gglobal();
3385 p = (ppComponent_Text)tg->Component_Text.prv;
3389 glActiveTexture ( GL_TEXTURE0 );
3390 glBindTexture ( GL_TEXTURE_2D, p->textureID );
3391 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3392 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3395 glUniform1i ( p->textureLoc, 0 );
3399 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA , GL_UNSIGNED_BYTE, buffer);
3401 glUniform4f(p->blendLoc,0.0f,0.0f,0.0f,1.0f);
3405 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, width, height, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, buffer);
3408 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA , GL_UNSIGNED_BYTE, buffer);
3409 glUniform4f(p->blendLoc,1.0f,1.0f,1.0f,1.0f);
3417 memcpy(cursorVert2,cursorVert,2*3*3*
sizeof(GLfloat));
3419 cursorVert2[i*3 +0] *= xsize;
3420 cursorVert2[i*3 +0] += xpos;
3421 if(!iyup) cursorVert2[i*3 +1] = 1.0f - cursorVert2[i*3 +1];
3422 cursorVert2[i*3 +1] *= ysize;
3423 cursorVert2[i*3 +1] += ypos;
3426 glVertexAttribPointer (p->positionLoc, 3, GL_FLOAT,
3427 GL_FALSE, 0, cursorVert2 );
3429 fixy.X = (float)ix/(
float)width;
3430 fiwh.X = (float)iw/(
float)width;
3432 fixy.Y = (float)iy/(
float)height;
3433 fiwh.Y = (float)ih/(
float)height;
3435 fixy.Y = (float)(height -iy)/(float)height;
3436 fiwh.Y =-(float)ih/(
float)height;
3438 memcpy(cursorTex2,cursorTex,2*3*2*
sizeof(GLfloat));
3440 cursorTex2[i*2 +0] *= fiwh.X;
3441 cursorTex2[i*2 +0] += fixy.X;
3442 cursorTex2[i*2 +1] *= fiwh.Y;
3443 cursorTex2[i*2 +1] += fixy.Y;
3445 glVertexAttribPointer (p->texCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, cursorTex2 );
3446 glEnableVertexAttribArray (p->positionLoc );
3447 glEnableVertexAttribArray (p->texCoordLoc);
3455 glDrawElements ( GL_TRIANGLES, 3*2, GL_UNSIGNED_INT, ind );
3460int render_captiontext(AtlasFont *font,
int *utf32,
int len32,
vec4 color){
3466 int i, pen_x, pen_y;
3471 ttglobal tg = gglobal();
3472 p = (ppComponent_Text)tg->Component_Text.prv;
3475 if(len32 == 0)
return FALSE;
3477 if(!font)
return FALSE;
3480 finishedWithGlobalShader();
3481 glDepthMask(GL_FALSE);
3482 glDisable(GL_DEPTH_TEST);
3483 if(!p->programObject) initProgramObject();
3485 glUseProgram ( p->programObject );
3487 glGenTextures(1, &p->textureID);
3489 glBindTexture(GL_TEXTURE_2D, p->textureID);
3490 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
3491 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
3493 glUniformMatrix4fv(p->modelviewLoc, 1, GL_FALSE,modelviewIdentityf);
3494 glUniformMatrix4fv(p->projectionLoc, 1, GL_FALSE, projectionIdentityf);
3496 glUniform4f(p->color4fLoc,color.X,color.Y,color.Z,color.W);
3498 vportstack = (Stack*)tg->Mainloop._vportstack;
3499 ivport = stack_top(
ivec4,vportstack);
3501 pen_y = ivport.Y + ivport.H - set->EMpixels;
3503 for (i = 0; i < len32; i++)
3505 AtlasEntry *entry = NULL;
3510 entry = AtlasEntrySet_getEntry(set,ichar);
3513 float xpos, ypos, xsize, ysize;
3515 xpos = pen_x + entry->pos.X;
3516 ypos = pen_y - entry->pos.Y;
3517 xsize = entry->size.X;
3518 ysize = entry->size.Y;
3520 fxy = pixel2normalizedViewport((GLfloat)xpos,(GLfloat)ypos);
3521 fwh = pixel2normalizedViewportScale((GLfloat)xsize,(GLfloat)ysize);
3523 fxy.Y = fxy.Y - fwh.Y;
3528 dug9gui_DrawSubImage(xpos,ypos,xsize,ysize,
3529 entry->apos.X, entry->apos.Y, entry->size.X, entry->size.Y,
3530 set->atlas->size.X,set->atlas->size.Y,set->atlas->bytesperpixel,set->atlas->texture);
3531 pen_x += entry->advance.X;
3536 glEnable(GL_DEPTH_TEST);
3537 glDepthMask(GL_TRUE);
3538 restoreGlobalShader();
3544void atlasfont_get_rowheight_charwidth_px(AtlasFont *font,
int *rowheight,
int *maxadvancepx){
3545 *rowheight = font->set->rowheight;
3546 *maxadvancepx = font->set->maxadvancepx;
3551int before_textpanel_render_rows(AtlasFont *font,
vec4 color){
3555 ttglobal tg = gglobal();
3556 p = (ppComponent_Text)tg->Component_Text.prv;
3558 if(font == NULL)
return FALSE;
3559 entryset = font->set;
3560 if(entryset == NULL)
return FALSE;
3561 if(entryset->atlas == NULL)
return FALSE;
3563 atlas = entryset->atlas;
3565 finishedWithGlobalShader();
3566 glDepthMask(GL_FALSE);
3567 glDisable(GL_DEPTH_TEST);
3568 if(!p->programObject) initProgramObject();
3570 glUseProgram ( p->programObject );
3572 glGenTextures(1, &p->textureID);
3575 glActiveTexture ( GL_TEXTURE0 );
3576 glBindTexture ( GL_TEXTURE_2D, p->textureID );
3577 glUniform1i ( p->textureLoc, 0 );
3579 if (atlas->bytesperpixel == 1){
3580 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3581 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3583 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
3584 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3588 if(atlas->bytesperpixel == 1){
3589 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, atlas->size.X, atlas->size.Y, 0, GL_ALPHA , GL_UNSIGNED_BYTE, atlas->texture);
3590 }
else if(atlas->bytesperpixel == 2){
3592 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, atlas->size.X, atlas->size.Y, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, atlas->texture);
3593 }
else if(atlas->bytesperpixel == 4){
3594 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, atlas->size.X, atlas->size.Y, 0, GL_RGBA , GL_UNSIGNED_BYTE, atlas->texture);
3597 glUniform4f(p->color4fLoc,color.X,color.Y,color.Z,color.W);
3598 glUniform4f(p->blendLoc,0.0f,0.0f,0.0f,1.0f);
3600 glUniformMatrix4fv(p->modelviewLoc, 1, GL_FALSE,modelviewIdentityf);
3601 glUniformMatrix4fv(p->projectionLoc, 1, GL_FALSE, projectionIdentityf);
3607int textpanel_render_row(AtlasFont *font,
char * cText,
int len,
int *pen_x,
int *pen_y){
3615 if(cText == NULL)
return FALSE;
3616 if(len == 0)
return FALSE;
3617 if(font == NULL)
return FALSE;
3618 entryset = font->set;
3619 if(entryset == NULL)
return FALSE;
3620 if(entryset->atlas == NULL)
return FALSE;
3624 vec2 charScreenSize;
3625 vec2 charScreenOffset;
3626 vec2 charScreenAdvance;
3630 GLfloat x,y,z, xx, yy;
3641 ttglobal tg = gglobal();
3642 ppComponent_Text p = (ppComponent_Text)tg->Component_Text.prv;
3644 if(p->textpanel_size < max(maxlen,128)){
3645 int newsize = max(maxlen,128);
3646 p->textpanel_size = newsize;
3647 p->textpanel_vert_size = (2+(2*(newsize*2)))*3;
3648 p->textpanel_tex_size = (4*newsize)*2;
3649 p->textpanel_ind_size = (2*3)*(newsize*2);
3651 p->textpanel_vert = REALLOC(p->textpanel_vert,p->textpanel_vert_size*
sizeof(GLfloat));
3653 p->textpanel_tex = REALLOC(p->textpanel_tex,p->textpanel_tex_size*
sizeof(GLfloat));
3655 p->textpanel_ind = REALLOC(p->textpanel_ind,p->textpanel_ind_size*
sizeof(GLuint));
3657 vert = p->textpanel_vert;
3658 tex = p->textpanel_tex;
3659 ind = p->textpanel_ind;
3661 maxlen = min(maxlen,len);
3664 penxy = pixel2normalizedViewport((GLfloat)(*pen_x),(GLfloat)(*pen_y));
3665 penxy.Y = penxy.Y - 2.0f + .05;
3669 atlas = entryset->atlas;
3670 aw = 1.0f/(float)atlas->size.X;
3671 ah = 1.0f/(float)atlas->size.Y;
3673 for(i=0;i<maxlen;i++)
3675 ichar = (int)cText[i];
3676 if (ichar ==
'\t') ichar =
' ';
3677 ae = AtlasEntrySet_getEntry(entryset,ichar);
3679 ae = AtlasEntrySet_getEntry(entryset,(
int)
' ');
3684 charScreenSize = pixel2normalizedViewportScale(ae->size.X, ae->size.Y);
3685 charScreenAdvance = pixel2normalizedViewportScale(ae->advance.X, ae->advance.Y);
3686 charScreenOffset = pixel2normalizedViewportScale(ae->pos.X,ae->pos.Y);
3688 xx = x + charScreenOffset.X;
3689 yy = y + charScreenOffset.Y;
3692 vert[kk +1] = yy - charScreenSize.Y;
3697 vert[kk +6] = xx + charScreenSize.X;
3700 vert[kk +9] = xx + charScreenSize.X;
3701 vert[kk+10] = yy - charScreenSize.Y;
3703 if(kk+11 >= p->textpanel_vert_size)
3704 printf(
"ouch vert not big enough, need %d have %d\n",kk+11 +1,p->textpanel_vert_size);
3705 x = x + charScreenAdvance.X;
3706 (*pen_x) += ae->advance.X;
3708 tex[kk +0] = ((float)(ae->apos.X))*aw;
3709 tex[kk +2] = ((float)(ae->apos.X))*aw;
3711 tex[kk +4] = ((float)(ae->apos.X + ae->size.X))*aw;
3712 tex[kk +6] = ((float)(ae->apos.X + ae->size.X))*aw;
3715 tex[kk +1] = ((float)(ih - (ae->apos.Y + ae->size.Y)))*ah;
3716 tex[kk +3] = ((float)(ih - ae->apos.Y))*ah;
3718 tex[kk +5] = ((float)(ih - ae->apos.Y))*ah;
3719 tex[kk +7] = ((float)(ih - (ae->apos.Y + ae->size.Y)))*ah;
3721 tex[kk +1] = ((float)((ae->apos.Y + ae->size.Y)))*ah;
3722 tex[kk +3] = ((float)(ae->apos.Y))*ah;
3724 tex[kk +5] = ((float)(ae->apos.Y))*ah;
3725 tex[kk +7] = ((float)((ae->apos.Y + ae->size.Y)))*ah;
3727 if(kk+7 >= p->textpanel_tex_size)
3728 printf(
"ouch tex not big enough, need %d have %d\n",kk+7 +1,p->textpanel_tex_size);
3734 ind[kk +0] = i*4 + 0;
3735 ind[kk +1] = i*4 + 1;
3736 ind[kk +2] = i*4 + 2;
3737 ind[kk +3] = i*4 + 2;
3738 ind[kk +4] = i*4 + 3;
3739 ind[kk +5] = i*4 + 0;
3740 if(kk+5 >= p->textpanel_ind_size)
3741 printf(
"ouch ind not big enough, need %d have %d\n",kk+5 +1,p->textpanel_ind_size);
3746if(0) glEnableVertexAttribArray (p->positionLoc );
3747if(0) glEnableVertexAttribArray (p->texCoordLoc );
3749 glVertexAttribPointer (p->positionLoc, 3, GL_FLOAT,
3750 GL_FALSE, 0, vert );
3752 glVertexAttribPointer ( p->texCoordLoc, 2, GL_FLOAT,
3755 glDrawElements ( GL_TRIANGLES, len*3*2, GL_UNSIGNED_INT, ind );
3763void after_textpanel_render_rows(){
3765 glEnable(GL_DEPTH_TEST);
3766 glDepthMask(GL_TRUE);
3767 restoreGlobalShader();
3772This code may not be used anymore - JAS - Apr 2017
3774static void render_screentext0(
struct X3D_Text *tnode){
3781 if(tnode && tnode->_nodeType == NODE_Text){
3787 static int once = 0;
3789 ttglobal tg = gglobal();
3790 p = (ppComponent_Text)tg->Component_Text.prv;
3792 finishedWithGlobalShader();
3793 glDepthMask(GL_FALSE);
3794 glDisable(GL_DEPTH_TEST);
3795 if(!p->programObject) initProgramObject();
3797 glUseProgram ( p->programObject );
3799 glGenTextures(1, &p->textureID);
3801 glBindTexture(GL_TEXTURE_2D, p->textureID);
3802 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
3803 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
3804 glUniformMatrix4fv(p->modelviewLoc, 1, GL_FALSE,modelviewIdentityf);
3805 glUniformMatrix4fv(p->projectionLoc, 1, GL_FALSE, projectionIdentityf);
3811 font = (AtlasFont*)sdata->atlasfont;
3813 rowvec = sdata->rowvec;
3815 if(!once) printf(
"%s %5s %10s %10s %10s %10s !\n",
"c",
"adv",
"sx",
"sy",
"x",
"y");
3817 for(row=0;row<nrow;row++){
3818 for(i=0;i<rowvec[row].len32;i++){
3821 ichar = rowvec[row].str32[i];
3822 entry = AtlasEntrySet_getEntry(set,ichar);
3826 float xpos, ypos, xsize, ysize;
3831 xpos = (float)chr.x + 90.0f + entry->pos.X;
3832 ypos = (float)chr.y + 30.0f - entry->pos.Y;
3833 xsize = entry->size.X;
3834 ysize = entry->size.Y;
3837 fxy = pixel2normalizedScreen((GLfloat)xpos,(GLfloat)ypos);
3838 fwh = pixel2normalizedScreenScale((GLfloat)xsize,(GLfloat)ysize);
3840 fxy.Y = fxy.Y - fwh.Y;
3849 fxy = pixel2normalizedViewport((GLfloat)xpos,(GLfloat)ypos);
3850 fwh = pixel2normalizedViewportScale((GLfloat)xsize,(GLfloat)ysize);
3852 fxy.Y = fxy.Y - fwh.Y;
3860 if(!once) printf(
"%c %5f %10f %10f %10f %10f\n",(
char)rowvec[row].str32[i],chr.advance,chr.sx,chr.sy,chr.x,chr.y);
3862 dug9gui_DrawSubImage(xpos,ypos, xsize, ysize,
3863 entry->apos.X, entry->apos.Y, entry->size.X, entry->size.Y,
3864 set->atlas->size.X,set->atlas->size.Y,set->atlas->bytesperpixel,set->atlas->texture);
3869 glEnable(GL_DEPTH_TEST);
3870 glDepthMask(GL_TRUE);
3871 restoreGlobalShader();
3877static void dug9gui_DrawSubImage_scene(
float xpos,
float ypos,
float xsize,
float ysize,
3878 int ix,
int iy,
int iw,
int ih,
int width,
int height,
int bpp,
unsigned char *buffer){
3899GLfloat cursorVert[] = {
3907GLfloat cursorTex[] = {
3914 GLuint ind[] = {0,1,2,3,4,5};
3919 GLfloat cursorVert2[18];
3920 GLfloat cursorTex2[12];
3922 ttglobal tg = gglobal();
3923 p = (ppComponent_Text)tg->Component_Text.prv;
3927 glActiveTexture ( GL_TEXTURE0 );
3928 glBindTexture ( GL_TEXTURE_2D, p->textureID );
3931 glUniform1i ( p->textureLoc, 0 );
3935 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA , GL_UNSIGNED_BYTE, buffer);
3937 glUniform4f(p->blendLoc,0.0f,0.0f,0.0f,1.0f);
3941 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, width, height, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, buffer);
3944 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA , GL_UNSIGNED_BYTE, buffer);
3945 glUniform4f(p->blendLoc,1.0f,1.0f,1.0f,1.0f);
3954 memcpy(cursorVert2,cursorVert,2*3*3*
sizeof(GLfloat));
3956 cursorVert2[i*3 +0] *= xsize;
3957 cursorVert2[i*3 +0] += xpos;
3958 if(!iyup) cursorVert2[i*3 +1] = 1.0f - cursorVert2[i*3 +1];
3959 cursorVert2[i*3 +1] *= ysize;
3960 cursorVert2[i*3 +1] += ypos;
3963 glVertexAttribPointer (p->positionLoc, 3, GL_FLOAT,
3964 GL_FALSE, 0, cursorVert2 );
3966 fixy.X = (float)ix/(
float)width;
3967 fiwh.X = (float)iw/(
float)width;
3969 fixy.Y = (float)iy/(
float)height;
3970 fiwh.Y = (float)ih/(
float)height;
3972 fixy.Y = (float)(height -iy)/(float)height;
3973 fiwh.Y =-(float)ih/(
float)height;
3975 memcpy(cursorTex2,cursorTex,2*3*2*
sizeof(GLfloat));
3977 cursorTex2[i*2 +0] *= fiwh.X;
3978 cursorTex2[i*2 +0] += fixy.X;
3979 cursorTex2[i*2 +1] *= fiwh.Y;
3980 cursorTex2[i*2 +1] += fixy.Y;
3982 glVertexAttribPointer (p->texCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, cursorTex2 );
3983 glEnableVertexAttribArray (p->positionLoc );
3984 glEnableVertexAttribArray (p->texCoordLoc);
3992 glDrawElements ( GL_TRIANGLES, 3*2, GL_UNSIGNED_INT, ind );
3998static void render_screentext_aligned(
struct X3D_Text *tnode,
int screenAligned){
4003 if(tnode && tnode->_nodeType == NODE_Text){
4010 static int once = 0;
4011 GLfloat modelviewf[16], projectionf[16];
4012 GLdouble modelviewd[16], projectiond[16];
4014 ttglobal tg = gglobal();
4015 p = (ppComponent_Text)tg->Component_Text.prv;
4017 finishedWithGlobalShader();
4018 glDepthMask(GL_FALSE);
4019 glDisable(GL_DEPTH_TEST);
4020 if(!p->programObject) initProgramObject();
4022 glUseProgram ( p->programObject );
4024 glGenTextures(1, &p->textureID);
4026 glBindTexture(GL_TEXTURE_2D, p->textureID);
4027 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
4028 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
4034 glUniform4f(p->color4fLoc,.5f,.5f,.5f,1.0f);
4037 dc = myap->fw_FrontMaterial.diffuse;
4038 o = 1.0f - myap->fw_FrontMaterial.transparency;
4039 glUniform4f(p->color4fLoc,dc[0],dc[1],dc[2],o);
4046 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, modelviewd);
4047 matdouble2float4(modelviewf, modelviewd);
4048 glUniformMatrix4fv(p->modelviewLoc, 1, GL_FALSE,modelviewf);
4049 FW_GL_GETDOUBLEV(GL_PROJECTION_MATRIX, projectiond);
4050 matdouble2float4(projectionf,projectiond);
4051 glUniformMatrix4fv(p->projectionLoc, 1, GL_FALSE, projectionf);
4054 glUniformMatrix4fv(p->modelviewLoc, 1, GL_FALSE,modelviewIdentityf);
4055 glUniformMatrix4fv(p->projectionLoc, 1, GL_FALSE, projectionIdentityf);
4061 font = (AtlasFont*)sdata->atlasfont;
4065 rowvec = sdata->rowvec;
4067 if(!once) printf(
"%s %5s %10s %10s %10s %10s\n",
"c",
"adv",
"sx",
"sy",
"x",
"y");
4069 for(row=0;row<nrow;row++){
4070 for(i=0;i<rowvec[row].len32;i++){
4075 ichar = rowvec[row].str32[i];
4077 set_emsize = set->EMpixels;
4078 entry = AtlasEntrySet_getEntry(set,ichar);
4082 float x,y,sx,sy,scale;
4090 rescale = (double)XRES/(
double)PPI;
4095 sx = sdata->size *rescale / (float)(set_emsize + 1) * (float) (entry->size.X + 1) ;
4096 sy = sdata->size *rescale / (float)(set_emsize + 1) * (float) (entry->size.Y + 1) ;
4099 ptresize = 20.0/12.0;
4100 x = ptresize * chr.x * scale *rescale;
4101 y = ptresize * chr.y * scale *rescale + (float)(entry->pos.Y - entry->size.Y)/(float)set_emsize*sdata->size*rescale;
4104 FW_GL_GETINTEGERV(GL_VIEWPORT, viewPort);
4105 x = ((GLfloat)x/(GLfloat)(viewPort[2]-viewPort[0])) * 2.0f -1.0f;
4106 y = ((GLfloat)y/(GLfloat)(viewPort[3]-viewPort[1])) * 2.0f -1.0f;
4107 sx = ((GLfloat)sx/(GLfloat)(viewPort[2]-viewPort[0])) * 2.0f;
4108 sy = ((GLfloat)sy/(GLfloat)(viewPort[3]-viewPort[1])) * 2.0f;
4112 if(!once) printf(
"%c %5f %10f %10f %10f %10f\n",(
char)rowvec[row].str32[i],chr.advance,chr.sx,chr.sy,chr.x,chr.y);
4113 dug9gui_DrawSubImage_scene(x,y, sx, sy,
4114 entry->apos.X, entry->apos.Y, entry->size.X, entry->size.Y,
4115 set->atlas->size.X,set->atlas->size.Y,set->atlas->bytesperpixel,set->atlas->texture);
4122 sx = chr.sx *chr.advance/(float) set_emsize * (
float) entry->size.X;
4123 sy = chr.sy *sdata->size/(float) set_emsize * (
float) entry->size.Y ;
4125 y = chr.y + sdata->size/(float)set_emsize * (
float)(entry->pos.Y - entry->size.Y);
4126 if(!once) printf(
"%c %5f %10f %10f %10f %10f\n",(
char)rowvec[row].str32[i],chr.advance,chr.sx,chr.sy,chr.x,chr.y);
4127 if(1) dug9gui_DrawSubImage_scene(x,y, sx, sy,
4128 entry->apos.X, entry->apos.Y, entry->size.X, entry->size.Y,
4129 set->atlas->size.X,set->atlas->size.Y,set->atlas->bytesperpixel,set->atlas->texture);
4135 glEnable(GL_DEPTH_TEST);
4136 glDepthMask(GL_TRUE);
4137 restoreGlobalShader();
4140void render_screentext(
struct X3D_Text *tnode){
4143 render_screentext_aligned(tnode,0);
4145void prep_screentext(
struct X3D_Text *tnode,
int num,
double screensize){
4146 if(tnode && tnode->_nodeType == NODE_Text && !tnode->_screendata){
4152 iscreensize = (int)(screensize + .5);
4153 fontname = facename_from_num(num);
4157 sdata->atlasfont = (AtlasFont*)searchAtlasTableOrLoad(fontname,iscreensize);
4158 if(!sdata->atlasfont){
4159 printf(
"dug9gui: Can't find font %s do you have the wrong name?\n",fontname);
4170static void *GUImalloc(
struct Vector **guitable,
int type){
4171 void *retval = NULL;
4176 case GUI_ATLAS: size =
sizeof(Atlas);
break;
4177 case GUI_FONT: size =
sizeof(AtlasFont);
break;
4178 case GUI_ATLASENTRY: size =
sizeof(AtlasEntry);
break;
4179 case GUI_ATLASENTRYSET: size =
sizeof(
AtlasEntrySet);
break;
4181 printf(
"no guielement of this type %d\n",type);
4184 retval = MALLOCV(size);
4187 if(*guitable == NULL) *guitable = newVector(GUIElement*,20);
4188 vector_pushBack(GUIElement*,*guitable,retval);
4194static void GUItablefree(
struct Vector **guitable){
4196 struct Vector *table = (*guitable);
4197 for(i=0;i<table->n;i++){
4199 GUIElement* el = vector_get(GUIElement*,table,i);
4204 Atlas *a = (Atlas *)el;
4205 FREE_IF_NZ(a->texture);
4206 FREE_IF_NZ(a->name);
4213 AtlasFont *f = (AtlasFont *)el;
4215 FREE_IF_NZ(f->path);
4216 for(j=0;j<f->set->entries->n;j++){
4217 AtlasEntry *e = vector_get(AtlasEntry*,f->set->entries,j);
4218 FREE_IF_NZ(e->name);
4221 deleteVector(AtlasEntry*,f->set->entries);
4226 printf(
"mystery type %d\n",itype);
4231 deleteVector(GUIElement*,*guitable);