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 GLushort *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();
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){
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) {
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) {
433 p->androidFontFile = myFile;
440void render_Text (
struct X3D_Text * node)
444 render_screentext(node);
446 COMPILE_POLY_IF_REQUIRED (NULL, NULL, NULL, NULL, NULL);
448 CULL_FACE(node->solid)
449 render_polyrep(node);
454static
void FW_NewVertexPoint ()
505 p->FW_rep_->actualCoord[p->FW_pointctr*3+0] = (float) (OUT2GLB(p->last_point.x,p->shrink_x) + p->pen_x);
506 p->FW_rep_->actualCoord[p->FW_pointctr*3+1] = (float) (OUT2GLB(p->last_point.y,p->shrink_y) + p->pen_y);
507 p->FW_rep_->actualCoord[p->FW_pointctr*3+2] = p->TextZdist;
510 if (p->FW_RIA_indx >500) {
511 ConsoleMessage (
"Text, relative index too small\n");
512 freewrlDie(
"FW_NewVertexPoint: this should never happen...");
515 p->FW_RIA[p->FW_RIA_indx]=p->FW_pointctr;
516 v2[0]=p->FW_rep_->actualCoord[p->FW_pointctr*3+0];
517 v2[1]=p->FW_rep_->actualCoord[p->FW_pointctr*3+1];
518 v2[2]=p->FW_rep_->actualCoord[p->FW_pointctr*3+2];
521 FW_GLU_TESS_VERTEX(tg->Tess.text_tessobj,v2,&p->FW_RIA[p->FW_RIA_indx]);
523 if (p->TextVerbose) {
524 printf (
"FW_NewVertexPoint %f %f %f index %d\n",
525 p->FW_rep_->actualCoord[p->FW_pointctr*3+0],
526 p->FW_rep_->actualCoord[p->FW_pointctr*3+1],
527 p->FW_rep_->actualCoord[p->FW_pointctr*3+2],
533 if (p->FW_pointctr >= p->coordmaxsize) {
534 p->coordmaxsize+=800;
535 p->FW_rep_->actualCoord = (
float *)REALLOC(p->FW_rep_->actualCoord,
536 sizeof(*(p->FW_rep_->actualCoord))*p->coordmaxsize*3);
537 printf(
"realloc actualCoord=%p\n",p->FW_rep_->actualCoord);
540#define GLU_UNKNOWN 100124
541static int FW_moveto (FT_Vector* to,
void* user)
549 if (p->contour_started) {
550 FW_GLU_NEXT_CONTOUR(tg->Tess.text_tessobj,GLU_UNKNOWN);
554 p->contour_started = TRUE;
556 p->last_point.x = to->x; p->last_point.y = to->y;
559 printf (
"FW_moveto tox %ld toy %ld\n",to->x, to->y);
566static int FW_lineto (FT_Vector* to,
void* user)
572 if ((p->last_point.x == to->x) && (p->last_point.y == to->y)) {
577 p->last_point.x = to->x;
578 p->last_point.y = to->y;
580 if (p->TextVerbose) {
581 printf (
"FW_lineto, going to %ld %ld\n",to->x, to->y);
591static int FW_conicto (FT_Vector* control, FT_Vector* to,
void* user)
601 printf (
"FW_conicto\n");
604 ncontrol.x = (int) ((
double) 0.25*p->last_point.x + 0.5*control->x + 0.25*to->x);
605 ncontrol.y = (int) ((
double) 0.25*p->last_point.y + 0.5*control->y + 0.25*to->y);
610 FW_lineto (&ncontrol,user);
618static int FW_cubicto (FT_Vector* control1, FT_Vector* control2, FT_Vector* to,
void* user)
623 printf (
"FW_cubicto\n");
625 FW_lineto (control1, user);
626 FW_lineto (control2, user);
627 FW_lineto (to, user);
647} font_name_table [] = {
649 {
"VeraSe",
"serif", NULL, NULL, 0x04,0,0,1},
650 {
"VeraSeBd",
"serif",
"bold", NULL, 0x05,1,0,1},
651 {
"VeraSe",
"serif",
"italic", NULL, 0x06,0,1,1},
652 {
"VeraSeBd",
"serif",
"bold italic",
"bold oblique", 0x07,1,1,1},
653 {
"Vera",
"sans", NULL, NULL, 0x08,0,0,2},
654 {
"VeraBd",
"sans",
"bold", NULL, 0x09,0,1,2},
655 {
"VeraIt",
"sans",
"italic", NULL, 0x0a,1,0,2},
656 {
"VeraBI",
"sans",
"bold italic",
"bold oblique", 0x0b,1,1,2},
657 {
"VeraMono",
"monospace",NULL, NULL, 0x10,0,0,4},
658 {
"VeraMoBd",
"monospace",
"bold", NULL, 0x11,1,0,4},
659 {
"VeraMoIt",
"monospace",
"italic", NULL, 0x12,0,1,4},
660 {
"VeraMoBI",
"monospace",
"bold italic",
"bold oblique", 0x13,1,1,4},
661 {NULL, NULL, NULL, NULL, 0,0,0,0},
663struct name_num *get_fontname_entry_by_num(
int num){
667 while(font_name_table[i].facename){
668 if(font_name_table[i].num == num) {
669 retval = &font_name_table[i];
676struct name_num *get_fontname_entry_by_facename(
char *facename){
680 while(font_name_table[i].facename){
681 if(!strcmp(font_name_table[i].facename,facename)) {
682 retval = &font_name_table[i];
689char *facename_from_num(
int num){
693 val = get_fontname_entry_by_num(num);
694 if(val) retval = val->facename;
699#ifdef HAVE_FONTCONFIG
700void FW_make_fontname(
int num) {
729 FcPattern *FW_fp=NULL;
730 FcChar8 *FW_file=NULL;
734 char* configfile = (
char*)FcConfigFilename(0);
735 FILE*fi = fopen(configfile,
"rb");
744 printf(
"<debug> FontConfig Initialization failed.\n");
746 FcConfig * config = FcConfigGetCurrent();
748 printf(
"<debug> FontConfig Config Initialization failed.\n");
751 FcFontSet *set = FcConfigGetFonts(config, FcSetSystem);
753 if(!set || !set->nfont) {
754 printf(
"<debug> FontConfig has found zero fonts. This is probably a bad thing.\n");
759 FW_fp=FcPatternBuild(NULL,FC_FAMILY,FcTypeString,
"serif",FC_OUTLINE,FcTypeBool,FcTrue,NULL);
762 FW_fp=FcPatternBuild(NULL,FC_FAMILY,FcTypeString,
"serif",FC_OUTLINE,FcTypeBool,FcTrue,NULL);
763 FcPatternAddString(FW_fp,FC_STYLE,(
const FcChar8*)
"bold");
766 FW_fp=FcPatternBuild(NULL,FC_FAMILY,FcTypeString,
"serif",FC_OUTLINE,FcTypeBool,FcTrue,NULL);
767 FcPatternAddString(FW_fp,FC_STYLE,(
const FcChar8*)
"italic");
768 FcPatternAddString(FW_fp,FC_STYLE,(
const FcChar8*)
"oblique");
771 FW_fp=FcPatternBuild(NULL,FC_FAMILY,FcTypeString,
"serif",FC_OUTLINE,FcTypeBool,FcTrue,NULL);
772 FcPatternAddString(FW_fp,FC_STYLE,(
const FcChar8*)
"bold italic");
773 FcPatternAddString(FW_fp,FC_STYLE,(
const FcChar8*)
"bold oblique");
776 FW_fp=FcPatternBuild(NULL,FC_FAMILY,FcTypeString,
"sans",FC_OUTLINE,FcTypeBool,FcTrue,NULL);
779 FW_fp=FcPatternBuild(NULL,FC_FAMILY,FcTypeString,
"sans",FC_OUTLINE,FcTypeBool,FcTrue,NULL);
780 FcPatternAddString(FW_fp,FC_STYLE,(
const FcChar8*)
"bold");
783 FW_fp=FcPatternBuild(NULL,FC_FAMILY,FcTypeString,
"sans",FC_OUTLINE,FcTypeBool,FcTrue,NULL);
784 FcPatternAddString(FW_fp,FC_STYLE,(
const FcChar8*)
"italic");
785 FcPatternAddString(FW_fp,FC_STYLE,(
const FcChar8*)
"oblique");
788 FW_fp=FcPatternBuild(NULL,FC_FAMILY,FcTypeString,
"sans",FC_OUTLINE,FcTypeBool,FcTrue,NULL);
789 FcPatternAddString(FW_fp,FC_STYLE,(
const FcChar8*)
"bold italic");
790 FcPatternAddString(FW_fp,FC_STYLE,(
const FcChar8*)
"bold oblique");
793 FW_fp=FcPatternBuild(NULL,FC_FAMILY,FcTypeString,
"monospace",FC_OUTLINE,FcTypeBool,FcTrue,NULL);
796 FW_fp=FcPatternBuild(NULL,FC_FAMILY,FcTypeString,
"monospace",FC_OUTLINE,FcTypeBool,FcTrue,NULL);
797 FcPatternAddString(FW_fp,FC_STYLE,(
const FcChar8*)
"bold");
800 FW_fp=FcPatternBuild(NULL,FC_FAMILY,FcTypeString,
"monospace",FC_OUTLINE,FcTypeBool,FcTrue,NULL);
801 FcPatternAddString(FW_fp,FC_STYLE,(
const FcChar8*)
"italic");
802 FcPatternAddString(FW_fp,FC_STYLE,(
const FcChar8*)
"oblique");
805 FW_fp=FcPatternBuild(NULL,FC_FAMILY,FcTypeString,
"monospace",FC_OUTLINE,FcTypeBool,FcTrue,NULL);
806 FcPatternAddString(FW_fp,FC_STYLE,(
const FcChar8*)
"bold italic");
807 FcPatternAddString(FW_fp,FC_STYLE,(
const FcChar8*)
"bold oblique");
810 printf (
"dont know how to handle font id %x\n",num);
814 FcConfigSubstitute(0,FW_fp,FcMatchPattern);
815 FcDefaultSubstitute(FW_fp);
816 set = FcFontSort(0, FW_fp, 1, 0, &result);
822 for(t=0;t<set->nfont;t++) {
823 FcPattern *match = set->fonts[t];
824 if (FcPatternGetString(match,FC_FILE,0,&FW_file) != FcResultMatch) {
825 printf(
"<debug> FontConfig: Couldn't get fontconfig's filename for font id %x\n", num);
830 memcpy(p->thisfontname,(
char *)FW_file,strlen((
char *)FW_file));
831 p->thisfontname[strlen((
char *)FW_file)] =
'\0';
836 printf(
"<debug> no set? wha?\n");
838 FcPatternDestroy(FW_fp);
840 if (set) FcFontSetSortDestroy(set);
845void FW_make_fontname(
int num) {
874 if (!p->font_directory) {
875 printf(
"Internal error: no font directory.\n");
879 fontname = facename_from_num(num);
881 printf (
"dont know how to handle font id %x\n",num);
882 p->thisfontname[0] = 0;
884 if(p->font_directory){
885 strcpy (p->thisfontname, p->font_directory);
886 strcat(p->thisfontname,
"/");
888 strcat(p->thisfontname,fontname);
889 strcat(p->thisfontname,
".ttf");
894static FT_Face FW_init_face0(FT_Library library,
char* thisfontname)
907 if ((p->fileLen == 0) || (p->androidFontFile ==NULL)) {
908 ConsoleMessage (
"FW_init_face, fileLen and/or androidFontFile issue");
916 ConsoleMessage (
"TEXT INITIALIZATION - checking on the font file before doing anything");
917 if (0 == fstat(fileno(p->androidFontFile), &buf)) {
918 ConsoleMessage(
"TEXT INITIALIZATION file size is %ld\n", buf.st_size);
919 ConsoleMessage(
"TEXT INITIALIZATION time modified is %s\n", ctime(&buf.st_atime));
927 unsigned char *myFileData = MALLOC(
void *, p->fileLen+1);
929 frv = fread (myFileData, (
size_t)p->fileLen, (
size_t)1, p->androidFontFile);
930 myArgs.flags = FT_OPEN_MEMORY;
931 myArgs.memory_base = myFileData;
932 myArgs.memory_size = p->fileLen;
934 err = FT_Open_Face(library, &
myArgs, 0, &ftface);
937 sprintf (line,
"FreeWRL - FreeType, can not set char size for font %s\n",thisfontname);
938 ConsoleMessage(line);
946 if (0 == fstat(fileno(p->androidFontFile), &buf)) {
947 ConsoleMessage(
"FIN TEXT INITIALIZATION file size is %ld\n", buf.st_size);
948 ConsoleMessage(
"FIN TEXT INITIALIZATION time modified is %s\n", ctime(&buf.st_atime));
953 fclose(p->androidFontFile);
954 p->androidFontFile = NULL;
958 err = FW_Open_Face(library, thisfontname, 0, &ftface);
963 printf (
"FreeType - can not use font %s\n",thisfontname);
969int FW_set_facesize(FT_Face ftface,
char *thisfontname,
double pointsize){
979 pt_dot6 = (int)(pointsize * 64.0 + .5);
980 err = FT_Set_Char_Size(ftface,
987 printf (
"FreeWRL - FreeType, can not set char size for font %s\n",thisfontname);
1001FT_Error FW_Load_Char(
unsigned int idx)
1003 FT_Glyph glyph = NULL;
1004 FT_UInt glyph_index;
1008 if (p->cur_glyph >= MAX_GLYPHS) {
1013 glyph_index = FT_Get_Char_Index(p->font_face[p->myff],idx);
1017 error = FT_Load_Glyph(p->font_face[p->myff], glyph_index, FT_LOAD_DEFAULT) ||
1018 FT_Get_Glyph(p->font_face[p->myff]->glyph, &glyph);
1020 if (!error) { p->glyphs[p->cur_glyph++] = glyph; }
1027static void FW_draw_outline (FT_OutlineGlyph oglyph)
1037 gluTessNormal(tg->Tess.text_tessobj,0.0,0.0,1.0);
1040 cbdata.coords = p->FW_rep_->actualCoord;
1041 cbdata.counter = &p->FW_pointctr;
1042 cbdata.ria = p->FW_RIA;
1043 cbdata.riaindex = &p->FW_RIA_indx;
1047 gluTessBeginPolygon( tg->Tess.text_tessobj, &cbdata );
1048 gluTessBeginContour( tg->Tess.text_tessobj );
1052 retval = FT_Outline_Decompose( &oglyph->outline, &p->FW_outline_interface, &thisptr);
1055 gluTessEndContour( tg->Tess.text_tessobj );
1056 gluTessEndPolygon( tg->Tess.text_tessobj );
1059 if (retval != FT_Err_Ok)
1060 printf(
"FT_Outline_Decompose, error %d\n",retval);
1064static void FW_draw_character (FT_Glyph glyph)
1067 if (glyph->format == ft_glyph_format_outline) {
1068 FW_draw_outline ((FT_OutlineGlyph) glyph);
1069 p->pen_x += (glyph->advance.x >> 10);
1071 printf (
"FW_draw_character; glyphformat -- need outline for %s %s\n",
1072 p->font_face[p->myff]->family_name,p->font_face[p->myff]->style_name);
1074 if (p->TextVerbose) printf (
"done character\n");
1085 printf (
"open_font called\n");
1087 p->FW_outline_interface.move_to = (FT_Outline_MoveTo_Func)FW_moveto;
1088 p->FW_outline_interface.line_to = (FT_Outline_LineTo_Func)FW_lineto;
1089 p->FW_outline_interface.conic_to = (FT_Outline_ConicTo_Func)FW_conicto;
1090 p->FW_outline_interface.cubic_to = (FT_Outline_CubicTo_Func)FW_cubicto;
1091 p->FW_outline_interface.shift = 0;
1092 p->FW_outline_interface.delta = 0;
1096#ifndef HAVE_FONTCONFIG
1098 if(!p->font_directory)
1099 p->font_directory = makeFontDirectory();
1102 if (p->font_directory == NULL) {
1104 ConsoleMessage (
"Have a Text node, but no font library or directory found; continuing with a default builtin font\n");
1111 for (len = 0; len < num_fonts; len++) {
1112 p->font_state[len] = FONTSTATE_NONE;
1115 if ((err = FT_Init_FreeType(&p->library))) {
1116 fprintf(stderr,
"FreeWRL FreeType Initialize error %d\n",err);
1122int open_FTlibrary_if_not_already(){
1128 printf (
"Could not find System Fonts for Text nodes\n");
1133FT_Library getFontLibrary(){
1137 if(open_FTlibrary_if_not_already())
1138 library = p->library;
1163static const unsigned int Replacement = ( 0xfffd );
1164static const unsigned char UTF8TailLengths[256] = {
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 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 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1178 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1179 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
1180 3,3,3,3,3,3,3,3,4,4,4,4,5,5,0,0
1183static unsigned int utf8_to_utf32_char(
unsigned char *s,
unsigned char *end,
unsigned int *inc ) {
1184 unsigned int tail, i, c;
1190 tail = UTF8TailLengths[c];
1191 if( !tail || (s + tail > end))
1195 c &= ( 0x3f >> tail );
1196 for(i=0;i<tail;++i) {
1197 if( (s[i] & 0xc0) != 0x80 )
1199 c = (c << 6) + (s[i] & 0x3f);
1210unsigned int *utf8_to_utf32(
unsigned char *utf8string,
unsigned int *str32,
unsigned int *len32)
1216 unsigned int *to, *to0;
1217 unsigned char *start, *end;
1219 lenchar = (int)strlen((
const char *)utf8string);
1222 end = (
unsigned char *)&utf8string[lenchar];
1224 while ( start < end ) {
1225 while ( ( *start < 0x80 ) && ( start < end ) ) {
1229 if ( start < end ) {
1230 unsigned int inc = 0;
1231 *to++ = utf8_to_utf32_char(start,end,&inc);
1244Seems to be unused - JAS - April 2017
1246static unsigned int utf8_to_utf32_bytes(
unsigned char *s,
unsigned char *end)
1248 unsigned int tail, c;
1255 tail = UTF8TailLengths[c];
1256 tail = s + tail > end ? (
unsigned int)end - (
unsigned int)s : tail;
1264Seems to be unused - JAS - April 2017
1266static unsigned int len_utf8(
unsigned char *utf8string)
1268 unsigned char *start, *end;
1270 lenchar = (int)strlen((
const char *)utf8string);
1272 end = (
unsigned char *)&utf8string[lenchar];
1274 while ( start < end ) {
1275 while ( ( *start < 0x80 ) && ( start < end ) ) {
1279 if ( start < end ) {
1280 start += utf8_to_utf32_bytes(start,end);
1293void prep_screentext(
struct X3D_Text *tnode,
int num,
double screensize);
1303void FW_rendertext(
struct X3D_Text *tnode,
unsigned int numrows,
struct Uni_String **ptr,
1304 unsigned int nl,
float *length,
double maxext,
1305 double spacing,
double mysize,
unsigned int fsparam,
1308 unsigned char *str = NULL;
1309 unsigned int i,row,ii,irow;
1351 p->TextZdist = 0.0f;
1355 if(!open_FTlibrary_if_not_already())
return;
1358 printf (
"entering FW_Render_text \n");
1366 p->myff = (fsparam >> 3) & 0x1F;
1367#if defined (ANDROID)
1377 if (p->font_state[p->myff] < FONTSTATE_TRIED) {
1380 FW_make_fontname(p->myff);
1381 fontface = FW_init_face0(p->library,p->thisfontname);
1383 p->font_face[p->myff] = fontface;
1384 p->font_state[p->myff] = FONTSTATE_LOADED;
1386 p->font_state[p->myff] = FONTSTATE_TRIED;
1389 if(!p->font_face[p->myff])
return;
1391 if(tnode->_isScreen){
1392 p->pointsize = mysize;
1393 p->size = mysize * (double)XRES/(
double)PPI;
1395 p->pointsize = POINTSIZE;
1399 FW_set_facesize(p->font_face[p->myff],p->thisfontname,p->pointsize);
1402 if(tnode->_isScreen){
1405 if(!tnode->_screendata)
1406 prep_screentext(tnode,p->myff, p->pointsize);
1408 rowvec_allocn = sdata->nalloc;
1409 rowvec = sdata->rowvec;
1412 rowvec_allocn = p->rowvec_allocn;
1416 rowvec = (
row32*)MALLOCV(numrows *
sizeof(
row32));
1417 memset(rowvec,0,numrows *
sizeof(
row32));
1419 if(rowvec_allocn < numrows){
1420 rowvec = REALLOC(rowvec,numrows *
sizeof(
row32));
1421 memset(&rowvec[rowvec_allocn],0,(numrows - rowvec_allocn)*
sizeof(
row32));
1422 rowvec_allocn = numrows;
1425 for (row=0; row<numrows; row++) {
1427 str = (
unsigned char *)ptr[row]->strptr;
1428 len = strlen((
const char *)str);
1429 if(rowvec[row].allocn < len){
1430 rowvec[row].str32 = (
unsigned int *)REALLOC(rowvec[row].str32,(len+1) *
sizeof(
unsigned int));
1431 rowvec[row].chr = (
chardata *) REALLOC(rowvec[row].chr,len*
sizeof(
chardata));
1432 rowvec[row].allocn = len;
1433 rowvec[row].len32 = 0;
1436 if(tnode->_isScreen){
1439 sdata->rowvec = rowvec;
1440 sdata->nalloc = rowvec_allocn;
1441 sdata->nrow = numrows;
1442 sdata->faceheight = (float)p->font_face[p->myff]->height;
1443 sdata->size = p->size;
1444 sdata->emsize = mysize;
1447 p->rowvec_allocn = rowvec_allocn;
1451 for (row=0; row<numrows; row++) {
1452 unsigned int len32, *str32;
1453 double total_row_advance, widest_char;
1454 str = (
unsigned char *)ptr[row]->strptr;
1459 str32 = rowvec[row].str32;
1460 utf8_to_utf32(str,str32,&len32);
1461 rowvec[row].iglyphstartindex = p->cur_glyph;
1462 rowvec[row].len32 = len32;
1463 rowvec[row].str32 = str32;
1464 total_row_advance = 0;
1466 for(i=0;i<len32;i++){
1468 FW_Load_Char(str32[i]);
1469 icount = p->cur_glyph -1;
1470 rowvec[row].chr[i].iglyph = icount;
1472 rowvec[row].chr[i].advance = OUT2GLB(p->glyphs[icount]->advance.x >> 10,1.0);
1473 total_row_advance += rowvec[row].chr[i].advance;
1474 widest_char = rowvec[row].chr[i].advance > widest_char ? rowvec[row].chr[i].advance : widest_char;
1477 rowvec[row].hrowsize = total_row_advance;
1478 rowvec[row].vcolsize = len32 * p->size;
1479 rowvec[row].widestchar = widest_char;
1480 char_count += len32;
1484 if (p->TextVerbose) {
1485 printf (
"Text: rows %d char_count %d\n",numrows,char_count);
1497 for(row = 0; row < numrows; row++) {
1499 hrowsize = rowvec[row].hrowsize;
1500 maxlen = hrowsize > maxlen ? hrowsize : maxlen;
1503 shrink = maxext / maxlen;
1515 if(fsparam & (0x400<<(4))){
1519 if(fsparam & (0x200<<(4))){
1523 if (fsparam & (0x800<<(4))) {
1524 p->pen_y = (double)(numrows)/2.0;
1527 if (fsparam & (0x1000<<(4))) {
1529 p->pen_y = (double)numrows;
1537 if(fsparam & (0x200<<(4)))
1539 p->pen_y = numrows - 1.0 - p->pen_y;
1543 for(irow = 0; irow < numrows; irow++) {
1544 unsigned int lenchars;
1548 if(!TOPTOBOTTOM) row = numrows - irow -1;
1550 str = (
unsigned char *)ptr[row]->strptr;
1552 printf (
"text2 row %d :%s:\n",row, str);
1555 rowlen = rowvec[row].hrowsize;
1556 lenchars = rowvec[row].len32;
1558 if((row < nl) && !(APPROX(length[row],0.0))) {
1559 rshrink = length[row] / rowlen;
1563 if (((fsparam & 0x200) || (fsparam & 0x400)) && !LEFTTORIGHT ) {
1569 if (fsparam & 0x800) {
1570 p->pen_x = -rowlen/2.0;
1575 if ((fsparam & 0x1000) && LEFTTORIGHT ) {
1580 for(ii=0; ii<lenchars; ii++) {
1584 i = lenchars - ii -1;
1585 rowvec[row].chr[i].x = p->pen_x;
1586 rowvec[row].chr[i].y = p->pen_y;
1587 rowvec[row].chr[i].sx = shrink*rshrink;
1588 rowvec[row].chr[i].sy = 1.0;
1589 p->pen_x += rowvec[row].chr[i].advance * shrink*rshrink;
1591 p->pen_y += -spacing * p->size;
1597 double widest_column, column_spacing;
1599 double maxlen = 0.0;
1601 for(row = 0; row < numrows; row++) {
1602 double vcolsize = rowvec[row].vcolsize;
1603 maxlen = vcolsize > maxlen ? vcolsize : maxlen;
1606 if(maxlen > maxext) shrink = maxext / maxlen;
1608 widest_column = 0.0;
1609 for(row=0;row<numrows;row++)
1610 widest_column = rowvec[row].widestchar > widest_column ? rowvec[row].widestchar : widest_column;
1613 column_spacing = spacing * p->size;
1623 if(fsparam & (0x200<<(4)) || fsparam & (0x400<<(4))){
1628 p->pen_x = -(double)numrows * column_spacing;
1632 if (fsparam & (0x800<<(4))) {
1633 p->pen_x = -(double)(numrows)/2.0 *column_spacing;
1636 if (fsparam & (0x1000<<(4))) {
1639 p->pen_x = -(double)numrows * column_spacing;
1645 for(irow = 0; irow < numrows; irow++) {
1646 unsigned int lenchars;
1651 if(!LEFTTORIGHT) row = numrows - irow -1;
1653 str = (
unsigned char *)ptr[row]->strptr;
1655 printf (
"text2 row %d :%s:\n",row, str);
1658 rowlen = rowvec[row].vcolsize;
1659 lenchars = rowvec[row].len32;
1661 if((row < nl) && !(APPROX(length[row],0.0))) {
1662 rshrink = length[row] / rowlen;
1665 starty = -1.0*shrink*rshrink*p->size;
1667 if ((fsparam & 0x200) || (fsparam & 0x400)){
1671 p->pen_y = rowlen + starty;
1675 if (fsparam & 0x800) {
1676 p->pen_y = rowlen/2.0 + starty;
1680 if (fsparam & 0x1000 ) {
1682 p->pen_y = rowlen + starty;
1687 for(ii=0; ii<lenchars; ii++) {
1694 i = lenchars - ii -1;
1697 penx = penx + column_spacing - rowvec[row].chr[i].advance;
1699 rowvec[row].chr[i].x = penx;
1700 rowvec[row].chr[i].y = p->pen_y;
1701 rowvec[row].chr[i].sx = 1.0;
1702 rowvec[row].chr[i].sy = shrink*rshrink;
1703 p->pen_y += -p->size * shrink * rshrink;
1706 p->pen_x += column_spacing;
1710 if(!tnode->_isScreen){
1719 p->contour_started = FALSE;
1722 est_tri = char_count*800;
1723 p->coordmaxsize=est_tri;
1724 p->cindexmaxsize=est_tri;
1725 p->FW_rep_->cindex=MALLOC(GLuint *,
sizeof(*(p->FW_rep_->cindex))*est_tri);
1726 p->FW_rep_->actualCoord = MALLOC(
float *,
sizeof(*(p->FW_rep_->actualCoord))*est_tri*3);
1727 for(row = 0; row < numrows; row++) {
1728 unsigned int lenchars = rowvec[row].len32;
1729 for(i=0; i<lenchars; i++) {
1733 chr = rowvec[row].chr[i];
1736 p->shrink_x = chr.sx;
1737 p->shrink_y = chr.sy;
1740 tg->Tess.text_IFS_Coord_count = 0;
1743 kk = rowvec[row].chr[i].iglyph;
1744 FW_draw_character (p->glyphs[kk]);
1745 FT_Done_Glyph (p->glyphs[kk]);
1749 for (x=0; x<tg->Tess.text_IFS_Coord_count; x++) {
1754 if ((tg->Tess.text_IFS_Coords[x] >= p->cindexmaxsize) ||
1755 (p->indx_count >= p->cindexmaxsize) ||
1756 (tg->Tess.text_IFS_Coords[x] < 0)) {
1758 printf (
"Tesselated index %d out of range; skipping indx_count, %d cindexmaxsize %d global_IFS_Coord_count %d\n",
1759 tg->Tess.text_IFS_Coords[x],p->indx_count,p->cindexmaxsize,tg->Tess.text_IFS_Coord_count);
1763 p->FW_rep_->cindex[p->indx_count] = p->FW_rep_->cindex[p->indx_count-1];
1764 if (p->indx_count < (p->cindexmaxsize-1)) p->indx_count ++;
1770 p->FW_rep_->cindex[p->indx_count++] = tg->Tess.text_IFS_Coords[x];
1774 if (p->indx_count > (p->cindexmaxsize-400)) {
1775 p->cindexmaxsize += 800;
1776 p->FW_rep_->cindex=(GLuint *)REALLOC(p->FW_rep_->cindex,
sizeof(*(p->FW_rep_->cindex))*p->cindexmaxsize);
1782 static int _once = 0;
1784 ntris = tg->Tess.text_IFS_Coord_count / 3;
1787 FILE *fptris = fopen(
"test_glyph_triangles.wrl",
"w+");
1788 fprintf(fptris,
"%s\n",
"#VRML V2.0 utf8");
1789 fprintf(fptris,
"Transform {\n children [\n Shape {\n appearance Appearance { material Material { diffuseColor .6 .6 .6 }}\n");
1790 fprintf(fptris,
" geometry IndexedFaceSet { solid FALSE \n");
1791 fprintf(fptris,
" coordIndex ");
1793 fprintf(fptris,
"[");
1794 for(ii=0;ii<ntris;ii++){
1795 for(jj=0;jj<3;jj++){
1796 fprintf(fptris,
" %d",p->FW_rep_->cindex[ii*3+jj]);
1798 fprintf(fptris,
" -1");
1800 fprintf(fptris,
"]\n");
1802 fprintf(fptris,
"coord Coordinate { \n");
1803 fprintf(fptris,
" point [");
1810 for(ii=0;ii<p->FW_RIA_indx;ii++){
1811 for(jj=0;jj<3;jj++){
1812 fprintf(fptris,
" %f",p->FW_rep_->actualCoord[ii*3 + jj]);
1814 fprintf(fptris,
",");
1817 fprintf(fptris,
" ] }}}\n");
1818 fprintf(fptris,
" ]}");
1821 fptris = fopen(
"test_glyph_polygon.wrl",
"w+");
1822 fprintf(fptris,
"%s\n",
"#VRML V2.0 utf8");
1823 fprintf(fptris,
"Transform {\n children [\n Shape {\n appearance Appearance { material Material { diffuseColor .5 .5 .5 }}\n");
1824 fprintf(fptris,
" geometry IndexedFaceSet { solid FALSE convex FALSE \n");
1825 fprintf(fptris,
" coordIndex ");
1827 fprintf(fptris,
"[");
1828 for(ii=0;ii<p->FW_RIA_indx;ii++){
1829 fprintf(fptris,
" %d",ii);
1831 fprintf(fptris,
" -1");
1832 fprintf(fptris,
"]\n");
1834 fprintf(fptris,
"coord Coordinate { \n");
1835 fprintf(fptris,
" point [");
1842 for(ii=0;ii<p->FW_RIA_indx;ii++){
1843 for(jj=0;jj<3;jj++){
1844 fprintf(fptris,
" %f",p->FW_rep_->actualCoord[ii*3 + jj]);
1846 fprintf(fptris,
",");
1849 fprintf(fptris,
" ] }}}\n");
1850 fprintf(fptris,
" ]}");
1855 fprintf(fptris,
"%s\n",
"#VRML V2.0 utf8");
1856 fprintf(fptris,
"Transform {\n translation 0 0 .1 children [\n Shape {\n appearance Appearance { material Material { emissiveColor .1 .8 .2 }}\n");
1857 fprintf(fptris,
" geometry Polyline2D { \n");
1858 fprintf(fptris,
" lineSegments [");
1865 for(ii=0;ii<p->FW_RIA_indx;ii++){
1866 for(jj=0;jj<2;jj++){
1867 fprintf(fptris,
" %f",p->FW_rep_->actualCoord[ii*3 + jj]);
1869 fprintf(fptris,
",");
1872 fprintf(fptris,
" ] }}\n");
1873 fprintf(fptris,
" ]}");
1884 p->FW_rep_->ntri=p->indx_count/3;
1886 p->FW_rep_->ccw=FALSE;
1889 if (p->indx_count !=0) {
1896 p->FW_rep_->normal = MALLOC(
float *,
sizeof(*(p->FW_rep_->normal))*p->indx_count*3);
1897 for (i = 0; i<(
unsigned int)p->indx_count; i++) {
1898 p->FW_rep_->normal[i*3+0] = 0.0f;
1899 p->FW_rep_->normal[i*3+1] = 0.0f;
1900 p->FW_rep_->normal[i*3+2] = 1.0f;
1904 if (HAVETODOTEXTURES) {
1905 p->FW_rep_->GeneratedTexCoords[0] = MALLOC(
float *,
sizeof(*(p->FW_rep_->GeneratedTexCoords[0]))*(p->FW_pointctr+1)*3);
1908 for (i=0; i<(
unsigned int)p->FW_pointctr; i++) {
1909 p->FW_rep_->GeneratedTexCoords[0][i*3+0] = p->FW_rep_->actualCoord[i*3+0]*1.66f;
1910 p->FW_rep_->GeneratedTexCoords[0][i*3+1] = 0.0f;
1911 p->FW_rep_->GeneratedTexCoords[0][i*3+2] = p->FW_rep_->actualCoord[i*3+1]*1.66f;
1917 if (p->TextVerbose) printf (
"exiting FW_Render_text\n");
1920int avatarCollisionVolumeIntersectMBBf(
double *modelMatrix,
float *minVals,
float *maxVals);
1922void collide_Text (
struct X3D_Text *node)
1925 GLDOUBLE awidth,atop,abottom,astep,modelMatrix[16];
1932 if(node->_isScreen > 0)
return;
1934 naviinfo = (
struct sNaviInfo*)tg->Bindable.naviinfo;
1936 awidth = naviinfo->width;
1937 atop = naviinfo->width;
1938 abottom = -naviinfo->height;
1939 astep = -naviinfo->height+naviinfo->step;
1948 if (node->_intern == NULL)
return;
1951 if (node->_intern->ntri == 0)
return;
1955 change = node->_intern->irep_change;
1957 COMPILE_POLY_IF_REQUIRED(NULL, NULL, NULL, NULL, NULL);
1960 node->_intern->irep_change = change;
1965 pr = *(node->_intern);
1973 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, modelMatrix);
1975 matmultiplyAFFINE(modelMatrix,modelMatrix,FallInfo()->avatar2collision);
1978 if(!avatarCollisionVolumeIntersectMBBf(modelMatrix,pr.minVals,pr.maxVals) )
return;
1979 delta = planar_polyrep_disp(abottom,atop,astep,awidth,pr,modelMatrix,PR_DOUBLESIDED,delta);
1982 vecscale(&delta,&delta,-1);
1984 accumulate_disp(CollisionInfo(),delta);
1986#ifdef COLLISIONVERBOSE
1987 if((fabs(delta.x) != 0. || fabs(delta.y) != 0. || fabs(delta.z) != 0.)) {
1988 fprintf(stderr,
"COLLISION_TXT: (%f %f %f) (%f %f %f)\n",
1989 t_orig.x, t_orig.y, t_orig.z,
1990 delta.x, delta.y, delta.z);
1995void make_Text (
struct X3D_Text *node)
1998 double spacing = 1.0;
2000 int isScreenFontStyle;
2001 unsigned int fsparams = 0;
2003 isScreenFontStyle = FALSE;
2007 if (node->fontStyle) {
2038 unsigned char *lang;
2039 unsigned char *style;
2044 unsigned char *stmp;
2047 POSSIBLE_PROTO_EXPANSION(
struct X3D_FontStyle *, node->fontStyle,fsp);
2050 if (fsp->_nodeType != NODE_FontStyle && fsp->_nodeType != NODE_ScreenFontStyle) {
2051 ConsoleMessage (
"Text node has FontStyle of %s\n",stringNodeType(fsp->_nodeType));
2052 node->fontStyle = NULL;
2057 lang = (
unsigned char *)fsp->language->strptr;
2058 style = (
unsigned char *)fsp->style->strptr;
2060 family = fsp->family;
2061 justify = fsp->justify;
2064 spacing = fsp->spacing;
2066 if(fsp->_nodeType == NODE_ScreenFontStyle){
2070 size = fsps->pointSize;
2071 isScreenFontStyle = TRUE;
2075 fsparams = (fsp->horizontal)|(fsp->leftToRight<<1)|(fsp->topToBottom<<2);
2080 if (strlen((
const char *)style)) {
2081 if (!strcmp((
const char *)style,
"ITALIC")) {fsparams |= 0x10;}
2082 else if(!strcmp((
const char *)style,
"BOLD")) {fsparams |= 0x08;}
2083 else if (!strcmp((
const char *)style,
"BOLDITALIC")) {fsparams |= 0x18;}
2084 else if (strcmp((
const char *)style,
"PLAIN")) {
2085 printf (
"Warning - FontStyle style %s assuming PLAIN\n",style);}
2087 if (strlen((
const char *)lang)) {
2088 printf (
"Warning - FontStyle - language param unparsed\n");
2096 for (tmp = 0; tmp < family.n; tmp++) {
2097 stmp = (
unsigned char *)svptr[tmp]->strptr;
2098 if (strlen((
const char *)stmp) == 0) {fsparams |=0x20; }
2099 else if (!strcmp((
const char *)stmp,
"SERIF")) { fsparams |= 0x20;}
2100 else if(!strcmp((
const char *)stmp,
"SANS")) { fsparams |= 0x40;}
2101 else if (!strcmp((
const char *)stmp,
"TYPEWRITER")) { fsparams |= 0x80;}
2108 if (tx == 0) { fsparams |= 0x2400; }
2109 else if (tx == 1) { fsparams |= 0x2000; }
2111 printf (
"Warning - FontStyle, max 2 elements in Justify\n");
2115 for (tmp = 0; tmp < tx; tmp++) {
2116 stmp = (
unsigned char *)svptr[tmp]->strptr;
2117 if (strlen((
const char *)stmp) == 0) {
2124 else if (!strcmp((
const char *)stmp,
"FIRST")) { fsparams |= (0x200<<(tmp*4));}
2125 else if(!strcmp((
const char *)stmp,
"BEGIN")) { fsparams |= (0x400<<(tmp*4));}
2126 else if (!strcmp((
const char *)stmp,
"MIDDLE")) { fsparams |= (0x800<<(tmp*4));}
2127 else if (!strcmp((
const char *)stmp,
"END")) { fsparams |= (0x1000<<(tmp*4));}
2144 node->_isScreen = isScreenFontStyle;
2146 FW_rendertext(node,((node->string).n),((node->string).p),
2147 ((node->length).n),((node->length).p),
2148 (node->maxExtent),spacing,size,fsparams,rep_);
2214typedef enum GUIElementType
2218 GUI_ATLASENTRY = 11,
2219 GUI_ATLASENTRYSET = 12,
2267 unsigned char *texture;
2299typedef struct vec4 {
float X;
float Y;
float Z;
float W;}
vec4;
2304 GUIElementType type;
2318static void *GUImalloc(
struct Vector **guitable,
int type);
2323static void AtlasEntrySet_init(AtlasFont *font,
AtlasEntrySet *me,
char *name){
2326 me->type = GUI_ATLASENTRYSET;
2329 memset(me->ascii,0,128*
sizeof(
int));
2335Code appears to be unused - JAS April 2017
2337static void AtlasEntry_init1(
AtlasEntry *me,
char *name,
int index,
int x,
int y,
int width,
int height){
2340 me->type = GUI_ATLASENTRY;
2344 me->size.Y = height;
2349static void Atlas_init(
Atlas *me,
int size,
int rowheight){
2350 me->type = GUI_ATLAS;
2353 me->pen.X = me->pen.Y = 0;
2354 me->size.X = me->size.Y = size;
2355 me->rowheight = rowheight;
2357 me->bytesperpixel = 1;
2361 me->bytesperpixel = 1;
2366 me->bytesperpixel = 1;
2369 me->texture = (
unsigned char*)MALLOCV(me->size.X *me->size.Y*me->bytesperpixel);
2370 memset(me->texture,127,me->size.X *me->size.Y*me->bytesperpixel);
2383static void subimage_paste(
unsigned char *image,
ivec2 size,
unsigned char* subimage,
int bpp,
ivec2 ulpos,
ivec2 subsize ){
2385 int imrow, imcol, impos,bpp1;
2388 for(i=0;i<subsize.Y;i++ ){
2389 imrow = ulpos.Y + i;
2391 impos = (imrow * size.X + imcol)*bpp;
2394 ispos = (i*subsize.X + iscol)*bpp1;
2395 if(impos >= 0 && (impos+subsize.X*bpp <= size.X*size.Y*bpp))
2397 if(bpp == 1) memcpy(&image[impos],&subimage[ispos],subsize.X*bpp1);
2402 for(k=0;k<subsize.X;k++){
2405 if(j ==5) image[impos+k+j] = 255;
2406 else image[impos+k+j] = subimage[ispos+k];
2421 for(i=0;i<vectorSize(guitable);i++){
2424 if(!strcmp(name,el->name)){
2433static void Atlas_addEntry(
Atlas *me,
AtlasEntry *entry,
unsigned char *gray){
2442 if((me->pen.X + entry->size.X) > me->size.X){
2443 me->pen.Y += me->rowheight;
2446 if(me->pen.Y > me->size.Y){
2447 ConsoleMessage(
"Atlas too small, skipping %d\n",entry->ichar);
2452 pos.X = me->pen.X + entry->pos.X;
2453 pos.Y = me->pen.Y + entry->pos.Y;
2455 if(1) subimage_paste(me->texture,me->size,gray,me->bytesperpixel,me->pen,entry->size);
2456 if(0) subimage_paste(me->texture,me->size,gray,1,pos,entry->size);
2459 entry->apos.X = me->pen.X;
2460 entry->apos.Y = me->pen.Y;
2462 entry->apos.X = pos.X;
2463 entry->apos.Y = pos.Y;
2465 me->pen.X += entry->size.X;
2472Code appears to be unused - JAS April 2017
2476 vector_pushBack(
AtlasEntry*,me->entries,entry);
2477 if(entry->ichar > 0 && entry->ichar < 128){
2479 me->ascii[entry->ichar] = entry;
2480 me->lastascii = max(me->lastascii,me->entries->n);
2488 vector_pushBack(
AtlasEntry*,me->entries,entry);
2489 if(entry->ichar > 0 && entry->ichar < 128){
2491 me->ascii[entry->ichar] = entry;
2492 me->lastascii = max(me->lastascii,me->entries->n);
2495 me->atlas = (
Atlas*)searchGUItable(p->atlas_table,me->atlasName);
2497 Atlas_addEntry(me->atlas, entry, gray);
2502Code appears to be unused - JAS April 2017
2507 for(i=0;i<vectorSize(me->entries);i++){
2509 if(!strcmp(entry->name,name))
2522 if(ichar > 0 && ichar < 128){
2523 ae = me->ascii[ichar];
2527 for(i=me->lastascii;i<vectorSize(me->entries);i++){
2529 if(entry->ichar == ichar){
2537 ae = AtlasAddIChar(me->font, me, ichar);
2538 for(i=0;i<vectorSize(me->entries);i++){
2540 if(entry->ichar == ichar){
2546 printf(
"tried to add char %d to atlas, but didn't show up\n",ichar);
2556static void AtlasFont_init(AtlasFont *me,
char *facename,
int EMsize,
char* path){
2558 me->name = facename;
2559 me->type = GUI_FONT;
2561 me->fontFace = NULL;
2562 me->EMsize = EMsize;
2593static char *newstringfromchar(
char c){
2594 char *ret = MALLOCV(2);
2603 FT_Face fontFace = font->fontFace;
2610 c = FT_Get_Char_Index(fontFace, ichar);
2611 error = FT_Load_Glyph(fontFace, c, FT_LOAD_RENDER);
2618 glyph = fontFace->glyph;
2622 entry->ichar = ichar;
2623 entry->pos.X = glyph->bitmap_left;
2624 entry->pos.Y = glyph->bitmap_top;
2625 entry->advance.X = glyph->advance.x >> 6;
2626 entry->advance.Y = glyph->advance.y >> 6;
2627 entry->size.X = glyph->bitmap.width;
2628 entry->size.Y = glyph->bitmap.rows;
2630 AtlasEntrySet_addEntry(entryset,entry,glyph->bitmap.buffer);
2635static int RenderFontAtlas(AtlasFont *font,
AtlasEntrySet *entryset,
char * cText){
2641 FT_Face fontFace = font->fontFace;
2643 for (i = 0; i < strlen(cText); i++)
2650 c = FT_Get_Char_Index(fontFace, (
int) cText[i]);
2651 error = FT_Load_Glyph(fontFace, c, FT_LOAD_RENDER);
2658 glyph = fontFace->glyph;
2662 if( cText[i] > 31 && cText[i] < 128 ) entry->ichar = cText[i];
2663 entry->pos.X = glyph->bitmap_left;
2664 entry->pos.Y = glyph->bitmap_top;
2665 entry->advance.X = glyph->advance.x >> 6;
2666 entry->advance.Y = glyph->advance.y >> 6;
2667 entry->size.X = glyph->bitmap.width;
2668 entry->size.Y = glyph->bitmap.rows;
2669 entry->name = newstringfromchar(cText[i]);
2670 AtlasEntrySet_addEntry(entryset,entry,glyph->bitmap.buffer);
2679static int AtlasFont_LoadFont(AtlasFont *font){
2681 FT_Library fontlibrary;
2684 char thisfontname[2048];
2690 if(!p->font_directory)
2691 p->font_directory = makeFontDirectory();
2693 strcpy (thisfontname, p->font_directory);
2694 strcat(thisfontname,
"/");
2695 strcat(thisfontname,font->path);
2697 fontlibrary = getFontLibrary();
2701 fontname_entry = get_fontname_entry_by_facename(font->name);
2704 int num = fontname_entry->num;
2705 if(p->font_state[num] < FONTSTATE_TRIED){
2706 FW_make_fontname(num);
2707 fontface = FW_init_face0(fontlibrary,p->thisfontname);
2709 p->font_face[num] = fontface;
2710 p->font_state[num] = FONTSTATE_LOADED;
2711 font->fontFace = fontface;
2713 p->font_state[num] = FONTSTATE_TRIED;
2719 font->fontFace = p->font_face[num];
2723 err = FT_New_Face(fontlibrary, thisfontname, 0, &fontface);
2725 printf (
"FreeType - can not use font %s\n",thisfontname);
2728 font->fontFace = fontface;
2732 printf(
"fontface flags & Scalable? = %ld \n",font->fontFace->face_flags & FT_FACE_FLAG_SCALABLE );
2733 nsizes = font->fontFace->num_fixed_sizes;
2734 printf(
"num_fixed_sizes = %d\n",nsizes);
2740static int AtlasFont_setFontSize(AtlasFont *me,
int EMpixels,
int *rowheight,
int *maxadvancepx){
2742 FT_Face fontFace = me->fontFace;
2744 if(!fontFace)
return FALSE;
2755 err = FT_Set_Pixel_Sizes(
2767 *rowheight = fontFace->size->metrics.height >> 6;
2772 *maxadvancepx = fontFace->size->metrics.max_advance >> 6;
2774 printf (
"FreeWRL - FreeType, can not set char size for font %s\n",me->path);
2780static unsigned int upperPowerOfTwo(
unsigned int k){
2782 unsigned int kk = 1;
2783 for(ipow=2;ipow<32;ipow++){
2785 if(kk > k)
return kk;
2791static void AtlasFont_RenderFontAtlas(AtlasFont *me,
int EMpixels,
char* alphabet){
2794 int rowheight, maxadvancepx, pixelsNeeded;
2795 unsigned int dimension;
2798 Atlas *atlas = NULL;
2809 if(!me->fontFace)
return;
2811 atlas = GUImalloc(&p->atlas_table,GUI_ATLAS);
2814 name = MALLOCV(strlen(me->name)+12);
2815 strcpy(name,me->name);
2816 sprintf(&name[strlen(me->name)],
"%d",EMpixels);
2818 AtlasEntrySet_init(me,aes,name);
2820 AtlasFont_setFontSize(me,EMpixels, &rowheight, &maxadvancepx);
2821 pixelsNeeded = rowheight * EMpixels / 2 * strlen(alphabet);
2822 dimension = (
unsigned int)sqrt((
double)pixelsNeeded);
2823 dimension = upperPowerOfTwo(dimension);
2825 Atlas_init(atlas,dimension,rowheight);
2827 aes->EMpixels = EMpixels;
2828 aes->maxadvancepx = maxadvancepx;
2829 aes->rowheight = rowheight;
2831 aes->atlasName = name;
2833 RenderFontAtlas(me,aes,alphabet);
2843static int bin2hex(
char *inpath,
char *outpath){
2850 fin = fopen(inpath,
"r+b");
2851 fout = fopen(outpath,
"w+");
2854 char *bufname, *bufdup, *ir, *sep;
2858 buf = MALLOCV(ncol + 1);
2860 bufname = bufdup = STRDUP(inpath);
2861 ir = strrchr(bufname,
'\\');
2862 if(ir) bufname = &ir[1];
2863 ir = strrchr(bufname,
'/');
2864 if(ir) bufname = &ir[1];
2865 ir = strrchr(bufname,
'.');
2868 fprintf(fout,
"unsigned char %s_data[] = \n",bufname);
2874 nc = fread(buf,1,nc,fin);
2875 if(nc < ncol) more = 0;
2877 fprintf(fout,
"%s",sep);
2879 fprintf(fout,
"0x%.2x",hh);
2882 if(more) fprintf(fout,
"\n");
2885 fprintf(fout,
"};\n");
2887 fprintf(fout,
"int %s_size = %d;\n",bufname,m);
2897static int AtlasFont_LoadFromDotC(AtlasFont *font,
unsigned char *start,
int size){
2899 FT_Library fontlibrary;
2903 fontname = font->path;
2905 if(!size || !start){
2906 printf(
"not compiled in C %s\n", font->name);
2910 fontlibrary = getFontLibrary();
2914 args.flags = FT_OPEN_MEMORY;
2915 args.memory_base = start;
2916 args.memory_size = size;
2917 err = FT_Open_Face(fontlibrary, &args, 0, &fontFace);
2920 printf (
"FreeType - can not use font %s\n",fontname);
2923 font->fontFace = fontFace;
2927 printf(
"fontface flags & Scalable? = %ld \n",fontFace->face_flags & FT_FACE_FLAG_SCALABLE );
2928 nsizes = fontFace->num_fixed_sizes;
2929 printf(
"num_fixed_sizes = %d\n",nsizes);
2936static AtlasFont *searchAtlasFontTable(
struct Vector* guitable,
char *name,
int EMsize){
2938 AtlasFont *retval = NULL;
2940 for(i=0;i<vectorSize(guitable);i++){
2941 AtlasFont *el = vector_get(AtlasFont *,guitable,i);
2943 if(!strcmp(name,el->name) && EMsize == el->EMsize){
2955#ifdef HAVE_COMPILED_IN_FONT
2956extern unsigned char VeraMono_ttf_data[];
2957extern int VeraMono_ttf_size;
2958extern unsigned char freewrl_wingding_ttf_data[];
2959extern int freewrl_wingding_ttf_size;
2961unsigned char *VeraMono_ttf_data = NULL;
2962int VeraMono_ttf_size = 0;
2966static int FW_Open_Face(FT_Library library,
char *thisfontname,
int faceIndex, FT_Face *face)
2973 if(VeraMono_ttf_size && strstr(thisfontname,
"VeraMono.ttf")){
2976 args.flags = FT_OPEN_MEMORY;
2977 args.memory_base = VeraMono_ttf_data;
2978 args.memory_size = VeraMono_ttf_size;
2979 err = FT_Open_Face(library, &args, 0, face);
2981 err = FT_New_Face(library, thisfontname, faceIndex, face);
2982 if(err && VeraMono_ttf_size)
2986 args.flags = FT_OPEN_MEMORY;
2987 args.memory_base = VeraMono_ttf_data;
2988 args.memory_size = VeraMono_ttf_size;
2989 err = FT_Open_Face(library, &args, faceIndex, face);
2997AtlasFont *searchAtlasTableOrLoad(
char *facename,
int EMpixels){
3000 font = (AtlasFont*)searchAtlasFontTable(p->font_table,facename,EMpixels);
3002 static char * ascii32_126 =
" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQURSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
3003 int font_tactic, len;
3006 font = GUImalloc(&p->font_table,GUI_FONT);
3008 len = strlen(facename) + 7;
3009 facenamettf = MALLOCV(len);
3010 strcpy(facenamettf,facename);
3011 facenamettf = strcat(facenamettf,
".ttf");
3012 AtlasFont_init(font,facename,EMpixels,facenamettf);
3014 font_tactic = DOTC_NONE;
3015 if(!strcmp(facename,
"VeraMono")){
3018 if(0) font_tactic = DOTC_SAVE;
3019 else font_tactic = DOTC_LOAD;
3020 if(font_tactic == DOTC_LOAD)
3021 AtlasFont_LoadFromDotC(font, VeraMono_ttf_data, VeraMono_ttf_size);
3023 if(!strcmp(facename,
"freewrl_wingding")){
3026 if(0) font_tactic = DOTC_SAVE;
3027 else font_tactic = DOTC_LOAD;
3028 if(font_tactic == DOTC_LOAD)
3029 AtlasFont_LoadFromDotC(font, freewrl_wingding_ttf_data, freewrl_wingding_ttf_size);
3031 if(font_tactic == DOTC_SAVE) {
3035 facenamettfc = alloca(strlen(facenamettf)+3);
3036 strcpy(facenamettfc,facenamettf);
3037 facenamettfc[len-7] =
'_';
3038 strcat(facenamettfc,
".c");
3039 bin2hex(font->path, facenamettfc);
3041 if(font_tactic != DOTC_LOAD)
3042 AtlasFont_LoadFont(font);
3044 AtlasFont_RenderFontAtlas(font,EMpixels,ascii32_126);
3049 printf(
"dug9gui: Can't find font %s did you misname the fontface sb Vera or VeraMono etc?\n",facename);
3057vec4 vec4_init(
float x,
float y,
float z,
float w){
3059 ret.X = x, ret.Y = y; ret.Z = z; ret.W = w;
3064static vec2 vec2_init(
float x,
float y){
3066 ret.X = x, ret.Y = y;
3072typedef struct ivec4 {
int X;
int Y;
int W;
int H;}
ivec4;
3073ivec4 ivec4_init(
int x,
int y,
int w,
int h);
3083static vec2 pixel2normalizedViewportScale( GLfloat x, GLfloat y)
3088 ivec4 currentvp = stack_top(
ivec4,gglobal()->Mainloop._vportstack);
3091 xy.X = ((GLfloat)(x)/(GLfloat)currentvp.W) * 2.0f;
3092 xy.Y = ((GLfloat)(y)/(GLfloat)currentvp.H) * 2.0f;
3096static vec2 pixel2normalizedViewport( GLfloat x, GLfloat y){
3097 ivec4 currentvp = stack_top(
ivec4,gglobal()->Mainloop._vportstack);
3100 xy.X = ((GLfloat)(x - currentvp.X)/(GLfloat)currentvp.W) * 2.0f;
3101 xy.Y = ((GLfloat)(y - currentvp.Y)/(GLfloat)currentvp.H) * 2.0f;
3110Calls commented out, removing from active compile - JAS April 2017
3111static void printvpstacktop(
Stack *vpstack,
int line){
3113 int n = ((
struct Vector*)vpstack)->n;
3114 int xx = ((
ivec4*)((
struct Vector*)vpstack)->data)[3].X;
3115 printf(
"vp top[%d] = [%d %d %d %d] line %d xx=%d\n",n,currentvp.X,currentvp.Y,currentvp.W,currentvp.H,line,xx);
3121Code appears not to be called - JAS April 2017
3123static vec2 pixel2normalizedScreenScale( GLfloat x, GLfloat y)
3128 xy.X = ((GLfloat)x/(GLfloat)screen.X) * 2.0f;
3129 xy.Y = ((GLfloat)y/(GLfloat)screen.Y) * 2.0f;
3137Code appears not to be called - JAS April 2017
3139static vec2 pixel2normalizedScreen( GLfloat x, GLfloat y){
3140 vec2 xy = pixel2normalizedScreenScale(x,y);
3150static GLbyte vShaderStr[] =
3151 "attribute vec4 a_position; \n"
3152 "attribute vec2 a_texCoord; \n"
3153 "uniform mat4 u_ModelViewMatrix; \n"
3154 "uniform mat4 u_ProjectionMatrix; \n"
3155 "varying vec2 v_texCoord; \n"
3158 " gl_Position = u_ProjectionMatrix * u_ModelViewMatrix * a_position; \n"
3159 " v_texCoord = a_texCoord; \n"
3176static GLbyte fShaderStr[] =
3177#ifdef GL_ES_VERSION_2_0
3178 "precision mediump float; \n"
3180 "varying vec2 v_texCoord; \n"
3181 "uniform sampler2D Texture0; \n"
3182 "uniform vec4 Color4f; \n"
3183 "uniform vec4 blend; \n"
3186 " vec4 texColor = texture2D( Texture0, v_texCoord ); \n"
3187 " vec4 one = vec4(1.0,1.0,1.0,1.0); \n"
3188 " vec4 omb = vec4(one.rgb - blend.rgb,1.0 - blend.a); \n"
3189 " vec4 tcolor = omb + (blend*texColor);\n"
3190 " float aa = omb.a*Color4f.a + blend.a*(1.0 -texColor.a);\n"
3191 " tcolor = Color4f * tcolor;\n"
3192 " vec4 finalColor = vec4(tcolor.rgb, 1.0 - aa ); \n"
3193 " gl_FragColor = finalColor; \n"
3202static GLfloat modelviewIdentityf[] = {
3203 1.0f, 0.0f, 0.0f, 0.0f,
3204 0.0f, 1.0f, 0.0f, 0.0f,
3205 0.0f, 0.0f, 1.0f, 0.0f,
3206 0.0f, 0.0f, 0.0f, 1.0f
3208static GLfloat projectionIdentityf[] = {
3209 1.0f, 0.0f, 0.0f, 0.0f,
3210 0.0f, 1.0f, 0.0f, 0.0f,
3211 0.0f, 0.0f, 1.0f, 0.0f,
3212 0.0f, 0.0f, 0.0f, 1.0f
3215static void initProgramObject(){
3221 p->programObject = esLoadProgram ( (
const char*) vShaderStr, (
const char *)fShaderStr );
3223 p->positionLoc = glGetAttribLocation ( p->programObject,
"a_position" );
3224 p->texCoordLoc = glGetAttribLocation ( p->programObject,
"a_texCoord" );
3226 p->textureLoc = glGetUniformLocation ( p->programObject,
"Texture0" );
3227 p->color4fLoc = glGetUniformLocation ( p->programObject,
"Color4f" );
3228 p->blendLoc = glGetUniformLocation ( p->programObject,
"blend" );
3229 p->modelviewLoc = glGetUniformLocation ( p->programObject,
"u_ModelViewMatrix" );
3230 p->projectionLoc = glGetUniformLocation ( p->programObject,
"u_ProjectionMatrix" );
3236JAS - possibly unused - Apr 2017
3238static void dug9gui_DrawImage(
int xpos,
int ypos,
int width,
int height,
char *buffer){
3245GLfloat cursorVert[] = {
3254GLfloat cursorTex[] = {
3262 GLushort ind[] = {0,1,2,3,4,5};
3267 GLfloat cursorVert2[18];
3274 if(0) glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, width, height, 0, GL_LUMINANCE , GL_UNSIGNED_BYTE, buffer);
3277 if(1) glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA , GL_UNSIGNED_BYTE, buffer);
3278 glUniform4f(p->blendLoc,0.0f,0.0f,0.0f,1.0f);
3282 fxy = pixel2normalizedScreen((GLfloat)xpos,(GLfloat)ypos);
3283 fwh = pixel2normalizedScreenScale((GLfloat)width,(GLfloat)height);
3285 fxy.Y = fxy.Y - fwh.Y;
3290 fxy = pixel2normalizedViewport((GLfloat)xpos,(GLfloat)ypos);
3292 fwh = pixel2normalizedViewportScale((GLfloat)width,(GLfloat)height);
3295 fxy.Y = fxy.Y - fwh.Y;
3300 memcpy(cursorVert2,cursorVert,2*3*3*
sizeof(GLfloat));
3304 cursorVert2[i*3 +0] *= fwh.X;
3305 cursorVert2[i*3 +0] += fxy.X;
3306 if(!iyup) cursorVert2[i*3 +1] = 1.0f - cursorVert2[i*3 +1];
3307 cursorVert2[i*3 +1] *= fwh.Y;
3308 cursorVert2[i*3 +1] += fxy.Y;
3314 glActiveTexture ( GL_TEXTURE0 );
3315 glBindTexture ( GL_TEXTURE_2D, p->textureID );
3316 glUniform1i ( p->textureLoc, 0 );
3318 glVertexAttribPointer (p->positionLoc, 3, GL_FLOAT,
3319 GL_FALSE, 0, cursorVert2 );
3321 glVertexAttribPointer (p->texCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, cursorTex );
3322 glEnableVertexAttribArray (p->positionLoc );
3323 glEnableVertexAttribArray (p->texCoordLoc);
3330 glDrawElements ( GL_TRIANGLES, 3*2, GL_UNSIGNED_SHORT, ind );
3340static void dug9gui_DrawSubImage(
float xpos,
float ypos,
float xsize,
float ysize,
3341 int ix,
int iy,
int iw,
int ih,
int width,
int height,
int bpp,
unsigned char *buffer){
3362GLfloat cursorVert[] = {
3370GLfloat cursorTex[] = {
3377 GLushort ind[] = {0,1,2,3,4,5};
3382 GLfloat cursorVert2[18];
3383 GLfloat cursorTex2[12];
3390 glActiveTexture ( GL_TEXTURE0 );
3391 glBindTexture ( GL_TEXTURE_2D, p->textureID );
3392 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3393 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3396 glUniform1i ( p->textureLoc, 0 );
3400 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA , GL_UNSIGNED_BYTE, buffer);
3402 glUniform4f(p->blendLoc,0.0f,0.0f,0.0f,1.0f);
3406 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, width, height, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, buffer);
3409 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA , GL_UNSIGNED_BYTE, buffer);
3410 glUniform4f(p->blendLoc,1.0f,1.0f,1.0f,1.0f);
3418 memcpy(cursorVert2,cursorVert,2*3*3*
sizeof(GLfloat));
3420 cursorVert2[i*3 +0] *= xsize;
3421 cursorVert2[i*3 +0] += xpos;
3422 if(!iyup) cursorVert2[i*3 +1] = 1.0f - cursorVert2[i*3 +1];
3423 cursorVert2[i*3 +1] *= ysize;
3424 cursorVert2[i*3 +1] += ypos;
3427 glVertexAttribPointer (p->positionLoc, 3, GL_FLOAT,
3428 GL_FALSE, 0, cursorVert2 );
3430 fixy.X = (float)ix/(
float)width;
3431 fiwh.X = (float)iw/(
float)width;
3433 fixy.Y = (float)iy/(
float)height;
3434 fiwh.Y = (float)ih/(
float)height;
3436 fixy.Y = (float)(height -iy)/(float)height;
3437 fiwh.Y =-(float)ih/(
float)height;
3439 memcpy(cursorTex2,cursorTex,2*3*2*
sizeof(GLfloat));
3441 cursorTex2[i*2 +0] *= fiwh.X;
3442 cursorTex2[i*2 +0] += fixy.X;
3443 cursorTex2[i*2 +1] *= fiwh.Y;
3444 cursorTex2[i*2 +1] += fixy.Y;
3446 glVertexAttribPointer (p->texCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, cursorTex2 );
3447 glEnableVertexAttribArray (p->positionLoc );
3448 glEnableVertexAttribArray (p->texCoordLoc);
3456 glDrawElements ( GL_TRIANGLES, 3*2, GL_UNSIGNED_SHORT, ind );
3461int render_captiontext(AtlasFont *font,
int *utf32,
int len32,
vec4 color){
3467 int i, pen_x, pen_y;
3476 if(len32 == 0)
return FALSE;
3478 if(!font)
return FALSE;
3481 finishedWithGlobalShader();
3482 glDepthMask(GL_FALSE);
3483 glDisable(GL_DEPTH_TEST);
3484 if(!p->programObject) initProgramObject();
3486 glUseProgram ( p->programObject );
3488 glGenTextures(1, &p->textureID);
3490 glBindTexture(GL_TEXTURE_2D, p->textureID);
3491 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
3492 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
3494 glUniformMatrix4fv(p->modelviewLoc, 1, GL_FALSE,modelviewIdentityf);
3495 glUniformMatrix4fv(p->projectionLoc, 1, GL_FALSE, projectionIdentityf);
3497 glUniform4f(p->color4fLoc,color.X,color.Y,color.Z,color.W);
3499 vportstack = (
Stack*)tg->Mainloop._vportstack;
3500 ivport = stack_top(
ivec4,vportstack);
3502 pen_y = ivport.Y + ivport.H - set->EMpixels;
3504 for (i = 0; i < len32; i++)
3511 entry = AtlasEntrySet_getEntry(set,ichar);
3514 float xpos, ypos, xsize, ysize;
3516 xpos = pen_x + entry->pos.X;
3517 ypos = pen_y - entry->pos.Y;
3518 xsize = entry->size.X;
3519 ysize = entry->size.Y;
3521 fxy = pixel2normalizedViewport((GLfloat)xpos,(GLfloat)ypos);
3522 fwh = pixel2normalizedViewportScale((GLfloat)xsize,(GLfloat)ysize);
3524 fxy.Y = fxy.Y - fwh.Y;
3529 dug9gui_DrawSubImage(xpos,ypos,xsize,ysize,
3530 entry->apos.X, entry->apos.Y, entry->size.X, entry->size.Y,
3531 set->atlas->size.X,set->atlas->size.Y,set->atlas->bytesperpixel,set->atlas->texture);
3532 pen_x += entry->advance.X;
3537 glEnable(GL_DEPTH_TEST);
3538 glDepthMask(GL_TRUE);
3539 restoreGlobalShader();
3545void atlasfont_get_rowheight_charwidth_px(AtlasFont *font,
int *rowheight,
int *maxadvancepx){
3546 *rowheight = font->set->rowheight;
3547 *maxadvancepx = font->set->maxadvancepx;
3552int before_textpanel_render_rows(AtlasFont *font,
vec4 color){
3559 if(font == NULL)
return FALSE;
3560 entryset = font->set;
3561 if(entryset == NULL)
return FALSE;
3562 if(entryset->atlas == NULL)
return FALSE;
3564 atlas = entryset->atlas;
3566 finishedWithGlobalShader();
3567 glDepthMask(GL_FALSE);
3568 glDisable(GL_DEPTH_TEST);
3569 if(!p->programObject) initProgramObject();
3571 glUseProgram ( p->programObject );
3573 glGenTextures(1, &p->textureID);
3576 glActiveTexture ( GL_TEXTURE0 );
3577 glBindTexture ( GL_TEXTURE_2D, p->textureID );
3578 glUniform1i ( p->textureLoc, 0 );
3580 if (atlas->bytesperpixel == 1){
3581 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3582 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3584 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
3585 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3589 if(atlas->bytesperpixel == 1){
3590 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, atlas->size.X, atlas->size.Y, 0, GL_ALPHA , GL_UNSIGNED_BYTE, atlas->texture);
3591 }
else if(atlas->bytesperpixel == 2){
3593 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, atlas->size.X, atlas->size.Y, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, atlas->texture);
3594 }
else if(atlas->bytesperpixel == 4){
3595 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, atlas->size.X, atlas->size.Y, 0, GL_RGBA , GL_UNSIGNED_BYTE, atlas->texture);
3598 glUniform4f(p->color4fLoc,color.X,color.Y,color.Z,color.W);
3599 glUniform4f(p->blendLoc,0.0f,0.0f,0.0f,1.0f);
3601 glUniformMatrix4fv(p->modelviewLoc, 1, GL_FALSE,modelviewIdentityf);
3602 glUniformMatrix4fv(p->projectionLoc, 1, GL_FALSE, projectionIdentityf);
3608int textpanel_render_row(AtlasFont *font,
char * cText,
int len,
int *pen_x,
int *pen_y){
3616 if(cText == NULL)
return FALSE;
3617 if(len == 0)
return FALSE;
3618 if(font == NULL)
return FALSE;
3619 entryset = font->set;
3620 if(entryset == NULL)
return FALSE;
3621 if(entryset->atlas == NULL)
return FALSE;
3625 vec2 charScreenSize;
3626 vec2 charScreenOffset;
3627 vec2 charScreenAdvance;
3631 GLfloat x,y,z, xx, yy;
3645 if(p->textpanel_size < max(maxlen,128)){
3646 int newsize = max(maxlen,128);
3647 p->textpanel_size = newsize;
3648 p->textpanel_vert_size = (2+(2*(newsize*2)))*3;
3649 p->textpanel_tex_size = (4*newsize)*2;
3650 p->textpanel_ind_size = (2*3)*(newsize*2);
3652 p->textpanel_vert = REALLOC(p->textpanel_vert,p->textpanel_vert_size*
sizeof(GLfloat));
3654 p->textpanel_tex = REALLOC(p->textpanel_tex,p->textpanel_tex_size*
sizeof(GLfloat));
3656 p->textpanel_ind = REALLOC(p->textpanel_ind,p->textpanel_ind_size*
sizeof(GLushort));
3658 vert = p->textpanel_vert;
3659 tex = p->textpanel_tex;
3660 ind = p->textpanel_ind;
3662 maxlen = min(maxlen,len);
3665 penxy = pixel2normalizedViewport((GLfloat)(*pen_x),(GLfloat)(*pen_y));
3666 penxy.Y = penxy.Y - 2.0f + .05;
3670 atlas = entryset->atlas;
3671 aw = 1.0f/(float)atlas->size.X;
3672 ah = 1.0f/(float)atlas->size.Y;
3674 for(i=0;i<maxlen;i++)
3676 ichar = (int)cText[i];
3677 if (ichar ==
'\t') ichar =
' ';
3678 ae = AtlasEntrySet_getEntry(entryset,ichar);
3680 ae = AtlasEntrySet_getEntry(entryset,(
int)
' ');
3685 charScreenSize = pixel2normalizedViewportScale(ae->size.X, ae->size.Y);
3686 charScreenAdvance = pixel2normalizedViewportScale(ae->advance.X, ae->advance.Y);
3687 charScreenOffset = pixel2normalizedViewportScale(ae->pos.X,ae->pos.Y);
3689 xx = x + charScreenOffset.X;
3690 yy = y + charScreenOffset.Y;
3693 vert[kk +1] = yy - charScreenSize.Y;
3698 vert[kk +6] = xx + charScreenSize.X;
3701 vert[kk +9] = xx + charScreenSize.X;
3702 vert[kk+10] = yy - charScreenSize.Y;
3704 if(kk+11 >= p->textpanel_vert_size)
3705 printf(
"ouch vert not big enough, need %d have %d\n",kk+11 +1,p->textpanel_vert_size);
3706 x = x + charScreenAdvance.X;
3707 (*pen_x) += ae->advance.X;
3709 tex[kk +0] = ((float)(ae->apos.X))*aw;
3710 tex[kk +2] = ((float)(ae->apos.X))*aw;
3712 tex[kk +4] = ((float)(ae->apos.X + ae->size.X))*aw;
3713 tex[kk +6] = ((float)(ae->apos.X + ae->size.X))*aw;
3716 tex[kk +1] = ((float)(ih - (ae->apos.Y + ae->size.Y)))*ah;
3717 tex[kk +3] = ((float)(ih - ae->apos.Y))*ah;
3719 tex[kk +5] = ((float)(ih - ae->apos.Y))*ah;
3720 tex[kk +7] = ((float)(ih - (ae->apos.Y + ae->size.Y)))*ah;
3722 tex[kk +1] = ((float)((ae->apos.Y + ae->size.Y)))*ah;
3723 tex[kk +3] = ((float)(ae->apos.Y))*ah;
3725 tex[kk +5] = ((float)(ae->apos.Y))*ah;
3726 tex[kk +7] = ((float)((ae->apos.Y + ae->size.Y)))*ah;
3728 if(kk+7 >= p->textpanel_tex_size)
3729 printf(
"ouch tex not big enough, need %d have %d\n",kk+7 +1,p->textpanel_tex_size);
3735 ind[kk +0] = i*4 + 0;
3736 ind[kk +1] = i*4 + 1;
3737 ind[kk +2] = i*4 + 2;
3738 ind[kk +3] = i*4 + 2;
3739 ind[kk +4] = i*4 + 3;
3740 ind[kk +5] = i*4 + 0;
3741 if(kk+5 >= p->textpanel_ind_size)
3742 printf(
"ouch ind not big enough, need %d have %d\n",kk+5 +1,p->textpanel_ind_size);
3747if(0) glEnableVertexAttribArray (p->positionLoc );
3748if(0) glEnableVertexAttribArray (p->texCoordLoc );
3750 glVertexAttribPointer (p->positionLoc, 3, GL_FLOAT,
3751 GL_FALSE, 0, vert );
3753 glVertexAttribPointer ( p->texCoordLoc, 2, GL_FLOAT,
3756 glDrawElements ( GL_TRIANGLES, len*3*2, GL_UNSIGNED_SHORT, ind );
3764void after_textpanel_render_rows(){
3766 glEnable(GL_DEPTH_TEST);
3767 glDepthMask(GL_TRUE);
3768 restoreGlobalShader();
3773This code may not be used anymore - JAS - Apr 2017
3775static void render_screentext0(
struct X3D_Text *tnode){
3782 if(tnode && tnode->_nodeType == NODE_Text){
3788 static int once = 0;
3793 finishedWithGlobalShader();
3794 glDepthMask(GL_FALSE);
3795 glDisable(GL_DEPTH_TEST);
3796 if(!p->programObject) initProgramObject();
3798 glUseProgram ( p->programObject );
3800 glGenTextures(1, &p->textureID);
3802 glBindTexture(GL_TEXTURE_2D, p->textureID);
3803 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
3804 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
3805 glUniformMatrix4fv(p->modelviewLoc, 1, GL_FALSE,modelviewIdentityf);
3806 glUniformMatrix4fv(p->projectionLoc, 1, GL_FALSE, projectionIdentityf);
3812 font = (AtlasFont*)sdata->atlasfont;
3814 rowvec = sdata->rowvec;
3816 if(!once) printf(
"%s %5s %10s %10s %10s %10s !\n",
"c",
"adv",
"sx",
"sy",
"x",
"y");
3818 for(row=0;row<nrow;row++){
3819 for(i=0;i<rowvec[row].len32;i++){
3822 ichar = rowvec[row].str32[i];
3823 entry = AtlasEntrySet_getEntry(set,ichar);
3827 float xpos, ypos, xsize, ysize;
3832 xpos = (float)chr.x + 90.0f + entry->pos.X;
3833 ypos = (float)chr.y + 30.0f - entry->pos.Y;
3834 xsize = entry->size.X;
3835 ysize = entry->size.Y;
3838 fxy = pixel2normalizedScreen((GLfloat)xpos,(GLfloat)ypos);
3839 fwh = pixel2normalizedScreenScale((GLfloat)xsize,(GLfloat)ysize);
3841 fxy.Y = fxy.Y - fwh.Y;
3850 fxy = pixel2normalizedViewport((GLfloat)xpos,(GLfloat)ypos);
3851 fwh = pixel2normalizedViewportScale((GLfloat)xsize,(GLfloat)ysize);
3853 fxy.Y = fxy.Y - fwh.Y;
3861 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);
3863 dug9gui_DrawSubImage(xpos,ypos, xsize, ysize,
3864 entry->apos.X, entry->apos.Y, entry->size.X, entry->size.Y,
3865 set->atlas->size.X,set->atlas->size.Y,set->atlas->bytesperpixel,set->atlas->texture);
3870 glEnable(GL_DEPTH_TEST);
3871 glDepthMask(GL_TRUE);
3872 restoreGlobalShader();
3878static void dug9gui_DrawSubImage_scene(
float xpos,
float ypos,
float xsize,
float ysize,
3879 int ix,
int iy,
int iw,
int ih,
int width,
int height,
int bpp,
unsigned char *buffer){
3900GLfloat cursorVert[] = {
3908GLfloat cursorTex[] = {
3915 GLushort ind[] = {0,1,2,3,4,5};
3920 GLfloat cursorVert2[18];
3921 GLfloat cursorTex2[12];
3928 glActiveTexture ( GL_TEXTURE0 );
3929 glBindTexture ( GL_TEXTURE_2D, p->textureID );
3932 glUniform1i ( p->textureLoc, 0 );
3936 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA , GL_UNSIGNED_BYTE, buffer);
3938 glUniform4f(p->blendLoc,0.0f,0.0f,0.0f,1.0f);
3942 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, width, height, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, buffer);
3945 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA , GL_UNSIGNED_BYTE, buffer);
3946 glUniform4f(p->blendLoc,1.0f,1.0f,1.0f,1.0f);
3955 memcpy(cursorVert2,cursorVert,2*3*3*
sizeof(GLfloat));
3957 cursorVert2[i*3 +0] *= xsize;
3958 cursorVert2[i*3 +0] += xpos;
3959 if(!iyup) cursorVert2[i*3 +1] = 1.0f - cursorVert2[i*3 +1];
3960 cursorVert2[i*3 +1] *= ysize;
3961 cursorVert2[i*3 +1] += ypos;
3964 glVertexAttribPointer (p->positionLoc, 3, GL_FLOAT,
3965 GL_FALSE, 0, cursorVert2 );
3967 fixy.X = (float)ix/(
float)width;
3968 fiwh.X = (float)iw/(
float)width;
3970 fixy.Y = (float)iy/(
float)height;
3971 fiwh.Y = (float)ih/(
float)height;
3973 fixy.Y = (float)(height -iy)/(float)height;
3974 fiwh.Y =-(float)ih/(
float)height;
3976 memcpy(cursorTex2,cursorTex,2*3*2*
sizeof(GLfloat));
3978 cursorTex2[i*2 +0] *= fiwh.X;
3979 cursorTex2[i*2 +0] += fixy.X;
3980 cursorTex2[i*2 +1] *= fiwh.Y;
3981 cursorTex2[i*2 +1] += fixy.Y;
3983 glVertexAttribPointer (p->texCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, cursorTex2 );
3984 glEnableVertexAttribArray (p->positionLoc );
3985 glEnableVertexAttribArray (p->texCoordLoc);
3993 glDrawElements ( GL_TRIANGLES, 3*2, GL_UNSIGNED_SHORT, ind );
3999static void render_screentext_aligned(
struct X3D_Text *tnode,
int screenAligned){
4004 if(tnode && tnode->_nodeType == NODE_Text){
4011 static int once = 0;
4012 GLfloat modelviewf[16], projectionf[16];
4013 GLdouble modelviewd[16], projectiond[16];
4018 finishedWithGlobalShader();
4019 glDepthMask(GL_FALSE);
4020 glDisable(GL_DEPTH_TEST);
4021 if(!p->programObject) initProgramObject();
4023 glUseProgram ( p->programObject );
4025 glGenTextures(1, &p->textureID);
4027 glBindTexture(GL_TEXTURE_2D, p->textureID);
4028 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
4029 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
4035 glUniform4f(p->color4fLoc,.5f,.5f,.5f,1.0f);
4038 dc = myap->fw_FrontMaterial.diffuse;
4039 glUniform4f(p->color4fLoc,dc[0],dc[1],dc[2],dc[3]);
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++){
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++){
4218 FREE_IF_NZ(e->name);
4226 printf(
"mystery type %d\n",itype);