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"
46 #include "Collision.h"
47 #include "LinearAlgebra.h"
48 #include "Component_Shape.h"
49 #include "../scenegraph/Tess.h"
50 #include "../scenegraph/Polyrep.h"
56 #include <sys/types.h>
58 #endif //ANDROID_DEBUG
60 #define HAVE_COMPILED_IN_FONT 1
68 #define POINTSIZE 200 //20 before forced TTF hinting, which triggered tesselation combiner calls on intersections
71 #define TOPTOBOTTOM (fsparam & 0x04)
72 #define LEFTTORIGHT (fsparam & 0x02)
73 #define HORIZONTAL (fsparam & 0x01)
178 #define OUT2GLB(a,s) ((double)(a) * p->size/64.0 / p->pointsize * (double)PPI/(double)XRES *s)
214 int iglyphstartindex;
234 #if defined(_ANDROID) || defined(IPHONE)
238 FILE *androidFontFile;
246 FT_Face font_face[num_fonts];
247 int font_state[num_fonts];
251 #define MAX_GLYPHS 2048
252 FT_Glyph glyphs[MAX_GLYPHS];
259 FT_Outline_Funcs FW_outline_interface;
263 #define fp_name_len 256
264 char *font_directory;
265 char thisfontname[fp_name_len];
269 double shrink_x, shrink_y;
291 FT_Vector last_point;
296 GLfloat *textpanel_vert;
297 GLfloat *textpanel_tex;
298 GLushort *textpanel_ind;
300 int textpanel_vert_size;
301 int textpanel_tex_size;
302 int textpanel_ind_size;
303 struct Vector *font_table;
304 struct Vector *atlas_table;
313 GLuint projectionLoc;
314 GLuint programObject;
318 void *Component_Text_constructor(){
323 void Component_Text_init(
struct tComponent_Text *t){
326 t->prv = Component_Text_constructor();
330 p->TextVerbose = FALSE;
331 p->font_directory = NULL;
334 p->rowvec_allocn = 0;
337 p->textpanel_vert = NULL;
338 p->textpanel_tex = NULL;
339 p->textpanel_ind = NULL;
340 p->textpanel_size = 0;
341 p->font_table = NULL;
342 p->atlas_table = NULL;
344 p->programObject = 0;
352 static void GUItablefree(
struct Vector **guitable);
353 static 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);
354 void finishedWithGlobalShader(
void);
355 void restoreGlobalShader();
356 GLuint esLoadProgram (
const char *vertShaderSrc,
const char *fragShaderSrc );
357 static int FW_Open_Face(FT_Library library,
char *thisfontname,
int faceIndex, FT_Face *face);
361 void Component_Text_clear(
struct tComponent_Text *t){
366 FREE_IF_NZ(p->font_directory);
370 for(row=0;row<p->rowvec_allocn;row++){
371 FREE_IF_NZ(p->rowvec[row].str32);
372 FREE_IF_NZ(p->rowvec[row].chr);
374 FREE_IF_NZ(p->rowvec);
376 if(p->textpanel_size){
377 FREE_IF_NZ(p->textpanel_vert);
378 FREE_IF_NZ(p->textpanel_tex);
379 FREE_IF_NZ(p->textpanel_ind);
382 GUItablefree(&p->atlas_table);
385 GUItablefree(&p->font_table);
392 void fwl_fontFileLocation(
char *fontFileLocation) {
397 if (fontFileLocation)
398 if (do_dir_exists(fontFileLocation)) {
399 FREE_IF_NZ(p->font_directory);
400 p->font_directory = STRDUP(fontFileLocation);
405 static void FW_NewVertexPoint();
406 static int FW_moveto (FT_Vector* to,
void* user);
407 static int FW_lineto(FT_Vector* to,
void* user);
408 static int FW_conicto(FT_Vector* control, FT_Vector* to,
void* user);
409 static int FW_cubicto(FT_Vector* control1, FT_Vector* control2, FT_Vector* to,
void* user);
410 static void FW_make_fontname (
int num);
411 static void render_screentext(
struct X3D_Text * node);
416 static FT_Error FW_Load_Char(
unsigned int idx);
417 static void FW_draw_outline(FT_OutlineGlyph oglyph);
418 static void FW_draw_character(FT_Glyph glyph);
419 static int open_font(
void);
421 #if defined(_ANDROID) || defined(IPHONE)
423 void fwg_AndroidFontFile(FILE *myFile,
int len) {
425 p->androidFontFile = myFile;
432 void render_Text (
struct X3D_Text * node)
436 render_screentext(node);
438 COMPILE_POLY_IF_REQUIRED (NULL, NULL, NULL, NULL, NULL);
440 CULL_FACE(node->solid)
441 render_polyrep(node);
446 static
void FW_NewVertexPoint ()
497 p->FW_rep_->actualCoord[p->FW_pointctr*3+0] = (
float) (OUT2GLB(p->last_point.x,p->shrink_x) + p->pen_x);
498 p->FW_rep_->actualCoord[p->FW_pointctr*3+1] = (float) (OUT2GLB(p->last_point.y,p->shrink_y) + p->pen_y);
499 p->FW_rep_->actualCoord[p->FW_pointctr*3+2] = p->TextZdist;
502 if (p->FW_RIA_indx >500) {
503 ConsoleMessage (
"Text, relative index too small\n");
504 freewrlDie(
"FW_NewVertexPoint: this should never happen...");
507 p->FW_RIA[p->FW_RIA_indx]=p->FW_pointctr;
508 v2[0]=p->FW_rep_->actualCoord[p->FW_pointctr*3+0];
509 v2[1]=p->FW_rep_->actualCoord[p->FW_pointctr*3+1];
510 v2[2]=p->FW_rep_->actualCoord[p->FW_pointctr*3+2];
513 FW_GLU_TESS_VERTEX(tg->Tess.global_tessobj,v2,&p->FW_RIA[p->FW_RIA_indx]);
515 if (p->TextVerbose) {
516 printf (
"FW_NewVertexPoint %f %f %f index %d\n",
517 p->FW_rep_->actualCoord[p->FW_pointctr*3+0],
518 p->FW_rep_->actualCoord[p->FW_pointctr*3+1],
519 p->FW_rep_->actualCoord[p->FW_pointctr*3+2],
525 if (p->FW_pointctr >= p->coordmaxsize) {
526 p->coordmaxsize+=800;
527 p->FW_rep_->actualCoord = (
float *)REALLOC(p->FW_rep_->actualCoord,
528 sizeof(*(p->FW_rep_->actualCoord))*p->coordmaxsize*3);
529 printf(
"realloc actualCoord=%p\n",p->FW_rep_->actualCoord);
532 #define GLU_UNKNOWN 100124
533 static int FW_moveto (FT_Vector* to,
void* user)
541 if (p->contour_started) {
542 FW_GLU_NEXT_CONTOUR(tg->Tess.global_tessobj,GLU_UNKNOWN);
546 p->contour_started = TRUE;
548 p->last_point.x = to->x; p->last_point.y = to->y;
551 printf (
"FW_moveto tox %ld toy %ld\n",to->x, to->y);
558 static int FW_lineto (FT_Vector* to,
void* user)
564 if ((p->last_point.x == to->x) && (p->last_point.y == to->y)) {
569 p->last_point.x = to->x;
570 p->last_point.y = to->y;
572 if (p->TextVerbose) {
573 printf (
"FW_lineto, going to %ld %ld\n",to->x, to->y);
583 static int FW_conicto (FT_Vector* control, FT_Vector* to,
void* user)
593 printf (
"FW_conicto\n");
596 ncontrol.x = (int) ((
double) 0.25*p->last_point.x + 0.5*control->x + 0.25*to->x);
597 ncontrol.y = (int) ((
double) 0.25*p->last_point.y + 0.5*control->y + 0.25*to->y);
602 FW_lineto (&ncontrol,user);
610 static int FW_cubicto (FT_Vector* control1, FT_Vector* control2, FT_Vector* to,
void* user)
615 printf (
"FW_cubicto\n");
617 FW_lineto (control1, user);
618 FW_lineto (control2, user);
619 FW_lineto (to, user);
639 } font_name_table [] = {
641 {
"VeraSe",
"serif", NULL, NULL, 0x04,0,0,1},
642 {
"VeraSeBd",
"serif",
"bold", NULL, 0x05,1,0,1},
643 {
"VeraSe",
"serif",
"italic", NULL, 0x06,0,1,1},
644 {
"VeraSeBd",
"serif",
"bold italic",
"bold oblique", 0x07,1,1,1},
645 {
"Vera",
"sans", NULL, NULL, 0x08,0,0,2},
646 {
"VeraBd",
"sans",
"bold", NULL, 0x09,0,1,2},
647 {
"VeraIt",
"sans",
"italic", NULL, 0x0a,1,0,2},
648 {
"VeraBI",
"sans",
"bold italic",
"bold oblique", 0x0b,1,1,2},
649 {
"VeraMono",
"monospace",NULL, NULL, 0x10,0,0,4},
650 {
"VeraMoBd",
"monospace",
"bold", NULL, 0x11,1,0,4},
651 {
"VeraMoIt",
"monospace",
"italic", NULL, 0x12,0,1,4},
652 {
"VeraMoBI",
"monospace",
"bold italic",
"bold oblique", 0x13,1,1,4},
653 {NULL, NULL, NULL, NULL, 0,0,0,0},
655 struct name_num *get_fontname_entry_by_num(num){
659 while(font_name_table[i].facename){
660 if(font_name_table[i].num == num) {
661 retval = &font_name_table[i];
668 struct name_num *get_fontname_entry_by_facename(
char *facename){
672 while(font_name_table[i].facename){
673 if(!strcmp(font_name_table[i].facename,facename)) {
674 retval = &font_name_table[i];
681 char *facename_from_num(
int num){
685 val = get_fontname_entry_by_num(num);
686 if(val) retval = val->facename;
691 #ifdef HAVE_FONTCONFIG
692 void FW_make_fontname(
int num) {
721 FcPattern *FW_fp=NULL;
722 FcChar8 *FW_file=NULL;
726 char* configfile = (
char*)FcConfigFilename(0);
727 FILE*fi = fopen(configfile,
"rb");
736 printf(
"<debug> FontConfig Initialization failed.\n");
738 FcConfig * config = FcConfigGetCurrent();
740 printf(
"<debug> FontConfig Config Initialization failed.\n");
743 FcFontSet *set = FcConfigGetFonts(config, FcSetSystem);
745 if(!set || !set->nfont) {
746 printf(
"<debug> FontConfig has found zero fonts. This is probably a bad thing.\n");
751 FW_fp=FcPatternBuild(NULL,FC_FAMILY,FcTypeString,
"serif",FC_OUTLINE,FcTypeBool,FcTrue,NULL);
754 FW_fp=FcPatternBuild(NULL,FC_FAMILY,FcTypeString,
"serif",FC_OUTLINE,FcTypeBool,FcTrue,NULL);
755 FcPatternAddString(FW_fp,FC_STYLE,(
const FcChar8*)
"bold");
758 FW_fp=FcPatternBuild(NULL,FC_FAMILY,FcTypeString,
"serif",FC_OUTLINE,FcTypeBool,FcTrue,NULL);
759 FcPatternAddString(FW_fp,FC_STYLE,(
const FcChar8*)
"italic");
760 FcPatternAddString(FW_fp,FC_STYLE,(
const FcChar8*)
"oblique");
763 FW_fp=FcPatternBuild(NULL,FC_FAMILY,FcTypeString,
"serif",FC_OUTLINE,FcTypeBool,FcTrue,NULL);
764 FcPatternAddString(FW_fp,FC_STYLE,(
const FcChar8*)
"bold italic");
765 FcPatternAddString(FW_fp,FC_STYLE,(
const FcChar8*)
"bold oblique");
768 FW_fp=FcPatternBuild(NULL,FC_FAMILY,FcTypeString,
"sans",FC_OUTLINE,FcTypeBool,FcTrue,NULL);
771 FW_fp=FcPatternBuild(NULL,FC_FAMILY,FcTypeString,
"sans",FC_OUTLINE,FcTypeBool,FcTrue,NULL);
772 FcPatternAddString(FW_fp,FC_STYLE,(
const FcChar8*)
"bold");
775 FW_fp=FcPatternBuild(NULL,FC_FAMILY,FcTypeString,
"sans",FC_OUTLINE,FcTypeBool,FcTrue,NULL);
776 FcPatternAddString(FW_fp,FC_STYLE,(
const FcChar8*)
"italic");
777 FcPatternAddString(FW_fp,FC_STYLE,(
const FcChar8*)
"oblique");
780 FW_fp=FcPatternBuild(NULL,FC_FAMILY,FcTypeString,
"sans",FC_OUTLINE,FcTypeBool,FcTrue,NULL);
781 FcPatternAddString(FW_fp,FC_STYLE,(
const FcChar8*)
"bold italic");
782 FcPatternAddString(FW_fp,FC_STYLE,(
const FcChar8*)
"bold oblique");
785 FW_fp=FcPatternBuild(NULL,FC_FAMILY,FcTypeString,
"monospace",FC_OUTLINE,FcTypeBool,FcTrue,NULL);
788 FW_fp=FcPatternBuild(NULL,FC_FAMILY,FcTypeString,
"monospace",FC_OUTLINE,FcTypeBool,FcTrue,NULL);
789 FcPatternAddString(FW_fp,FC_STYLE,(
const FcChar8*)
"bold");
792 FW_fp=FcPatternBuild(NULL,FC_FAMILY,FcTypeString,
"monospace",FC_OUTLINE,FcTypeBool,FcTrue,NULL);
793 FcPatternAddString(FW_fp,FC_STYLE,(
const FcChar8*)
"italic");
794 FcPatternAddString(FW_fp,FC_STYLE,(
const FcChar8*)
"oblique");
797 FW_fp=FcPatternBuild(NULL,FC_FAMILY,FcTypeString,
"monospace",FC_OUTLINE,FcTypeBool,FcTrue,NULL);
798 FcPatternAddString(FW_fp,FC_STYLE,(
const FcChar8*)
"bold italic");
799 FcPatternAddString(FW_fp,FC_STYLE,(
const FcChar8*)
"bold oblique");
802 printf (
"dont know how to handle font id %x\n",num);
806 FcConfigSubstitute(0,FW_fp,FcMatchPattern);
807 FcDefaultSubstitute(FW_fp);
808 set = FcFontSort(0, FW_fp, 1, 0, &result);
814 for(t=0;t<set->nfont;t++) {
815 FcPattern *match = set->fonts[t];
816 if (FcPatternGetString(match,FC_FILE,0,&FW_file) != FcResultMatch) {
817 printf(
"<debug> FontConfig: Couldn't get fontconfig's filename for font id %x\n", num);
822 strncpy(p->thisfontname,(
char *)FW_file,strlen((
char *)FW_file));
823 p->thisfontname[strlen((
char *)FW_file)] =
'\0';
828 printf(
"<debug> no set? wha?\n");
830 FcPatternDestroy(FW_fp);
832 if (set) FcFontSetSortDestroy(set);
837 void FW_make_fontname(
int num) {
866 if (!p->font_directory) {
867 printf(
"Internal error: no font directory.\n");
871 fontname = facename_from_num(num);
873 printf (
"dont know how to handle font id %x\n",num);
874 p->thisfontname[0] = 0;
876 if(p->font_directory){
877 strcpy (p->thisfontname, p->font_directory);
878 strcat(p->thisfontname,
"/");
880 strcat(p->thisfontname,fontname);
881 strcat(p->thisfontname,
".ttf");
886 static FT_Face FW_init_face0(FT_Library library,
char* thisfontname)
899 if ((p->fileLen == 0) || (p->androidFontFile ==NULL)) {
900 ConsoleMessage (
"FW_init_face, fileLen and/or androidFontFile issue");
908 ConsoleMessage (
"TEXT INITIALIZATION - checking on the font file before doing anything");
909 if (0 == fstat(fileno(p->androidFontFile), &buf)) {
910 ConsoleMessage(
"TEXT INITIALIZATION file size is %ld\n", buf.st_size);
911 ConsoleMessage(
"TEXT INITIALIZATION time modified is %s\n", ctime(&buf.st_atime));
914 #endif //ANDROID_DEBUG
919 unsigned char *myFileData = MALLOC(
void *, p->fileLen+1);
921 frv = fread (myFileData, (
size_t)p->fileLen, (
size_t)1, p->androidFontFile);
922 myArgs.flags = FT_OPEN_MEMORY;
923 myArgs.memory_base = myFileData;
924 myArgs.memory_size = p->fileLen;
926 err = FT_Open_Face(library, &myArgs, 0, &ftface);
929 sprintf (line,
"FreeWRL - FreeType, can not set char size for font %s\n",thisfontname);
930 ConsoleMessage(line);
938 if (0 == fstat(fileno(p->androidFontFile), &buf)) {
939 ConsoleMessage(
"FIN TEXT INITIALIZATION file size is %ld\n", buf.st_size);
940 ConsoleMessage(
"FIN TEXT INITIALIZATION time modified is %s\n", ctime(&buf.st_atime));
943 #endif //ANDROID_DEBUG
945 fclose(p->androidFontFile);
946 p->androidFontFile = NULL;
950 err = FW_Open_Face(library, thisfontname, 0, &ftface);
955 printf (
"FreeType - can not use font %s\n",thisfontname);
961 int FW_set_facesize(FT_Face ftface,
char *thisfontname,
double pointsize){
971 pt_dot6 = (int)(pointsize * 64.0 + .5);
972 err = FT_Set_Char_Size(ftface,
979 printf (
"FreeWRL - FreeType, can not set char size for font %s\n",thisfontname);
993 FT_Error FW_Load_Char(
unsigned int idx)
995 FT_Glyph glyph = NULL;
1000 if (p->cur_glyph >= MAX_GLYPHS) {
1005 glyph_index = FT_Get_Char_Index(p->font_face[p->myff],idx);
1009 error = FT_Load_Glyph(p->font_face[p->myff], glyph_index, FT_LOAD_DEFAULT) ||
1010 FT_Get_Glyph(p->font_face[p->myff]->glyph, &glyph);
1012 if (!error) { p->glyphs[p->cur_glyph++] = glyph; }
1019 static void FW_draw_outline (FT_OutlineGlyph oglyph)
1029 gluTessNormal(tg->Tess.global_tessobj,0.0,0.0,1.0);
1032 cbdata.coords = p->FW_rep_->actualCoord;
1033 cbdata.counter = &p->FW_pointctr;
1034 cbdata.ria = p->FW_RIA;
1035 cbdata.riaindex = &p->FW_RIA_indx;
1039 gluTessBeginPolygon( tg->Tess.global_tessobj, &cbdata );
1040 gluTessBeginContour( tg->Tess.global_tessobj );
1044 retval = FT_Outline_Decompose( &oglyph->outline, &p->FW_outline_interface, &thisptr);
1047 gluTessEndContour( tg->Tess.global_tessobj );
1048 gluTessEndPolygon( tg->Tess.global_tessobj );
1051 if (retval != FT_Err_Ok)
1052 printf(
"FT_Outline_Decompose, error %d\n",retval);
1056 static void FW_draw_character (FT_Glyph glyph)
1059 if (glyph->format == ft_glyph_format_outline) {
1060 FW_draw_outline ((FT_OutlineGlyph) glyph);
1061 p->pen_x += (glyph->advance.x >> 10);
1063 printf (
"FW_draw_character; glyphformat -- need outline for %s %s\n",
1064 p->font_face[p->myff]->family_name,p->font_face[p->myff]->style_name);
1066 if (p->TextVerbose) printf (
"done character\n");
1077 printf (
"open_font called\n");
1079 p->FW_outline_interface.move_to = (FT_Outline_MoveTo_Func)FW_moveto;
1080 p->FW_outline_interface.line_to = (FT_Outline_LineTo_Func)FW_lineto;
1081 p->FW_outline_interface.conic_to = (FT_Outline_ConicTo_Func)FW_conicto;
1082 p->FW_outline_interface.cubic_to = (FT_Outline_CubicTo_Func)FW_cubicto;
1083 p->FW_outline_interface.shift = 0;
1084 p->FW_outline_interface.delta = 0;
1088 #ifndef HAVE_FONTCONFIG
1090 if(!p->font_directory)
1091 p->font_directory = makeFontDirectory();
1094 if (p->font_directory == NULL) {
1096 ConsoleMessage (
"Have a Text node, but no font library or directory found; continuing with a default builtin font\n");
1099 #endif //HAVE_FONTCONFIG
1103 for (len = 0; len < num_fonts; len++) {
1104 p->font_state[len] = FONTSTATE_NONE;
1107 if ((err = FT_Init_FreeType(&p->library))) {
1108 fprintf(stderr,
"FreeWRL FreeType Initialize error %d\n",err);
1114 int open_FTlibrary_if_not_already(){
1120 printf (
"Could not find System Fonts for Text nodes\n");
1125 FT_Library getFontLibrary(){
1129 if(open_FTlibrary_if_not_already())
1130 library = p->library;
1155 static const unsigned int Replacement = ( 0xfffd );
1156 static const unsigned char UTF8TailLengths[256] = {
1157 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1158 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1159 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1160 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1161 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1162 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1163 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1164 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1165 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1170 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1171 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
1172 3,3,3,3,3,3,3,3,4,4,4,4,5,5,0,0
1175 static unsigned int utf8_to_utf32_char(
unsigned char *s,
unsigned char *end,
unsigned int *inc ) {
1176 unsigned int tail, i, c;
1182 tail = UTF8TailLengths[c];
1183 if( !tail || (s + tail > end))
1187 c &= ( 0x3f >> tail );
1188 for(i=0;i<tail;++i) {
1189 if( (s[i] & 0xc0) != 0x80 )
1191 c = (c << 6) + (s[i] & 0x3f);
1202 unsigned int *utf8_to_utf32(
unsigned char *utf8string,
unsigned int *str32,
unsigned int *len32)
1208 unsigned int *to, *to0;
1209 unsigned char *start, *end;
1211 lenchar = (int)strlen((
const char *)utf8string);
1214 end = (
unsigned char *)&utf8string[lenchar];
1216 while ( start < end ) {
1217 while ( ( *start < 0x80 ) && ( start < end ) ) {
1221 if ( start < end ) {
1222 unsigned int inc = 0;
1223 *to++ = utf8_to_utf32_char(start,end,&inc);
1236 Seems to be unused - JAS - April 2017
1238 static unsigned int utf8_to_utf32_bytes(
unsigned char *s,
unsigned char *end)
1240 unsigned int tail, c;
1247 tail = UTF8TailLengths[c];
1248 tail = s + tail > end ? (
unsigned int)end - (
unsigned int)s : tail;
1256 Seems to be unused - JAS - April 2017
1258 static unsigned int len_utf8(
unsigned char *utf8string)
1260 unsigned char *start, *end;
1262 lenchar = (int)strlen((
const char *)utf8string);
1264 end = (
unsigned char *)&utf8string[lenchar];
1266 while ( start < end ) {
1267 while ( ( *start < 0x80 ) && ( start < end ) ) {
1271 if ( start < end ) {
1272 start += utf8_to_utf32_bytes(start,end);
1284 void register_Polyrep_combiner();
1285 void prep_screentext(
struct X3D_Text *tnode,
int num,
double screensize);
1294 void register_Text_combiner();
1295 void FW_rendertext(
struct X3D_Text *tnode,
unsigned int numrows,
struct Uni_String **ptr,
1296 unsigned int nl,
float *length,
double maxext,
1297 double spacing,
double mysize,
unsigned int fsparam,
1300 unsigned char *str = NULL;
1301 unsigned int i,row,ii,irow;
1343 p->TextZdist = 0.0f;
1347 if(!open_FTlibrary_if_not_already())
return;
1350 printf (
"entering FW_Render_text \n");
1358 p->myff = (fsparam >> 3) & 0x1F;
1359 #if defined (ANDROID)
1369 if (p->font_state[p->myff] < FONTSTATE_TRIED) {
1372 FW_make_fontname(p->myff);
1373 fontface = FW_init_face0(p->library,p->thisfontname);
1375 p->font_face[p->myff] = fontface;
1376 p->font_state[p->myff] = FONTSTATE_LOADED;
1378 p->font_state[p->myff] = FONTSTATE_TRIED;
1381 if(!p->font_face[p->myff])
return;
1383 if(tnode->_isScreen){
1384 p->pointsize = mysize;
1385 p->size = mysize * (double)XRES/(
double)PPI;
1387 p->pointsize = POINTSIZE;
1391 FW_set_facesize(p->font_face[p->myff],p->thisfontname,p->pointsize);
1394 if(tnode->_isScreen){
1397 if(!tnode->_screendata)
1398 prep_screentext(tnode,p->myff, p->pointsize);
1400 rowvec_allocn = sdata->nalloc;
1401 rowvec = sdata->rowvec;
1404 rowvec_allocn = p->rowvec_allocn;
1408 rowvec = (
row32*)MALLOCV(numrows *
sizeof(
row32));
1409 memset(rowvec,0,numrows *
sizeof(
row32));
1411 if(rowvec_allocn < numrows){
1412 rowvec = REALLOC(rowvec,numrows *
sizeof(
row32));
1413 memset(&rowvec[rowvec_allocn],0,(numrows - rowvec_allocn)*
sizeof(
row32));
1414 rowvec_allocn = numrows;
1417 for (row=0; row<numrows; row++) {
1419 str = (
unsigned char *)ptr[row]->strptr;
1420 len = strlen((
const char *)str);
1421 if(rowvec[row].allocn < len){
1422 rowvec[row].str32 = (
unsigned int *)REALLOC(rowvec[row].str32,(len+1) *
sizeof(
unsigned int));
1423 rowvec[row].chr = (
chardata *) REALLOC(rowvec[row].chr,len*
sizeof(
chardata));
1424 rowvec[row].allocn = len;
1425 rowvec[row].len32 = 0;
1428 if(tnode->_isScreen){
1431 sdata->rowvec = rowvec;
1432 sdata->nalloc = rowvec_allocn;
1433 sdata->nrow = numrows;
1434 sdata->faceheight = (
float)p->font_face[p->myff]->height;
1435 sdata->size = p->size;
1436 sdata->emsize = mysize;
1439 p->rowvec_allocn = rowvec_allocn;
1443 for (row=0; row<numrows; row++) {
1444 unsigned int len32, *str32;
1445 double total_row_advance, widest_char;
1446 str = (
unsigned char *)ptr[row]->strptr;
1451 str32 = rowvec[row].str32;
1452 utf8_to_utf32(str,str32,&len32);
1453 rowvec[row].iglyphstartindex = p->cur_glyph;
1454 rowvec[row].len32 = len32;
1455 rowvec[row].str32 = str32;
1456 total_row_advance = 0;
1458 for(i=0;i<len32;i++){
1460 FW_Load_Char(str32[i]);
1461 icount = p->cur_glyph -1;
1462 rowvec[row].chr[i].iglyph = icount;
1464 rowvec[row].chr[i].advance = OUT2GLB(p->glyphs[icount]->advance.x >> 10,1.0);
1465 total_row_advance += rowvec[row].chr[i].advance;
1466 widest_char = rowvec[row].chr[i].advance > widest_char ? rowvec[row].chr[i].advance : widest_char;
1469 rowvec[row].hrowsize = total_row_advance;
1470 rowvec[row].vcolsize = len32 * p->size;
1471 rowvec[row].widestchar = widest_char;
1472 char_count += len32;
1476 if (p->TextVerbose) {
1477 printf (
"Text: rows %d char_count %d\n",numrows,char_count);
1489 for(row = 0; row < numrows; row++) {
1491 hrowsize = rowvec[row].hrowsize;
1492 maxlen = hrowsize > maxlen ? hrowsize : maxlen;
1495 shrink = maxext / maxlen;
1507 if(fsparam & (0x400<<(4))){
1511 if(fsparam & (0x200<<(4))){
1515 if (fsparam & (0x800<<(4))) {
1516 p->pen_y = (double)(numrows)/2.0;
1519 if (fsparam & (0x1000<<(4))) {
1521 p->pen_y = (double)numrows;
1529 if(fsparam & (0x200<<(4)))
1531 p->pen_y = numrows - 1.0 - p->pen_y;
1535 for(irow = 0; irow < numrows; irow++) {
1536 unsigned int lenchars;
1540 if(!TOPTOBOTTOM) row = numrows - irow -1;
1542 str = (
unsigned char *)ptr[row]->strptr;
1544 printf (
"text2 row %d :%s:\n",row, str);
1547 rowlen = rowvec[row].hrowsize;
1548 lenchars = rowvec[row].len32;
1550 if((row < nl) && !(APPROX(length[row],0.0))) {
1551 rshrink = length[row] / rowlen;
1555 if (((fsparam & 0x200) || (fsparam & 0x400)) && !LEFTTORIGHT ) {
1561 if (fsparam & 0x800) {
1562 p->pen_x = -rowlen/2.0;
1567 if ((fsparam & 0x1000) && LEFTTORIGHT ) {
1572 for(ii=0; ii<lenchars; ii++) {
1576 i = lenchars - ii -1;
1577 rowvec[row].chr[i].x = p->pen_x;
1578 rowvec[row].chr[i].y = p->pen_y;
1579 rowvec[row].chr[i].sx = shrink*rshrink;
1580 rowvec[row].chr[i].sy = 1.0;
1581 p->pen_x += rowvec[row].chr[i].advance * shrink*rshrink;
1583 p->pen_y += -spacing * p->size;
1589 double widest_column, column_spacing;
1591 double maxlen = 0.0;
1593 for(row = 0; row < numrows; row++) {
1594 double vcolsize = rowvec[row].vcolsize;
1595 maxlen = vcolsize > maxlen ? vcolsize : maxlen;
1598 if(maxlen > maxext) shrink = maxext / maxlen;
1600 widest_column = 0.0;
1601 for(row=0;row<numrows;row++)
1602 widest_column = rowvec[row].widestchar > widest_column ? rowvec[row].widestchar : widest_column;
1605 column_spacing = spacing * p->size;
1615 if(fsparam & (0x200<<(4)) || fsparam & (0x400<<(4))){
1620 p->pen_x = -(double)numrows * column_spacing;
1624 if (fsparam & (0x800<<(4))) {
1625 p->pen_x = -(double)(numrows)/2.0 *column_spacing;
1628 if (fsparam & (0x1000<<(4))) {
1631 p->pen_x = -(double)numrows * column_spacing;
1637 for(irow = 0; irow < numrows; irow++) {
1638 unsigned int lenchars;
1643 if(!LEFTTORIGHT) row = numrows - irow -1;
1645 str = (
unsigned char *)ptr[row]->strptr;
1647 printf (
"text2 row %d :%s:\n",row, str);
1650 rowlen = rowvec[row].vcolsize;
1651 lenchars = rowvec[row].len32;
1653 if((row < nl) && !(APPROX(length[row],0.0))) {
1654 rshrink = length[row] / rowlen;
1657 starty = -1.0*shrink*rshrink*p->size;
1659 if ((fsparam & 0x200) || (fsparam & 0x400)){
1663 p->pen_y = rowlen + starty;
1667 if (fsparam & 0x800) {
1668 p->pen_y = rowlen/2.0 + starty;
1672 if (fsparam & 0x1000 ) {
1674 p->pen_y = rowlen + starty;
1679 for(ii=0; ii<lenchars; ii++) {
1686 i = lenchars - ii -1;
1689 penx = penx + column_spacing - rowvec[row].chr[i].advance;
1691 rowvec[row].chr[i].x = penx;
1692 rowvec[row].chr[i].y = p->pen_y;
1693 rowvec[row].chr[i].sx = 1.0;
1694 rowvec[row].chr[i].sy = shrink*rshrink;
1695 p->pen_y += -p->size * shrink * rshrink;
1698 p->pen_x += column_spacing;
1702 if(!tnode->_isScreen){
1704 register_Text_combiner();
1711 p->contour_started = FALSE;
1714 est_tri = char_count*800;
1715 p->coordmaxsize=est_tri;
1716 p->cindexmaxsize=est_tri;
1717 p->FW_rep_->cindex=MALLOC(GLuint *,
sizeof(*(p->FW_rep_->cindex))*est_tri);
1718 p->FW_rep_->actualCoord = MALLOC(
float *,
sizeof(*(p->FW_rep_->actualCoord))*est_tri*3);
1719 for(row = 0; row < numrows; row++) {
1720 unsigned int lenchars = rowvec[row].len32;
1721 for(i=0; i<lenchars; i++) {
1725 chr = rowvec[row].chr[i];
1728 p->shrink_x = chr.sx;
1729 p->shrink_y = chr.sy;
1732 tg->Tess.global_IFS_Coord_count = 0;
1735 kk = rowvec[row].chr[i].iglyph;
1736 FW_draw_character (p->glyphs[kk]);
1737 FT_Done_Glyph (p->glyphs[kk]);
1741 for (x=0; x<tg->Tess.global_IFS_Coord_count; x++) {
1746 if ((tg->Tess.global_IFS_Coords[x] >= p->cindexmaxsize) ||
1747 (p->indx_count >= p->cindexmaxsize) ||
1748 (tg->Tess.global_IFS_Coords[x] < 0)) {
1750 printf (
"Tesselated index %d out of range; skipping indx_count, %d cindexmaxsize %d global_IFS_Coord_count %d\n",
1751 tg->Tess.global_IFS_Coords[x],p->indx_count,p->cindexmaxsize,tg->Tess.global_IFS_Coord_count);
1755 p->FW_rep_->cindex[p->indx_count] = p->FW_rep_->cindex[p->indx_count-1];
1756 if (p->indx_count < (p->cindexmaxsize-1)) p->indx_count ++;
1762 p->FW_rep_->cindex[p->indx_count++] = tg->Tess.global_IFS_Coords[x];
1766 if (p->indx_count > (p->cindexmaxsize-400)) {
1767 p->cindexmaxsize += 800;
1768 p->FW_rep_->cindex=(GLuint *)REALLOC(p->FW_rep_->cindex,
sizeof(*(p->FW_rep_->cindex))*p->cindexmaxsize);
1774 static int _once = 0;
1776 ntris = tg->Tess.global_IFS_Coord_count / 3;
1779 FILE *fptris = fopen(
"test_glyph_triangles.wrl",
"w+");
1780 fprintf(fptris,
"%s\n",
"#VRML V2.0 utf8");
1781 fprintf(fptris,
"Transform {\n children [\n Shape {\n appearance Appearance { material Material { diffuseColor .6 .6 .6 }}\n");
1782 fprintf(fptris,
" geometry IndexedFaceSet { solid FALSE \n");
1783 fprintf(fptris,
" coordIndex ");
1785 fprintf(fptris,
"[");
1786 for(ii=0;ii<ntris;ii++){
1787 for(jj=0;jj<3;jj++){
1788 fprintf(fptris,
" %d",p->FW_rep_->cindex[ii*3+jj]);
1790 fprintf(fptris,
" -1");
1792 fprintf(fptris,
"]\n");
1794 fprintf(fptris,
"coord Coordinate { \n");
1795 fprintf(fptris,
" point [");
1802 for(ii=0;ii<p->FW_RIA_indx;ii++){
1803 for(jj=0;jj<3;jj++){
1804 fprintf(fptris,
" %f",p->FW_rep_->actualCoord[ii*3 + jj]);
1806 fprintf(fptris,
",");
1809 fprintf(fptris,
" ] }}}\n");
1810 fprintf(fptris,
" ]}");
1813 fptris = fopen(
"test_glyph_polygon.wrl",
"w+");
1814 fprintf(fptris,
"%s\n",
"#VRML V2.0 utf8");
1815 fprintf(fptris,
"Transform {\n children [\n Shape {\n appearance Appearance { material Material { diffuseColor .5 .5 .5 }}\n");
1816 fprintf(fptris,
" geometry IndexedFaceSet { solid FALSE convex FALSE \n");
1817 fprintf(fptris,
" coordIndex ");
1819 fprintf(fptris,
"[");
1820 for(ii=0;ii<p->FW_RIA_indx;ii++){
1821 fprintf(fptris,
" %d",ii);
1823 fprintf(fptris,
" -1");
1824 fprintf(fptris,
"]\n");
1826 fprintf(fptris,
"coord Coordinate { \n");
1827 fprintf(fptris,
" point [");
1834 for(ii=0;ii<p->FW_RIA_indx;ii++){
1835 for(jj=0;jj<3;jj++){
1836 fprintf(fptris,
" %f",p->FW_rep_->actualCoord[ii*3 + jj]);
1838 fprintf(fptris,
",");
1841 fprintf(fptris,
" ] }}}\n");
1842 fprintf(fptris,
" ]}");
1847 fprintf(fptris,
"%s\n",
"#VRML V2.0 utf8");
1848 fprintf(fptris,
"Transform {\n translation 0 0 .1 children [\n Shape {\n appearance Appearance { material Material { emissiveColor .1 .8 .2 }}\n");
1849 fprintf(fptris,
" geometry Polyline2D { \n");
1850 fprintf(fptris,
" lineSegments [");
1857 for(ii=0;ii<p->FW_RIA_indx;ii++){
1858 for(jj=0;jj<2;jj++){
1859 fprintf(fptris,
" %f",p->FW_rep_->actualCoord[ii*3 + jj]);
1861 fprintf(fptris,
",");
1864 fprintf(fptris,
" ] }}\n");
1865 fprintf(fptris,
" ]}");
1876 p->FW_rep_->ntri=p->indx_count/3;
1878 p->FW_rep_->ccw=FALSE;
1881 if (p->indx_count !=0) {
1888 p->FW_rep_->normal = MALLOC(
float *,
sizeof(*(p->FW_rep_->normal))*p->indx_count*3);
1889 for (i = 0; i<(
unsigned int)p->indx_count; i++) {
1890 p->FW_rep_->normal[i*3+0] = 0.0f;
1891 p->FW_rep_->normal[i*3+1] = 0.0f;
1892 p->FW_rep_->normal[i*3+2] = 1.0f;
1896 if (HAVETODOTEXTURES) {
1897 p->FW_rep_->GeneratedTexCoords[0] = MALLOC(
float *,
sizeof(*(p->FW_rep_->GeneratedTexCoords[0]))*(p->FW_pointctr+1)*3);
1900 for (i=0; i<(
unsigned int)p->FW_pointctr; i++) {
1901 p->FW_rep_->GeneratedTexCoords[0][i*3+0] = p->FW_rep_->actualCoord[i*3+0]*1.66f;
1902 p->FW_rep_->GeneratedTexCoords[0][i*3+1] = 0.0f;
1903 p->FW_rep_->GeneratedTexCoords[0][i*3+2] = p->FW_rep_->actualCoord[i*3+1]*1.66f;
1906 register_Polyrep_combiner();
1909 if (p->TextVerbose) printf (
"exiting FW_Render_text\n");
1912 int avatarCollisionVolumeIntersectMBBf(
double *modelMatrix,
float *minVals,
float *maxVals);
1914 void collide_Text (
struct X3D_Text *node)
1917 GLDOUBLE awidth,atop,abottom,astep,modelMatrix[16];
1924 if(node->_isScreen > 0)
return;
1926 naviinfo = (
struct sNaviInfo*)tg->Bindable.naviinfo;
1928 awidth = naviinfo->width;
1929 atop = naviinfo->width;
1930 abottom = -naviinfo->height;
1931 astep = -naviinfo->height+naviinfo->step;
1940 if (node->_intern == NULL)
return;
1943 if (node->_intern->ntri == 0)
return;
1947 change = node->_intern->irep_change;
1949 COMPILE_POLY_IF_REQUIRED(NULL, NULL, NULL, NULL, NULL);
1952 node->_intern->irep_change = change;
1957 pr = *(node->_intern);
1965 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, modelMatrix);
1967 matmultiplyAFFINE(modelMatrix,modelMatrix,FallInfo()->avatar2collision);
1970 if(!avatarCollisionVolumeIntersectMBBf(modelMatrix,pr.minVals,pr.maxVals) )
return;
1971 delta = planar_polyrep_disp(abottom,atop,astep,awidth,pr,modelMatrix,PR_DOUBLESIDED,delta);
1974 vecscale(&delta,&delta,-1);
1976 accumulate_disp(CollisionInfo(),delta);
1978 #ifdef COLLISIONVERBOSE
1979 if((fabs(delta.x) != 0. || fabs(delta.y) != 0. || fabs(delta.z) != 0.)) {
1980 fprintf(stderr,
"COLLISION_TXT: (%f %f %f) (%f %f %f)\n",
1981 t_orig.x, t_orig.y, t_orig.z,
1982 delta.x, delta.y, delta.z);
1987 void make_Text (
struct X3D_Text *node)
1990 double spacing = 1.0;
1992 int isScreenFontStyle;
1993 unsigned int fsparams = 0;
1995 isScreenFontStyle = FALSE;
1999 if (node->fontStyle) {
2030 unsigned char *lang;
2031 unsigned char *style;
2036 unsigned char *stmp;
2039 POSSIBLE_PROTO_EXPANSION(
struct X3D_FontStyle *, node->fontStyle,fsp);
2042 if (fsp->_nodeType != NODE_FontStyle && fsp->_nodeType != NODE_ScreenFontStyle) {
2043 ConsoleMessage (
"Text node has FontStyle of %s\n",stringNodeType(fsp->_nodeType));
2044 node->fontStyle = NULL;
2049 lang = (
unsigned char *)fsp->language->strptr;
2050 style = (
unsigned char *)fsp->style->strptr;
2052 family = fsp->family;
2053 justify = fsp->justify;
2056 spacing = fsp->spacing;
2058 if(fsp->_nodeType == NODE_ScreenFontStyle){
2062 size = fsps->pointSize;
2063 isScreenFontStyle = TRUE;
2067 fsparams = (fsp->horizontal)|(fsp->leftToRight<<1)|(fsp->topToBottom<<2);
2072 if (strlen((
const char *)style)) {
2073 if (!strcmp((
const char *)style,
"ITALIC")) {fsparams |= 0x10;}
2074 else if(!strcmp((
const char *)style,
"BOLD")) {fsparams |= 0x08;}
2075 else if (!strcmp((
const char *)style,
"BOLDITALIC")) {fsparams |= 0x18;}
2076 else if (strcmp((
const char *)style,
"PLAIN")) {
2077 printf (
"Warning - FontStyle style %s assuming PLAIN\n",style);}
2079 if (strlen((
const char *)lang)) {
2080 printf (
"Warning - FontStyle - language param unparsed\n");
2088 for (tmp = 0; tmp < family.n; tmp++) {
2089 stmp = (
unsigned char *)svptr[tmp]->strptr;
2090 if (strlen((
const char *)stmp) == 0) {fsparams |=0x20; }
2091 else if (!strcmp((
const char *)stmp,
"SERIF")) { fsparams |= 0x20;}
2092 else if(!strcmp((
const char *)stmp,
"SANS")) { fsparams |= 0x40;}
2093 else if (!strcmp((
const char *)stmp,
"TYPEWRITER")) { fsparams |= 0x80;}
2100 if (tx == 0) { fsparams |= 0x2400; }
2101 else if (tx == 1) { fsparams |= 0x2000; }
2103 printf (
"Warning - FontStyle, max 2 elements in Justify\n");
2107 for (tmp = 0; tmp < tx; tmp++) {
2108 stmp = (
unsigned char *)svptr[tmp]->strptr;
2109 if (strlen((
const char *)stmp) == 0) {
2116 else if (!strcmp((
const char *)stmp,
"FIRST")) { fsparams |= (0x200<<(tmp*4));}
2117 else if(!strcmp((
const char *)stmp,
"BEGIN")) { fsparams |= (0x400<<(tmp*4));}
2118 else if (!strcmp((
const char *)stmp,
"MIDDLE")) { fsparams |= (0x800<<(tmp*4));}
2119 else if (!strcmp((
const char *)stmp,
"END")) { fsparams |= (0x1000<<(tmp*4));}
2136 node->_isScreen = isScreenFontStyle;
2138 FW_rendertext(node,((node->string).n),((node->string).p),
2139 ((node->length).n),((node->length).p),
2140 (node->maxExtent),spacing,size,fsparams,rep_);
2191 static int iyup = 0;
2201 typedef enum GUIElementType
2205 GUI_ATLASENTRY = 11,
2206 GUI_ATLASENTRYSET = 12,
2254 unsigned char *texture;
2286 typedef struct vec4 {
float X;
float Y;
float Z;
float W;}
vec4;
2291 GUIElementType type;
2305 static void *GUImalloc(
struct Vector **guitable,
int type);
2313 me->type = GUI_ATLASENTRYSET;
2316 memset(me->ascii,0,128*
sizeof(
int));
2322 Code appears to be unused - JAS April 2017
2324 static void AtlasEntry_init1(
AtlasEntry *me,
char *name,
int index,
int x,
int y,
int width,
int height){
2327 me->type = GUI_ATLASENTRY;
2331 me->size.Y = height;
2336 static void Atlas_init(
Atlas *me,
int size,
int rowheight){
2337 me->type = GUI_ATLAS;
2340 me->pen.X = me->pen.Y = 0;
2341 me->size.X = me->size.Y = size;
2342 me->rowheight = rowheight;
2344 me->bytesperpixel = 1;
2348 me->bytesperpixel = 1;
2353 me->bytesperpixel = 1;
2356 me->texture = (
unsigned char*)MALLOCV(me->size.X *me->size.Y*me->bytesperpixel);
2357 memset(me->texture,127,me->size.X *me->size.Y*me->bytesperpixel);
2370 static void subimage_paste(
unsigned char *image,
ivec2 size,
unsigned char* subimage,
int bpp,
ivec2 ulpos,
ivec2 subsize ){
2372 int imrow, imcol, impos,bpp1;
2375 for(i=0;i<subsize.Y;i++ ){
2376 imrow = ulpos.Y + i;
2378 impos = (imrow * size.X + imcol)*bpp;
2381 ispos = (i*subsize.X + iscol)*bpp1;
2382 if(impos >= 0 && (impos+subsize.X*bpp <= size.X*size.Y*bpp))
2384 if(bpp == 1) memcpy(&image[impos],&subimage[ispos],subsize.X*bpp1);
2389 for(k=0;k<subsize.X;k++){
2392 if(j ==5) image[impos+k+j] = 255;
2393 else image[impos+k+j] = subimage[ispos+k];
2408 for(i=0;i<vectorSize(guitable);i++){
2411 if(!strcmp(name,el->name)){
2420 static void Atlas_addEntry(
Atlas *me,
AtlasEntry *entry,
unsigned char *gray){
2429 if((me->pen.X + entry->size.X) > me->size.X){
2430 me->pen.Y += me->rowheight;
2433 if(me->pen.Y > me->size.Y){
2434 ConsoleMessage(
"Atlas too small, skipping %d\n",entry->ichar);
2439 pos.X = me->pen.X + entry->pos.X;
2440 pos.Y = me->pen.Y + entry->pos.Y;
2442 if(1) subimage_paste(me->texture,me->size,gray,me->bytesperpixel,me->pen,entry->size);
2443 if(0) subimage_paste(me->texture,me->size,gray,1,pos,entry->size);
2446 entry->apos.X = me->pen.X;
2447 entry->apos.Y = me->pen.Y;
2449 entry->apos.X = pos.X;
2450 entry->apos.Y = pos.Y;
2452 me->pen.X += entry->size.X;
2459 Code appears to be unused - JAS April 2017
2463 vector_pushBack(
AtlasEntry*,me->entries,entry);
2464 if(entry->ichar > 0 && entry->ichar < 128){
2466 me->ascii[entry->ichar] = entry;
2467 me->lastascii = max(me->lastascii,me->entries->n);
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);
2482 me->atlas = (
Atlas*)searchGUItable(p->atlas_table,me->atlasName);
2484 Atlas_addEntry(me->atlas, entry, gray);
2489 Code appears to be unused - JAS April 2017
2494 for(i=0;i<vectorSize(me->entries);i++){
2496 if(!strcmp(entry->name,name))
2509 if(ichar > 0 && ichar < 128){
2510 ae = me->ascii[ichar];
2514 for(i=me->lastascii;i<vectorSize(me->entries);i++){
2516 if(entry->ichar == ichar){
2524 ae = AtlasAddIChar(me->font, me, ichar);
2525 for(i=0;i<vectorSize(me->entries);i++){
2527 if(entry->ichar == ichar){
2533 printf(
"tried to add char %d to atlas, but didn't show up\n",ichar);
2543 static void AtlasFont_init(
AtlasFont *me,
char *facename,
int EMsize,
char* path){
2545 me->name = facename;
2546 me->type = GUI_FONT;
2548 me->fontFace = NULL;
2549 me->EMsize = EMsize;
2580 static char *newstringfromchar(
char c){
2581 char *ret = MALLOCV(2);
2590 FT_Face fontFace = font->fontFace;
2597 c = FT_Get_Char_Index(fontFace, ichar);
2598 error = FT_Load_Glyph(fontFace, c, FT_LOAD_RENDER);
2605 glyph = fontFace->glyph;
2609 entry->ichar = ichar;
2610 entry->pos.X = glyph->bitmap_left;
2611 entry->pos.Y = glyph->bitmap_top;
2612 entry->advance.X = glyph->advance.x >> 6;
2613 entry->advance.Y = glyph->advance.y >> 6;
2614 entry->size.X = glyph->bitmap.width;
2615 entry->size.Y = glyph->bitmap.rows;
2617 AtlasEntrySet_addEntry(entryset,entry,glyph->bitmap.buffer);
2628 FT_Face fontFace = font->fontFace;
2630 for (i = 0; i < strlen(cText); i++)
2637 c = FT_Get_Char_Index(fontFace, (
int) cText[i]);
2638 error = FT_Load_Glyph(fontFace, c, FT_LOAD_RENDER);
2645 glyph = fontFace->glyph;
2649 if( cText[i] > 31 && cText[i] < 128 ) entry->ichar = cText[i];
2650 entry->pos.X = glyph->bitmap_left;
2651 entry->pos.Y = glyph->bitmap_top;
2652 entry->advance.X = glyph->advance.x >> 6;
2653 entry->advance.Y = glyph->advance.y >> 6;
2654 entry->size.X = glyph->bitmap.width;
2655 entry->size.Y = glyph->bitmap.rows;
2656 entry->name = newstringfromchar(cText[i]);
2657 AtlasEntrySet_addEntry(entryset,entry,glyph->bitmap.buffer);
2666 static int AtlasFont_LoadFont(
AtlasFont *font){
2668 FT_Library fontlibrary;
2671 char thisfontname[2048];
2677 if(!p->font_directory)
2678 p->font_directory = makeFontDirectory();
2680 strcpy (thisfontname, p->font_directory);
2681 strcat(thisfontname,
"/");
2682 strcat(thisfontname,font->path);
2684 fontlibrary = getFontLibrary();
2688 fontname_entry = get_fontname_entry_by_facename(font->name);
2691 int num = fontname_entry->num;
2692 if(p->font_state[num] < FONTSTATE_TRIED){
2693 FW_make_fontname(num);
2694 fontface = FW_init_face0(fontlibrary,p->thisfontname);
2696 p->font_face[num] = fontface;
2697 p->font_state[num] = FONTSTATE_LOADED;
2698 font->fontFace = fontface;
2700 p->font_state[num] = FONTSTATE_TRIED;
2706 font->fontFace = p->font_face[num];
2710 err = FT_New_Face(fontlibrary, thisfontname, 0, &fontface);
2712 printf (
"FreeType - can not use font %s\n",thisfontname);
2715 font->fontFace = fontface;
2719 printf(
"fontface flags & Scalable? = %ld \n",font->fontFace->face_flags & FT_FACE_FLAG_SCALABLE );
2720 nsizes = font->fontFace->num_fixed_sizes;
2721 printf(
"num_fixed_sizes = %d\n",nsizes);
2727 static int AtlasFont_setFontSize(
AtlasFont *me,
int EMpixels,
int *rowheight,
int *maxadvancepx){
2729 FT_Face fontFace = me->fontFace;
2731 if(!fontFace)
return FALSE;
2742 err = FT_Set_Pixel_Sizes(
2754 *rowheight = fontFace->size->metrics.height >> 6;
2759 *maxadvancepx = fontFace->size->metrics.max_advance >> 6;
2761 printf (
"FreeWRL - FreeType, can not set char size for font %s\n",me->path);
2767 static unsigned int upperPowerOfTwo(
unsigned int k){
2769 unsigned int kk = 1;
2770 for(ipow=2;ipow<32;ipow++){
2772 if(kk > k)
return kk;
2778 static void AtlasFont_RenderFontAtlas(
AtlasFont *me,
int EMpixels,
char* alphabet){
2781 int rowheight, maxadvancepx, pixelsNeeded;
2782 unsigned int dimension;
2785 Atlas *atlas = NULL;
2796 if(!me->fontFace)
return;
2798 atlas = GUImalloc(&p->atlas_table,GUI_ATLAS);
2801 name = MALLOCV(strlen(me->name)+12);
2802 strcpy(name,me->name);
2803 sprintf(&name[strlen(me->name)],
"%d",EMpixels);
2805 AtlasEntrySet_init(me,aes,name);
2807 AtlasFont_setFontSize(me,EMpixels, &rowheight, &maxadvancepx);
2808 pixelsNeeded = rowheight * EMpixels / 2 * strlen(alphabet);
2809 dimension = (
unsigned int)sqrt((
double)pixelsNeeded);
2810 dimension = upperPowerOfTwo(dimension);
2812 Atlas_init(atlas,dimension,rowheight);
2814 aes->EMpixels = EMpixels;
2815 aes->maxadvancepx = maxadvancepx;
2816 aes->rowheight = rowheight;
2818 aes->atlasName = name;
2820 RenderFontAtlas(me,aes,alphabet);
2830 static int bin2hex(
char *inpath,
char *outpath){
2837 fin = fopen(inpath,
"r+b");
2838 fout = fopen(outpath,
"w+");
2841 char *bufname, *bufdup, *ir, *sep;
2845 buf = MALLOCV(ncol + 1);
2847 bufname = bufdup = STRDUP(inpath);
2848 ir = strrchr(bufname,
'\\');
2849 if(ir) bufname = &ir[1];
2850 ir = strrchr(bufname,
'/');
2851 if(ir) bufname = &ir[1];
2852 ir = strrchr(bufname,
'.');
2855 fprintf(fout,
"unsigned char %s_data[] = \n",bufname);
2861 nc = fread(buf,1,nc,fin);
2862 if(nc < ncol) more = 0;
2864 fprintf(fout,
"%s",sep);
2866 fprintf(fout,
"0x%.2x",hh);
2869 if(more) fprintf(fout,
"\n");
2872 fprintf(fout,
"};\n");
2874 fprintf(fout,
"int %s_size = %d;\n",bufname,m);
2884 static int AtlasFont_LoadFromDotC(
AtlasFont *font,
unsigned char *start,
int size){
2886 FT_Library fontlibrary;
2890 fontname = font->path;
2892 if(!size || !start){
2893 printf(
"not compiled in C %s\n", font->name);
2897 fontlibrary = getFontLibrary();
2901 args.flags = FT_OPEN_MEMORY;
2902 args.memory_base = start;
2903 args.memory_size = size;
2904 err = FT_Open_Face(fontlibrary, &args, 0, &fontFace);
2907 printf (
"FreeType - can not use font %s\n",fontname);
2910 font->fontFace = fontFace;
2914 printf(
"fontface flags & Scalable? = %ld \n",fontFace->face_flags & FT_FACE_FLAG_SCALABLE );
2915 nsizes = fontFace->num_fixed_sizes;
2916 printf(
"num_fixed_sizes = %d\n",nsizes);
2923 static AtlasFont *searchAtlasFontTable(
struct Vector* guitable,
char *name,
int EMsize){
2927 for(i=0;i<vectorSize(guitable);i++){
2930 if(!strcmp(name,el->name) && EMsize == el->EMsize){
2942 #ifdef HAVE_COMPILED_IN_FONT
2943 extern unsigned char VeraMono_ttf_data[];
2944 extern int VeraMono_ttf_size;
2945 extern unsigned char freewrl_wingding_ttf_data[];
2946 extern int freewrl_wingding_ttf_size;
2948 unsigned char *VeraMono_ttf_data = NULL;
2949 int VeraMono_ttf_size = 0;
2953 static int FW_Open_Face(FT_Library library,
char *thisfontname,
int faceIndex, FT_Face *face)
2960 if(VeraMono_ttf_size && strstr(thisfontname,
"VeraMono.ttf")){
2963 args.flags = FT_OPEN_MEMORY;
2964 args.memory_base = VeraMono_ttf_data;
2965 args.memory_size = VeraMono_ttf_size;
2966 err = FT_Open_Face(library, &args, 0, face);
2968 err = FT_New_Face(library, thisfontname, faceIndex, face);
2969 if(err && VeraMono_ttf_size)
2973 args.flags = FT_OPEN_MEMORY;
2974 args.memory_base = VeraMono_ttf_data;
2975 args.memory_size = VeraMono_ttf_size;
2976 err = FT_Open_Face(library, &args, faceIndex, face);
2984 AtlasFont *searchAtlasTableOrLoad(
char *facename,
int EMpixels){
2987 font = (
AtlasFont*)searchAtlasFontTable(p->font_table,facename,EMpixels);
2989 static char * ascii32_126 =
" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQURSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
2990 int font_tactic, len;
2993 font = GUImalloc(&p->font_table,GUI_FONT);
2995 len = strlen(facename) + 7;
2996 facenamettf = MALLOCV(len);
2997 strcpy(facenamettf,facename);
2998 facenamettf = strcat(facenamettf,
".ttf");
2999 AtlasFont_init(font,facename,EMpixels,facenamettf);
3001 font_tactic = DOTC_NONE;
3002 if(!strcmp(facename,
"VeraMono")){
3005 if(0) font_tactic = DOTC_SAVE;
3006 else font_tactic = DOTC_LOAD;
3007 if(font_tactic == DOTC_LOAD)
3008 AtlasFont_LoadFromDotC(font, VeraMono_ttf_data, VeraMono_ttf_size);
3010 if(!strcmp(facename,
"freewrl_wingding")){
3013 if(0) font_tactic = DOTC_SAVE;
3014 else font_tactic = DOTC_LOAD;
3015 if(font_tactic == DOTC_LOAD)
3016 AtlasFont_LoadFromDotC(font, freewrl_wingding_ttf_data, freewrl_wingding_ttf_size);
3018 if(font_tactic == DOTC_SAVE) {
3022 facenamettfc = alloca(strlen(facenamettf)+3);
3023 strcpy(facenamettfc,facenamettf);
3024 facenamettfc[len-7] =
'_';
3025 strcat(facenamettfc,
".c");
3026 bin2hex(font->path, facenamettfc);
3028 if(font_tactic != DOTC_LOAD)
3029 AtlasFont_LoadFont(font);
3031 AtlasFont_RenderFontAtlas(font,EMpixels,ascii32_126);
3036 printf(
"dug9gui: Can't find font %s did you misname the fontface sb Vera or VeraMono etc?\n",facename);
3044 vec4 vec4_init(
float x,
float y,
float z,
float w){
3046 ret.X = x, ret.Y = y; ret.Z = z; ret.W = w;
3051 static vec2 vec2_init(
float x,
float y){
3053 ret.X = x, ret.Y = y;
3059 typedef struct ivec4 {
int X;
int Y;
int W;
int H;}
ivec4;
3060 ivec4 ivec4_init(
int x,
int y,
int w,
int h);
3070 static vec2 pixel2normalizedViewportScale( GLfloat x, GLfloat y)
3075 ivec4 currentvp = stack_top(
ivec4,gglobal()->Mainloop._vportstack);
3078 xy.X = ((GLfloat)(x)/(GLfloat)currentvp.W) * 2.0f;
3079 xy.Y = ((GLfloat)(y)/(GLfloat)currentvp.H) * 2.0f;
3083 static vec2 pixel2normalizedViewport( GLfloat x, GLfloat y){
3084 ivec4 currentvp = stack_top(
ivec4,gglobal()->Mainloop._vportstack);
3087 xy.X = ((GLfloat)(x - currentvp.X)/(GLfloat)currentvp.W) * 2.0f;
3088 xy.Y = ((GLfloat)(y - currentvp.Y)/(GLfloat)currentvp.H) * 2.0f;
3095 #ifdef FOR_DEBUGGING
3097 Calls commented out, removing from active compile - JAS April 2017
3098 static void printvpstacktop(
Stack *vpstack,
int line){
3100 int n = ((
struct Vector*)vpstack)->n;
3101 int xx = ((
ivec4*)((
struct Vector*)vpstack)->data)[3].X;
3102 printf(
"vp top[%d] = [%d %d %d %d] line %d xx=%d\n",n,currentvp.X,currentvp.Y,currentvp.W,currentvp.H,line,xx);
3104 #endif //FOR_DEBUGGING
3108 Code appears not to be called - JAS April 2017
3110 static vec2 pixel2normalizedScreenScale( GLfloat x, GLfloat y)
3115 xy.X = ((GLfloat)x/(GLfloat)screen.X) * 2.0f;
3116 xy.Y = ((GLfloat)y/(GLfloat)screen.Y) * 2.0f;
3124 Code appears not to be called - JAS April 2017
3126 static vec2 pixel2normalizedScreen( GLfloat x, GLfloat y){
3127 vec2 xy = pixel2normalizedScreenScale(x,y);
3137 static GLbyte vShaderStr[] =
3138 "attribute vec4 a_position; \n"
3139 "attribute vec2 a_texCoord; \n"
3140 "uniform mat4 u_ModelViewMatrix; \n"
3141 "uniform mat4 u_ProjectionMatrix; \n"
3142 "varying vec2 v_texCoord; \n"
3145 " gl_Position = u_ProjectionMatrix * u_ModelViewMatrix * a_position; \n"
3146 " v_texCoord = a_texCoord; \n"
3163 static GLbyte fShaderStr[] =
3164 #ifdef GL_ES_VERSION_2_0
3165 "precision mediump float; \n"
3166 #endif //GL_ES_VERSION_2_0
3167 "varying vec2 v_texCoord; \n"
3168 "uniform sampler2D Texture0; \n"
3169 "uniform vec4 Color4f; \n"
3170 "uniform vec4 blend; \n"
3173 " vec4 texColor = texture2D( Texture0, v_texCoord ); \n"
3174 " vec4 one = vec4(1.0,1.0,1.0,1.0); \n"
3175 " vec4 omb = vec4(one.rgb - blend.rgb,1.0 - blend.a); \n"
3176 " vec4 tcolor = omb + (blend*texColor);\n"
3177 " float aa = omb.a*Color4f.a + blend.a*(1.0 -texColor.a);\n"
3178 " tcolor = Color4f * tcolor;\n"
3179 " vec4 finalColor = vec4(tcolor.rgb, 1.0 - aa ); \n"
3180 " gl_FragColor = finalColor; \n"
3189 static GLfloat modelviewIdentityf[] = {
3190 1.0f, 0.0f, 0.0f, 0.0f,
3191 0.0f, 1.0f, 0.0f, 0.0f,
3192 0.0f, 0.0f, 1.0f, 0.0f,
3193 0.0f, 0.0f, 0.0f, 1.0f
3195 static GLfloat projectionIdentityf[] = {
3196 1.0f, 0.0f, 0.0f, 0.0f,
3197 0.0f, 1.0f, 0.0f, 0.0f,
3198 0.0f, 0.0f, 1.0f, 0.0f,
3199 0.0f, 0.0f, 0.0f, 1.0f
3202 static void initProgramObject(){
3208 p->programObject = esLoadProgram ( (
const char*) vShaderStr, (
const char *)fShaderStr );
3210 p->positionLoc = glGetAttribLocation ( p->programObject,
"a_position" );
3211 p->texCoordLoc = glGetAttribLocation ( p->programObject,
"a_texCoord" );
3213 p->textureLoc = glGetUniformLocation ( p->programObject,
"Texture0" );
3214 p->color4fLoc = glGetUniformLocation ( p->programObject,
"Color4f" );
3215 p->blendLoc = glGetUniformLocation ( p->programObject,
"blend" );
3216 p->modelviewLoc = glGetUniformLocation ( p->programObject,
"u_ModelViewMatrix" );
3217 p->projectionLoc = glGetUniformLocation ( p->programObject,
"u_ProjectionMatrix" );
3223 JAS - possibly unused - Apr 2017
3225 static void dug9gui_DrawImage(
int xpos,
int ypos,
int width,
int height,
char *buffer){
3232 GLfloat cursorVert[] = {
3241 GLfloat cursorTex[] = {
3249 GLushort ind[] = {0,1,2,3,4,5};
3254 GLfloat cursorVert2[18];
3261 if(0) glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, width, height, 0, GL_LUMINANCE , GL_UNSIGNED_BYTE, buffer);
3264 if(1) glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA , GL_UNSIGNED_BYTE, buffer);
3265 glUniform4f(p->blendLoc,0.0f,0.0f,0.0f,1.0f);
3269 fxy = pixel2normalizedScreen((GLfloat)xpos,(GLfloat)ypos);
3270 fwh = pixel2normalizedScreenScale((GLfloat)width,(GLfloat)height);
3272 fxy.Y = fxy.Y - fwh.Y;
3277 fxy = pixel2normalizedViewport((GLfloat)xpos,(GLfloat)ypos);
3279 fwh = pixel2normalizedViewportScale((GLfloat)width,(GLfloat)height);
3282 fxy.Y = fxy.Y - fwh.Y;
3287 memcpy(cursorVert2,cursorVert,2*3*3*
sizeof(GLfloat));
3291 cursorVert2[i*3 +0] *= fwh.X;
3292 cursorVert2[i*3 +0] += fxy.X;
3293 if(!iyup) cursorVert2[i*3 +1] = 1.0f - cursorVert2[i*3 +1];
3294 cursorVert2[i*3 +1] *= fwh.Y;
3295 cursorVert2[i*3 +1] += fxy.Y;
3301 glActiveTexture ( GL_TEXTURE0 );
3302 glBindTexture ( GL_TEXTURE_2D, p->textureID );
3303 glUniform1i ( p->textureLoc, 0 );
3305 glVertexAttribPointer (p->positionLoc, 3, GL_FLOAT,
3306 GL_FALSE, 0, cursorVert2 );
3308 glVertexAttribPointer (p->texCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, cursorTex );
3309 glEnableVertexAttribArray (p->positionLoc );
3310 glEnableVertexAttribArray (p->texCoordLoc);
3317 glDrawElements ( GL_TRIANGLES, 3*2, GL_UNSIGNED_SHORT, ind );
3327 static void dug9gui_DrawSubImage(
float xpos,
float ypos,
float xsize,
float ysize,
3328 int ix,
int iy,
int iw,
int ih,
int width,
int height,
int bpp,
unsigned char *buffer){
3349 GLfloat cursorVert[] = {
3357 GLfloat cursorTex[] = {
3364 GLushort ind[] = {0,1,2,3,4,5};
3369 GLfloat cursorVert2[18];
3370 GLfloat cursorTex2[12];
3377 glActiveTexture ( GL_TEXTURE0 );
3378 glBindTexture ( GL_TEXTURE_2D, p->textureID );
3379 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3380 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3383 glUniform1i ( p->textureLoc, 0 );
3387 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA , GL_UNSIGNED_BYTE, buffer);
3389 glUniform4f(p->blendLoc,0.0f,0.0f,0.0f,1.0f);
3393 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, width, height, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, buffer);
3396 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA , GL_UNSIGNED_BYTE, buffer);
3397 glUniform4f(p->blendLoc,1.0f,1.0f,1.0f,1.0f);
3405 memcpy(cursorVert2,cursorVert,2*3*3*
sizeof(GLfloat));
3407 cursorVert2[i*3 +0] *= xsize;
3408 cursorVert2[i*3 +0] += xpos;
3409 if(!iyup) cursorVert2[i*3 +1] = 1.0f - cursorVert2[i*3 +1];
3410 cursorVert2[i*3 +1] *= ysize;
3411 cursorVert2[i*3 +1] += ypos;
3414 glVertexAttribPointer (p->positionLoc, 3, GL_FLOAT,
3415 GL_FALSE, 0, cursorVert2 );
3417 fixy.X = (float)ix/(
float)width;
3418 fiwh.X = (float)iw/(
float)width;
3420 fixy.Y = (float)iy/(
float)height;
3421 fiwh.Y = (float)ih/(
float)height;
3423 fixy.Y = (float)(height -iy)/(float)height;
3424 fiwh.Y =-(float)ih/(
float)height;
3426 memcpy(cursorTex2,cursorTex,2*3*2*
sizeof(GLfloat));
3428 cursorTex2[i*2 +0] *= fiwh.X;
3429 cursorTex2[i*2 +0] += fixy.X;
3430 cursorTex2[i*2 +1] *= fiwh.Y;
3431 cursorTex2[i*2 +1] += fixy.Y;
3433 glVertexAttribPointer (p->texCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, cursorTex2 );
3434 glEnableVertexAttribArray (p->positionLoc );
3435 glEnableVertexAttribArray (p->texCoordLoc);
3443 glDrawElements ( GL_TRIANGLES, 3*2, GL_UNSIGNED_SHORT, ind );
3448 int render_captiontext(
AtlasFont *font,
int *utf32,
int len32,
vec4 color){
3454 int i, pen_x, pen_y;
3463 if(len32 == 0)
return FALSE;
3465 if(!font)
return FALSE;
3468 finishedWithGlobalShader();
3469 glDepthMask(GL_FALSE);
3470 glDisable(GL_DEPTH_TEST);
3471 if(!p->programObject) initProgramObject();
3473 glUseProgram ( p->programObject );
3475 glGenTextures(1, &p->textureID);
3477 glBindTexture(GL_TEXTURE_2D, p->textureID);
3478 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
3479 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
3481 glUniformMatrix4fv(p->modelviewLoc, 1, GL_FALSE,modelviewIdentityf);
3482 glUniformMatrix4fv(p->projectionLoc, 1, GL_FALSE, projectionIdentityf);
3484 glUniform4f(p->color4fLoc,color.X,color.Y,color.Z,color.W);
3486 vportstack = (
Stack*)tg->Mainloop._vportstack;
3487 ivport = stack_top(
ivec4,vportstack);
3489 pen_y = ivport.Y + ivport.H - set->EMpixels;
3491 for (i = 0; i < len32; i++)
3498 entry = AtlasEntrySet_getEntry(set,ichar);
3501 float xpos, ypos, xsize, ysize;
3503 xpos = pen_x + entry->pos.X;
3504 ypos = pen_y - entry->pos.Y;
3505 xsize = entry->size.X;
3506 ysize = entry->size.Y;
3508 fxy = pixel2normalizedViewport((GLfloat)xpos,(GLfloat)ypos);
3509 fwh = pixel2normalizedViewportScale((GLfloat)xsize,(GLfloat)ysize);
3511 fxy.Y = fxy.Y - fwh.Y;
3516 dug9gui_DrawSubImage(xpos,ypos,xsize,ysize,
3517 entry->apos.X, entry->apos.Y, entry->size.X, entry->size.Y,
3518 set->atlas->size.X,set->atlas->size.Y,set->atlas->bytesperpixel,set->atlas->texture);
3519 pen_x += entry->advance.X;
3524 glEnable(GL_DEPTH_TEST);
3525 glDepthMask(GL_TRUE);
3526 restoreGlobalShader();
3532 void atlasfont_get_rowheight_charwidth_px(
AtlasFont *font,
int *rowheight,
int *maxadvancepx){
3533 *rowheight = font->set->rowheight;
3534 *maxadvancepx = font->set->maxadvancepx;
3539 int before_textpanel_render_rows(
AtlasFont *font,
vec4 color){
3546 if(font == NULL)
return FALSE;
3547 entryset = font->set;
3548 if(entryset == NULL)
return FALSE;
3549 if(entryset->atlas == NULL)
return FALSE;
3551 atlas = entryset->atlas;
3553 finishedWithGlobalShader();
3554 glDepthMask(GL_FALSE);
3555 glDisable(GL_DEPTH_TEST);
3556 if(!p->programObject) initProgramObject();
3558 glUseProgram ( p->programObject );
3560 glGenTextures(1, &p->textureID);
3563 glActiveTexture ( GL_TEXTURE0 );
3564 glBindTexture ( GL_TEXTURE_2D, p->textureID );
3565 glUniform1i ( p->textureLoc, 0 );
3567 if (atlas->bytesperpixel == 1){
3568 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3569 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3571 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
3572 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3576 if(atlas->bytesperpixel == 1){
3577 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, atlas->size.X, atlas->size.Y, 0, GL_ALPHA , GL_UNSIGNED_BYTE, atlas->texture);
3578 }
else if(atlas->bytesperpixel == 2){
3580 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, atlas->size.X, atlas->size.Y, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, atlas->texture);
3581 }
else if(atlas->bytesperpixel == 4){
3582 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, atlas->size.X, atlas->size.Y, 0, GL_RGBA , GL_UNSIGNED_BYTE, atlas->texture);
3585 glUniform4f(p->color4fLoc,color.X,color.Y,color.Z,color.W);
3586 glUniform4f(p->blendLoc,0.0f,0.0f,0.0f,1.0f);
3588 glUniformMatrix4fv(p->modelviewLoc, 1, GL_FALSE,modelviewIdentityf);
3589 glUniformMatrix4fv(p->projectionLoc, 1, GL_FALSE, projectionIdentityf);
3595 int textpanel_render_row(
AtlasFont *font,
char * cText,
int len,
int *pen_x,
int *pen_y){
3603 if(cText == NULL)
return FALSE;
3604 if(len == 0)
return FALSE;
3605 if(font == NULL)
return FALSE;
3606 entryset = font->set;
3607 if(entryset == NULL)
return FALSE;
3608 if(entryset->atlas == NULL)
return FALSE;
3612 vec2 charScreenSize;
3613 vec2 charScreenOffset;
3614 vec2 charScreenAdvance;
3618 GLfloat x,y,z, xx, yy;
3632 if(p->textpanel_size < max(maxlen,128)){
3633 int newsize = max(maxlen,128);
3634 p->textpanel_size = newsize;
3635 p->textpanel_vert_size = (2+(2*(newsize*2)))*3;
3636 p->textpanel_tex_size = (4*newsize)*2;
3637 p->textpanel_ind_size = (2*3)*(newsize*2);
3639 p->textpanel_vert = REALLOC(p->textpanel_vert,p->textpanel_vert_size*
sizeof(GLfloat));
3641 p->textpanel_tex = REALLOC(p->textpanel_tex,p->textpanel_tex_size*
sizeof(GLfloat));
3643 p->textpanel_ind = REALLOC(p->textpanel_ind,p->textpanel_ind_size*
sizeof(GLushort));
3645 vert = p->textpanel_vert;
3646 tex = p->textpanel_tex;
3647 ind = p->textpanel_ind;
3649 maxlen = min(maxlen,len);
3652 penxy = pixel2normalizedViewport((GLfloat)(*pen_x),(GLfloat)(*pen_y));
3653 penxy.Y = penxy.Y - 2.0f + .05;
3657 atlas = entryset->atlas;
3658 aw = 1.0f/(float)atlas->size.X;
3659 ah = 1.0f/(
float)atlas->size.Y;
3661 for(i=0;i<maxlen;i++)
3663 ichar = (int)cText[i];
3664 if (ichar ==
'\t') ichar =
' ';
3665 ae = AtlasEntrySet_getEntry(entryset,ichar);
3667 ae = AtlasEntrySet_getEntry(entryset,(
int)
' ');
3672 charScreenSize = pixel2normalizedViewportScale(ae->size.X, ae->size.Y);
3673 charScreenAdvance = pixel2normalizedViewportScale(ae->advance.X, ae->advance.Y);
3674 charScreenOffset = pixel2normalizedViewportScale(ae->pos.X,ae->pos.Y);
3676 xx = x + charScreenOffset.X;
3677 yy = y + charScreenOffset.Y;
3680 vert[kk +1] = yy - charScreenSize.Y;
3685 vert[kk +6] = xx + charScreenSize.X;
3688 vert[kk +9] = xx + charScreenSize.X;
3689 vert[kk+10] = yy - charScreenSize.Y;
3691 if(kk+11 >= p->textpanel_vert_size)
3692 printf(
"ouch vert not big enough, need %d have %d\n",kk+11 +1,p->textpanel_vert_size);
3693 x = x + charScreenAdvance.X;
3694 (*pen_x) += ae->advance.X;
3696 tex[kk +0] = ((float)(ae->apos.X))*aw;
3697 tex[kk +2] = ((float)(ae->apos.X))*aw;
3699 tex[kk +4] = ((float)(ae->apos.X + ae->size.X))*aw;
3700 tex[kk +6] = ((float)(ae->apos.X + ae->size.X))*aw;
3703 tex[kk +1] = ((float)(ih - (ae->apos.Y + ae->size.Y)))*ah;
3704 tex[kk +3] = ((float)(ih - ae->apos.Y))*ah;
3706 tex[kk +5] = ((float)(ih - ae->apos.Y))*ah;
3707 tex[kk +7] = ((float)(ih - (ae->apos.Y + ae->size.Y)))*ah;
3709 tex[kk +1] = ((float)((ae->apos.Y + ae->size.Y)))*ah;
3710 tex[kk +3] = ((float)(ae->apos.Y))*ah;
3712 tex[kk +5] = ((float)(ae->apos.Y))*ah;
3713 tex[kk +7] = ((float)((ae->apos.Y + ae->size.Y)))*ah;
3715 if(kk+7 >= p->textpanel_tex_size)
3716 printf(
"ouch tex not big enough, need %d have %d\n",kk+7 +1,p->textpanel_tex_size);
3722 ind[kk +0] = i*4 + 0;
3723 ind[kk +1] = i*4 + 1;
3724 ind[kk +2] = i*4 + 2;
3725 ind[kk +3] = i*4 + 2;
3726 ind[kk +4] = i*4 + 3;
3727 ind[kk +5] = i*4 + 0;
3728 if(kk+5 >= p->textpanel_ind_size)
3729 printf(
"ouch ind not big enough, need %d have %d\n",kk+5 +1,p->textpanel_ind_size);
3734 if(0) glEnableVertexAttribArray (p->positionLoc );
3735 if(0) glEnableVertexAttribArray (p->texCoordLoc );
3737 glVertexAttribPointer (p->positionLoc, 3, GL_FLOAT,
3738 GL_FALSE, 0, vert );
3740 glVertexAttribPointer ( p->texCoordLoc, 2, GL_FLOAT,
3743 glDrawElements ( GL_TRIANGLES, len*3*2, GL_UNSIGNED_SHORT, ind );
3751 void after_textpanel_render_rows(){
3753 glEnable(GL_DEPTH_TEST);
3754 glDepthMask(GL_TRUE);
3755 restoreGlobalShader();
3760 This code may not be used anymore - JAS - Apr 2017
3762 static void render_screentext0(
struct X3D_Text *tnode){
3769 if(tnode && tnode->_nodeType == NODE_Text){
3775 static int once = 0;
3780 finishedWithGlobalShader();
3781 glDepthMask(GL_FALSE);
3782 glDisable(GL_DEPTH_TEST);
3783 if(!p->programObject) initProgramObject();
3785 glUseProgram ( p->programObject );
3787 glGenTextures(1, &p->textureID);
3789 glBindTexture(GL_TEXTURE_2D, p->textureID);
3790 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
3791 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
3792 glUniformMatrix4fv(p->modelviewLoc, 1, GL_FALSE,modelviewIdentityf);
3793 glUniformMatrix4fv(p->projectionLoc, 1, GL_FALSE, projectionIdentityf);
3801 rowvec = sdata->rowvec;
3803 if(!once) printf(
"%s %5s %10s %10s %10s %10s !\n",
"c",
"adv",
"sx",
"sy",
"x",
"y");
3805 for(row=0;row<nrow;row++){
3806 for(i=0;i<rowvec[row].len32;i++){
3809 ichar = rowvec[row].str32[i];
3810 entry = AtlasEntrySet_getEntry(set,ichar);
3814 float xpos, ypos, xsize, ysize;
3819 xpos = (float)chr.x + 90.0f + entry->pos.X;
3820 ypos = (
float)chr.y + 30.0f - entry->pos.Y;
3821 xsize = entry->size.X;
3822 ysize = entry->size.Y;
3825 fxy = pixel2normalizedScreen((GLfloat)xpos,(GLfloat)ypos);
3826 fwh = pixel2normalizedScreenScale((GLfloat)xsize,(GLfloat)ysize);
3828 fxy.Y = fxy.Y - fwh.Y;
3837 fxy = pixel2normalizedViewport((GLfloat)xpos,(GLfloat)ypos);
3838 fwh = pixel2normalizedViewportScale((GLfloat)xsize,(GLfloat)ysize);
3840 fxy.Y = fxy.Y - fwh.Y;
3848 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);
3850 dug9gui_DrawSubImage(xpos,ypos, xsize, ysize,
3851 entry->apos.X, entry->apos.Y, entry->size.X, entry->size.Y,
3852 set->atlas->size.X,set->atlas->size.Y,set->atlas->bytesperpixel,set->atlas->texture);
3857 glEnable(GL_DEPTH_TEST);
3858 glDepthMask(GL_TRUE);
3859 restoreGlobalShader();
3865 static void dug9gui_DrawSubImage_scene(
float xpos,
float ypos,
float xsize,
float ysize,
3866 int ix,
int iy,
int iw,
int ih,
int width,
int height,
int bpp,
unsigned char *buffer){
3887 GLfloat cursorVert[] = {
3895 GLfloat cursorTex[] = {
3902 GLushort ind[] = {0,1,2,3,4,5};
3907 GLfloat cursorVert2[18];
3908 GLfloat cursorTex2[12];
3915 glActiveTexture ( GL_TEXTURE0 );
3916 glBindTexture ( GL_TEXTURE_2D, p->textureID );
3919 glUniform1i ( p->textureLoc, 0 );
3923 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA , GL_UNSIGNED_BYTE, buffer);
3925 glUniform4f(p->blendLoc,0.0f,0.0f,0.0f,1.0f);
3929 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, width, height, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, buffer);
3932 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA , GL_UNSIGNED_BYTE, buffer);
3933 glUniform4f(p->blendLoc,1.0f,1.0f,1.0f,1.0f);
3942 memcpy(cursorVert2,cursorVert,2*3*3*
sizeof(GLfloat));
3944 cursorVert2[i*3 +0] *= xsize;
3945 cursorVert2[i*3 +0] += xpos;
3946 if(!iyup) cursorVert2[i*3 +1] = 1.0f - cursorVert2[i*3 +1];
3947 cursorVert2[i*3 +1] *= ysize;
3948 cursorVert2[i*3 +1] += ypos;
3951 glVertexAttribPointer (p->positionLoc, 3, GL_FLOAT,
3952 GL_FALSE, 0, cursorVert2 );
3954 fixy.X = (float)ix/(
float)width;
3955 fiwh.X = (float)iw/(
float)width;
3957 fixy.Y = (float)iy/(
float)height;
3958 fiwh.Y = (float)ih/(
float)height;
3960 fixy.Y = (float)(height -iy)/(float)height;
3961 fiwh.Y =-(float)ih/(
float)height;
3963 memcpy(cursorTex2,cursorTex,2*3*2*
sizeof(GLfloat));
3965 cursorTex2[i*2 +0] *= fiwh.X;
3966 cursorTex2[i*2 +0] += fixy.X;
3967 cursorTex2[i*2 +1] *= fiwh.Y;
3968 cursorTex2[i*2 +1] += fixy.Y;
3970 glVertexAttribPointer (p->texCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, cursorTex2 );
3971 glEnableVertexAttribArray (p->positionLoc );
3972 glEnableVertexAttribArray (p->texCoordLoc);
3980 glDrawElements ( GL_TRIANGLES, 3*2, GL_UNSIGNED_SHORT, ind );
3986 static void render_screentext_aligned(
struct X3D_Text *tnode,
int screenAligned){
3991 if(tnode && tnode->_nodeType == NODE_Text){
3998 static int once = 0;
3999 GLfloat modelviewf[16], projectionf[16];
4000 GLdouble modelviewd[16], projectiond[16];
4005 finishedWithGlobalShader();
4006 glDepthMask(GL_FALSE);
4007 glDisable(GL_DEPTH_TEST);
4008 if(!p->programObject) initProgramObject();
4010 glUseProgram ( p->programObject );
4012 glGenTextures(1, &p->textureID);
4014 glBindTexture(GL_TEXTURE_2D, p->textureID);
4015 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
4016 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
4022 glUniform4f(p->color4fLoc,.5f,.5f,.5f,1.0f);
4025 dc = myap->fw_FrontMaterial.diffuse;
4026 glUniform4f(p->color4fLoc,dc[0],dc[1],dc[2],dc[3]);
4033 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, modelviewd);
4034 matdouble2float4(modelviewf, modelviewd);
4035 glUniformMatrix4fv(p->modelviewLoc, 1, GL_FALSE,modelviewf);
4036 FW_GL_GETDOUBLEV(GL_PROJECTION_MATRIX, projectiond);
4037 matdouble2float4(projectionf,projectiond);
4038 glUniformMatrix4fv(p->projectionLoc, 1, GL_FALSE, projectionf);
4041 glUniformMatrix4fv(p->modelviewLoc, 1, GL_FALSE,modelviewIdentityf);
4042 glUniformMatrix4fv(p->projectionLoc, 1, GL_FALSE, projectionIdentityf);
4052 rowvec = sdata->rowvec;
4054 if(!once) printf(
"%s %5s %10s %10s %10s %10s\n",
"c",
"adv",
"sx",
"sy",
"x",
"y");
4056 for(row=0;row<nrow;row++){
4057 for(i=0;i<rowvec[row].len32;i++){
4062 ichar = rowvec[row].str32[i];
4064 set_emsize = set->EMpixels;
4065 entry = AtlasEntrySet_getEntry(set,ichar);
4069 float x,y,sx,sy,scale;
4077 rescale = (double)XRES/(
double)PPI;
4082 sx = sdata->size *rescale / (float)(set_emsize + 1) * (float) (entry->size.X + 1) ;
4083 sy = sdata->size *rescale / (float)(set_emsize + 1) * (float) (entry->size.Y + 1) ;
4086 ptresize = 20.0/12.0;
4087 x = ptresize * chr.x * scale *rescale;
4088 y = ptresize * chr.y * scale *rescale + (float)(entry->pos.Y - entry->size.Y)/(float)set_emsize*sdata->size*rescale;
4091 FW_GL_GETINTEGERV(GL_VIEWPORT, viewPort);
4092 x = ((GLfloat)x/(GLfloat)(viewPort[2]-viewPort[0])) * 2.0f -1.0f;
4093 y = ((GLfloat)y/(GLfloat)(viewPort[3]-viewPort[1])) * 2.0f -1.0f;
4094 sx = ((GLfloat)sx/(GLfloat)(viewPort[2]-viewPort[0])) * 2.0f;
4095 sy = ((GLfloat)sy/(GLfloat)(viewPort[3]-viewPort[1])) * 2.0f;
4099 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);
4100 dug9gui_DrawSubImage_scene(x,y, sx, sy,
4101 entry->apos.X, entry->apos.Y, entry->size.X, entry->size.Y,
4102 set->atlas->size.X,set->atlas->size.Y,set->atlas->bytesperpixel,set->atlas->texture);
4109 sx = chr.sx *chr.advance/(float) set_emsize * (
float) entry->size.X;
4110 sy = chr.sy *sdata->size/(float) set_emsize * (
float) entry->size.Y ;
4112 y = chr.y + sdata->size/(float)set_emsize * (
float)(entry->pos.Y - entry->size.Y);
4113 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);
4114 if(1) dug9gui_DrawSubImage_scene(x,y, sx, sy,
4115 entry->apos.X, entry->apos.Y, entry->size.X, entry->size.Y,
4116 set->atlas->size.X,set->atlas->size.Y,set->atlas->bytesperpixel,set->atlas->texture);
4122 glEnable(GL_DEPTH_TEST);
4123 glDepthMask(GL_TRUE);
4124 restoreGlobalShader();
4127 void render_screentext(
struct X3D_Text *tnode){
4130 render_screentext_aligned(tnode,0);
4132 void prep_screentext(
struct X3D_Text *tnode,
int num,
double screensize){
4133 if(tnode && tnode->_nodeType == NODE_Text && !tnode->_screendata){
4139 iscreensize = (int)(screensize + .5);
4140 fontname = facename_from_num(num);
4144 sdata->atlasfont = (
AtlasFont*)searchAtlasTableOrLoad(fontname,iscreensize);
4145 if(!sdata->atlasfont){
4146 printf(
"dug9gui: Can't find font %s do you have the wrong name?\n",fontname);
4157 static void *GUImalloc(
struct Vector **guitable,
int type){
4158 void *retval = NULL;
4163 case GUI_ATLAS: size =
sizeof(
Atlas);
break;
4164 case GUI_FONT: size =
sizeof(
AtlasFont);
break;
4165 case GUI_ATLASENTRY: size =
sizeof(
AtlasEntry);
break;
4166 case GUI_ATLASENTRYSET: size =
sizeof(
AtlasEntrySet);
break;
4168 printf(
"no guielement of this type %d\n",type);
4171 retval = MALLOCV(size);
4174 if(*guitable == NULL) *guitable = newVector(
GUIElement*,20);
4175 vector_pushBack(
GUIElement*,*guitable,retval);
4181 static void GUItablefree(
struct Vector **guitable){
4183 struct Vector *table = (*guitable);
4184 for(i=0;i<table->n;i++){
4192 FREE_IF_NZ(a->texture);
4193 FREE_IF_NZ(a->name);
4202 FREE_IF_NZ(f->path);
4203 for(j=0;j<f->set->entries->n;j++){
4205 FREE_IF_NZ(e->name);
4213 printf(
"mystery type %d\n",itype);