void OLabel::handleAWord(const std::string& word, float& currentLineLength, float width) { float wordWidth = getWordWidth(word); if (currentLineLength + wordWidth > width) { if (currentLineLength > 0) { m_Lines.push_back(""); m_LinesWidth.push_back(0); currentLineLength = 0; } if (wordWidth <= width) { handleAWord(word, currentLineLength, width); } else { for(auto& c : word) { float cWidth = getCharWidth(c); if (currentLineLength + cWidth > width && cWidth <= width) { m_Lines.push_back(""); m_LinesWidth.push_back(0); currentLineLength = 0; } else if (cWidth > width){ break; } else { m_Lines.back() += c; m_LinesWidth.back() += cWidth; currentLineLength += cWidth; } } } } else { currentLineLength += wordWidth; m_Lines.back() += word; //add the word to the current line m_LinesWidth.back() += wordWidth; //add the word width to the current line width } }
//======================================================================== // // NAME GFXFont::wrapStr // // DESCRIPTION // modifies *str so that it will word wrap within the // specified width. Carriage returns are removed // and replaced with spaces or spaces are removed and // replaced by carriage returns. // // ARGUMENTS // str - String to be modified // width - wrapping width in pixels // RETURNS // // NOTES // Tabs are not supported. // //======================================================================== void GFXFont::wrapStr(char *str, Int32 width) { Int32 spaceLen; // length of a space character Int32 lineLen; // length of current line Int32 wordLen; // length of current word char *lastSpace; spaceLen = getWidth(' ') + getSpacing(); lineLen = 0; lastSpace = NULL; while (*str) { // convert spaces if (isspace(*str)) { lineLen += spaceLen; *str = ' '; lastSpace = str; str++; } else { wordLen = getWordWidth((void *)str); if ((lineLen + wordLen) > width) { if (lastSpace) { *lastSpace = '\n'; lastSpace = NULL; lineLen = 0; } } lineLen += wordLen; while (*str && (! isspace(*str)) ) str++; } } }
void drawFontWordCA(float x, float y, char *word) { drawFontWord((int)(x - getWordWidth(word) / 2), y, word); }
void drawOSD() { float x; float y; float tab; drawFrameSet2D(); glEnable(GL_BLEND); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); glBindTexture(GL_TEXTURE_2D, 0); #ifdef WITHOUT_AGAR // Top middle y = 10; glColor4f(1,1,1,1); drawFontWordCA(video.screenW / 2, y, "Hit SPACE to start a new simulation"); drawFontWordCA(video.screenW / 2, y += fontHeight, "Hold down a mouse button and move it around to change your orientation."); drawFontWordCA(video.screenW / 2, y += fontHeight, "Use the scroll wheel, or the A and Z keys to zoom in and out."); glColor4f(1,1,1,.5f); drawFontWordCA(video.screenW / 2, y += fontHeight, "press F1 for keyboard commands help."); #endif // Right DUHC(); drawFontWordRA((float)video.screenW - 10, (float)video.screenH - 10 - fontHeight * 1.0f, "press F1 for help"); drawFontWordRA((float)video.screenW - 10, (float)video.screenH - 10 - fontHeight * 3.0f, GRAVIT_VERSION); drawFontWordRA((float)video.screenW - 10, (float)video.screenH - 10 - fontHeight * 2.0f, GRAVIT_COPYRIGHT); // Left y = 10; x = 10; tab = getWordWidth("M") * 17; if (view.textMode == TM_STANDARD) { if (state.fileName) { DUH("simulation name", state.fileName); } else { DUH("simulation name", "-"); } DUH("particles", va("%i", state.particleCount)); DUH("avg video fps", va("%3.2f", fpsCurrentAverageFPS)); DUH("avg video frame time", va("%.0fms", fpsCurrentAverageFT)); DUH("last record frame time", va("%ims", view.deltaRecordFrame)); DUH("actual frames", va("%i", state.totalFrames)); DUH("recording skip", va("%i", state.historyNFrame)); if (view.frameSkip && state.mode & SM_PLAY) { DUH("display frame", va("%i (%i)", state.currentFrame, view.frameSkip)); } else { DUH("display frame", va("%i", state.currentFrame)); } DUH("recorded frames", va("%i", state.frame)); DUH("max frames", va("%i", state.historyFrames)); DUH("particle vertices", va("%i", view.vertices)); #if NBODY_METHOD == METHOD_OT DUH("tree nodes allocated", va("%i", view.recordNodes)); #endif DUH("memory allocated", va("%.1fmb", (float)state.memoryAllocated / 1024 / 1024)); if (state.mode & SM_RECORD) { glColor4f(1,0,0,.8f); y += fontHeight; y = drawFontWord(x, y, "RECORDING"); DUHC(); DUH("time left", va("~%0.1f minutes", (float)view.deltaRecordFrame * (state.historyFrames - state.frame) / 1000 / 60)); switch (view.recordStatus) { case 0: default: if (state.mode & SM_RECORD) { DUH("status", "rendering ..."); } else { DUH("status", "dormant"); } break; case 1: DUH("status", va("generating tree %.1f%%", (float)view.recordParticlesDone/state.particleCount*100)); break; case 2: DUH("status", va("applying forces %.1f%%", (float)view.recordParticlesDone/state.particleCount*100)); break; case 3: DUH("status", "freeing tree"); break; } } else if (state.mode & SM_PLAY) { glColor4f(0,1,0,.8f); y += fontHeight; y = drawFontWord(x, y, "PLAY"); } else if (state.currentlySpawning) { glColor4f(1,1,0,.8f); y += fontHeight; y = drawFontWord(x, y, "SPAWNING"); DUHC(); DUH("status", va("%.1f%%", (float)view.recordParticlesDone/state.particleCount*100)); } if (view.screenshotLoop) { glColor4f(1,0,0,.8f); y += fontHeight * 2; y = drawFontWord(x, y, "AUTO SCREENSHOT"); } // show renderer FPS average (if we have meaningful values) if ((view.timed_frames > 1) && (view.totalRenderTime > SDL_TIMESLICE )) { if (state.mode & SM_RECORD) { glColor4f(0,1,1,.5f); /*torquise*/ } else { DUHC(); y += fontHeight; } // XXX: This might be too many stats. I'll implement this in the ajax windowing screens. DUH("avg renderer fps", va("%5.2f", (float) view.timed_frames/ (float) view.totalRenderTime * 1000.0f )) /* DUH("avg renderer frame time", va("%4.1f ms", (float) view.totalRenderTime / (float) view.timed_frames )); */ DUHC(); } /* big = state.particleCount*state.particleCount-state.particleCount; DUH("total calcs", va("%-5i %3.2f%% (max: %i)", otGetNCalcs(), (float)otGetNCalcs()/big*100, state.particleCount*state.particleCount-state.particleCount)); DUH("space calcs", va("%-5i %3.2f%%", otGetSCalcs(), (float)100 * otGetSCalcs() / otGetNCalcs())); DUH("particle calcs", va("%-5i %3.2f%%", otGetPCalcs(), (float)100 * otGetPCalcs() / otGetNCalcs())); */ } if (view.textMode >= TM_HELP1) { WHITEHEADING(va("HELP!", view.textMode - TM_HELP1 + 1)); NEWLINE(); DUHC(); DUH("F1", "General Shortcut Keys"); DUH("F2", "Visual Effects Keys"); DUH("` (above TAB) or 1", "Use the Console"); DUH("ESC", "Exit Console/Help/Gravit"); } if (view.textMode == TM_HELP1) { WHITEHEADINGNL("GENERAL SHORTCUT KEYS"); WHITEHEADINGNL("Recording/Playback"); DUHC(); DUH("SPACE", "spawn particles"); DUH("F5", "replay"); DUH("F6", "record"); DUH("F7", "pause"); DUH("Q W", "decrease / increase playback speed"); DUH("CTRL + S", "quick save"); WHITEHEADINGNL("View Controls"); DUHC(); DUH("mouse X Y + button", "rotate (with mouse button)"); DUH("A Z", "zoom"); WHITEHEADINGNL("Stereoscopy"); DUHC(); DUH("S", "toggle stereo mode"); DUH("D F", "decrease / increase stereoseparation"); WHITEHEADINGNL("Other"); DUHC(); DUH("T", "display current oct tree"); DUH("O", "toggles drawing text"); DUH("P", "toggles drawing Sky background"); DUH("F9", "take one screenshot"); DUH("F10", "take a screenshot every frame (CAREFUL!)"); } if (view.textMode == TM_HELP2) { WHITEHEADINGNL("VISUAL EFFECTS KEYS"); WHITEHEADINGNL("Colours"); DUHC(); DUH("/", "colour mode (mass/vel/acc)"); DUH("L", "blending mode"); WHITEHEADINGNL("Particles"); DUHC(); DUH("\\", "particle render mode (circle/texture)"); DUH("= -", "min particle size"); DUH("[ ]", "max particle size"); WHITEHEADINGNL("Particle Tail"); DUHC(); DUH("X", "tail fade"); DUH("C V", "tail opacity"); DUH("B N", "tail length less/more"); DUH("M", "tail length infinite/none"); DUH(", (comma) . (period)", "tail resolution"); DUH("; (semicolon) ' (quote)", "tail width"); } }