// Constructor sets base variables RecordBox::RecordBox(u16 **_vram, void (*_onOk)(void), void (*_onCancel)(void), Sample *_sample, Instrument *_instrument, u8 _smpidx) :Widget((SCREEN_WIDTH-RECORDBOX_WIDTH)/2, (SCREEN_HEIGHT-RECORDBOX_HEIGHT)/2, RECORDBOX_WIDTH, RECORDBOX_HEIGHT, _vram, true), recording(false), btndown(false), onOk(_onOk), onCancel(_onCancel), sample(_sample), instrument(_instrument), smpidx(_smpidx), sound_data(0) { title = "sample recorder"; const char *msg = "hold down a"; u8 msgwidth = getStringWidth(msg); labelmsg = new Label(x+(RECORDBOX_WIDTH-msgwidth)/2, y+18, msgwidth+5, 12, _vram, false); labelmsg->setCaption(msg); msg = "or press b"; msgwidth = getStringWidth(msg); labelmsg2 = new Label(x+(RECORDBOX_WIDTH-msgwidth)/2, y+30, msgwidth+5, 12, _vram, false); labelmsg2->setCaption(msg); msg = "recording"; msgwidth = getStringWidth(msg); labelrec = new Label(x+(RECORDBOX_WIDTH-msgwidth)/2, y+33, msgwidth+5, 12, _vram, false, false, true); labelrec->setCaption(msg); labelrec->hide(); buttoncancel = new Button(x+(RECORDBOX_WIDTH-50)/2, y+44, 50, 14, _vram); buttoncancel->setCaption("cancel"); buttoncancel->registerPushCallback(_onCancel); }
void RecordBox::draw(void) { drawGradient(theme->col_dark_ctrl, theme->col_light_ctrl, 0, 0, width, 16); drawLine(0,16, width, 1, theme->col_outline); if(recording==true) { drawFullBox(0, 17, width, RECORDBOX_HEIGHT-17, theme->col_signal); labelmsg->setTheme(theme, theme->col_signal); labelmsg2->setTheme(theme, theme->col_signal); buttoncancel->setTheme(theme, theme->col_signal); labelrec->show(); labelmsg->hide(); labelmsg2->hide(); buttoncancel->hide(); } else { drawFullBox(0, 17, width, RECORDBOX_HEIGHT-17, theme->col_light_bg); labelrec->hide(); labelmsg->show(); labelmsg2->show(); buttoncancel->show(); buttoncancel->pleaseDraw(); } drawBorder(); u8 titlewidth = getStringWidth(title)+5; drawString(title, (RECORDBOX_WIDTH-titlewidth)/2, 2, titlewidth+5); labelmsg->pleaseDraw(); labelmsg2->pleaseDraw(); labelrec->pleaseDraw(); }
void ToucheEngine::drawButton(void *button) { Button *b = (Button *)button; if (b->flags & kButtonBorder) { Graphics::drawRect(_offscreenBuffer, kScreenWidth, b->x, b->y, b->w, b->h, 0xF7, 0xF9); } if (b->flags & kButtonText) { if (b->data != 0) { const char *str = getString(b->data); const int w = getStringWidth(b->data); const int h = kTextHeight; const int x = b->x + (b->w - w) / 2; const int y = b->y + (b->h - h) / 2; Graphics::drawString16(_offscreenBuffer, kScreenWidth, 0xFF, x, y, str); } } if (b->flags & kButtonArrow) { int dx = 0; int dy = 0; switch (b->data) { case 2000: // up arrow dx = 1; dy = 2; break; case 2001: // down arrow dx = -1; dy = -2; break; } const int x = b->x + b->w / 2; const int y = b->y + b->h / 2; drawArrow(_offscreenBuffer, kScreenWidth, x, y + dy + 1, dx, 0xD2); drawArrow(_offscreenBuffer, kScreenWidth, x, y + dy, dx, 0xFF); } }
void ofxUILabel::setLabel(string _label) { label = string(_label); if(autoSize) { float w = font->stringWidth(label); float h = font->stringHeight("1"); //otherwise we get some funky non-uniform spacing :( rect->setWidth(w); rect->setHeight(h); xOffset = 0; yOffset = 0; } else { while(getStringWidth(label) > rect->getWidth()-padding*4.0 && label.size()) { label = label.substr(0, label.size()-1); } float h = (int)font->stringHeight("1"); //otherwise we get some funky non-uniform spacing :( if(rect->getHeight() > 0) { yOffset = 0; } else { rect->setHeight(h); yOffset = 0; } xOffset = 0; } }
void Font::drawString(Surface *dst, const Common::String &str, int x, int y, int with_color, int spacing, bool markDirty) const { assert(dst != NULL); assert(x >= 0); assert(y >= 0); uint widest = getStringWidth(str, spacing); int curx = x + (widest - getLineWidth(str, 0, spacing)) / 2; int cury = y; for (uint i = 0; i < str.size(); ++i) { // If we encounter the '|' char (newline and end of string marker), // skip it and go to the start of the next line if (str[i] == '|') { cury += getFontHeight(); curx = x + (widest - getLineWidth(str, i+1, spacing) - 1) / 2; continue; } // Break early if there's no more space on the screen if (curx >= dst->w - 1 || cury >= dst->h - 1) { break; } drawChar(dst, str[i], curx, cury, with_color); curx += getCharWidth(str[i]) + spacing; } if (markDirty) { Common::Rect r(x, y, x + widest, y + getStringHeight(str)); dst->markDirtyRect(r); } }
void GroupBox::draw(void) { drawBox(0, 4, width, height, theme->col_lighter_bg); u16 strwidth = getStringWidth(text); drawFullBox(10, 0, strwidth+2, 10, theme->col_light_bg); drawString(text, 11, 0, width - 12); }
//ensure the surface is large enough void drawContextFltkStringTexture::drawString(const char *str) { GLfloat pos[4], color[4]; glGetFloatv(GL_CURRENT_RASTER_POSITION, pos); glGetFloatv(GL_CURRENT_COLOR, color); queueString::element elem = {str, pos[0], pos[1], pos[2], color[0], color[1], color[2], color[3], _currentFontSize, _currentFontId, getStringWidth(str) + 1, getStringHeight()}; _queue->append(elem); }
void FWRenderer::drawString(const char *string, byte param) { int width; width = getStringWidth(string) + 10; width = width > 300 ? 300 : width; drawMessage(string, (320 - width) / 2, 80, width, 4); blit(); }
void NormalizeBox::draw(void) { drawGradient(theme->col_list_highlight1, theme->col_list_highlight2, 0, 0, width, 16); drawLine(0,16, width, 1, RGB15(0,0,0)|BIT(15)); drawFullBox(0, 17, width, NORMALIZEBOX_HEIGHT-17, theme->col_light_bg); drawBorder(); u8 titlewidth = getStringWidth(title)+5; drawString(title, (NORMALIZEBOX_WIDTH-titlewidth)/2, 2, titlewidth+5); gui.draw(); }
/** * Fills out the passed rect with the dimensions of a given string word-wrapped to a * maximum specified width * * @s Message to be analyzed * @bounds Rectangle to put output size into * @maxWidth Maximum allowed line width in pixels */ void GfxFont::getStringBounds(const char *s, Rect &bounds, int maxWidth) { if (maxWidth == 0) { // No maximum width, so set bounds for a single line bounds.set(0, 0, getStringWidth(s), getHeight()); } else { int numLines = 0; int lineWidth = 0; // Loop to figure out the number of lines required, and the maximum line width while (*s) { const char *msg = s; int numChars = getStringFit(msg, maxWidth); lineWidth = MAX(lineWidth, getStringWidth(s, numChars)); s = msg; ++numLines; } bounds.set(0, 0, lineWidth, numLines * getHeight()); } }
void Textbox::appendText( std::string newText, glm::vec3 color ) { // get edges GLuint leftEdge = pos.x + paddingHorizontal + borderSize; GLuint rightEdge = pos.x + size.x - paddingHorizontal - borderSize - btnSize.x; // loop through each token of text std::string delimiter = " "; GLfloat delimOffset = getStringWidth( " " ); std::string token; GLuint start = 0; GLuint end = newText.find( delimiter ); while ( end != std::string::npos ) { // get the next token token = newText.substr( start, end - start ); // calculate the width of the token GLfloat width = getStringWidth( token ); // check to see if token fits on the same line if ( leftEdge + currHorizontalOffset + width > rightEdge ) { addNewLine(); } tokens.push_back( StringToken( token, currHorizontalOffset, currentLineNumber, color ) ); // move horizontal offset currHorizontalOffset += width + delimOffset; start = end + delimiter.length(); end = newText.find( delimiter, start ); } token = newText.substr( start, newText.size() ); GLfloat width = getStringWidth( token ); if ( leftEdge + currHorizontalOffset + width > rightEdge ) { addNewLine(); } tokens.push_back( StringToken( token, currHorizontalOffset, currentLineNumber, color ) ); currHorizontalOffset += width + delimOffset; }
void Matrix::writeString(char* _c, bool _m, uint16_t _t, int16_t _xy) { setFontMode(_m); int c1 = (_m ? getWidth() : getHeight()) * 8; int c2 = -(_m ? getStringWidth(_c) : getStringHeight(_c)) - c1; for (int a = c1; a > c2; a--) { setCursor((_m ? a : _xy), (_m ? _xy : a)); print(_c); delay(_t); #ifdef WDT wdt_reset(); #endif } }
void GLFont::drawText(const char *text, int halign) { int width = getStringWidth(text); int lines = 1; if (textWidth < width) textWidth = width; for (const char *pc = text; *pc; pc++) { if (*pc == '\n') lines++; } textLines.push_back(TextLine(text, halign, width, lines)); textHeight += lines * bmfont.common.lineHeight; }
void MainMenuUserInterface::render() { Parent::render(); if(motd[0]) { U32 width = getStringWidth(20, motd); glColor3f(1,1,1); U32 totalWidth = width + canvasWidth; U32 pixelsPerSec = 100; U32 delta = gClientGame->getCurrentTime() - motdArriveTime; delta = U32(delta * pixelsPerSec * 0.001) % totalWidth; drawString(canvasWidth - delta, 540, 20, motd); } }
void SmushFont::drawString(const char *str, byte *buffer, int dst_width, int dst_height, int x, int y, bool center) { debugC(DEBUG_SMUSH, "SmushFont::drawString(%s, %d, %d, %d)", str, x, y, center); while (str) { char line[256]; char *pos = (char *)strchr(str, '\n'); if (pos) { memcpy(line, str, pos - str - 1); line[pos - str - 1] = 0; str = pos + 1; } else { strcpy(line, str); str = 0; } drawSubstring(line, buffer, dst_width, center ? (x - getStringWidth(line) / 2) : x, y); y += getStringHeight(line); } }
void HUD::drawHUD(int score, int multiplier, int timeRemaining) { ////// //Draw the score text ///// char scoreAsChar[10];//limiting this to 10 will probably cause mad //crashes when scores start getting smashed all round the gaff _itoa(score, scoreAsChar,10); //we want to pin the score to right-alignment, like in the game-over screen //calculate the score's width float scoreOffset = getStringWidth(scoreFont,0,0, scoreAsChar); printWithColour(scoreTextFont, scorePos.x, scorePos.y, scoreTextColour, scoreText); printWithColour(scoreFont, scorePos.x+205-scoreOffset, scorePos.y, scoreColour, scoreAsChar); drawMulti(multiplier); drawTimer(timeRemaining); }
void CFont:: getStringBBox(const std::string &str, double x[4], double y[4]) const { double w = getStringWidth(str); double a = getCharAscent (); double d = getCharDescent(); double angle = getAngle(); double c = CMathGen::DCos(angle); double s = CMathGen::DSin(angle); x[0] = + d*s; y[0] = - d*c; x[1] = w*c + d*s; y[1] = w*s - d*c; x[2] = w*c - a*s; y[2] = w*s + a*c; x[3] = - a*s; y[3] = + a*c; }
void CreditContext::draw(){ //clear screen SDL_FillRect(screen,NULL,SDL_MapRGB(screen->format,0,0,0)); //draw listing int width = 0; int x = 0; for(size_t i = 0; i < creditListing.size(); ++i ){ width = getStringWidth(font::creditFont.at(fontSize), creditListing.at(i)); x = centerX( width, screen->w ); drawText( creditListing.at(i), font::creditFont.at(fontSize), colour::white, screen, x, line*i+y ); } //draw black box and "Press Esc to return" SDL_FillRect(screen, &escBox, SDL_MapRGB(screen->format,0,0,0)); drawText( "Press Esc to return", font::mainFont.at(16), colour::yellow, screen, 0, 0); }
/** * Returns the maximum number of characters for words that will fit into a given width * * @s Message to be analyzed * @maxWidth Maximum allowed width */ int GfxFont::getStringFit(const char *&s, int maxWidth) { const char *nextWord = NULL; const char *sStart = s; int numChars = 1; int strWidth = 1; char nextChar; for (;;) { nextChar = *s++; if ((nextChar == '\r') || (nextChar == '\0')) break; // Check if it's a word end if (nextChar == ' ') { nextWord = s; } strWidth = getStringWidth(sStart, numChars); if (strWidth > maxWidth) { if (nextWord) { s = nextWord; nextChar = ' '; } break; } ++numChars; } int totalChars = s - sStart; if (nextChar == '\0') --s; if ((nextChar == ' ') || (nextChar == '\r') || (nextChar == '\0')) --totalChars; return totalChars; }
int Font::wordWrapText(const Common::String &str, int maxWidth, Common::Array<Common::String> &lines) const { WordWrapper wrapper(lines); Common::String line; Common::String tmpStr; int lineWidth = 0; int tmpWidth = 0; // The rough idea behind this algorithm is as follows: // We accumulate characters into the string tmpStr. Whenever a full word // has been gathered together this way, we 'commit' it to the line buffer // 'line', i.e. we add tmpStr to the end of line, then clear it. Before // we do that, we check whether it would cause 'line' to exceed maxWidth; // in that case, we first add line to lines, then reset it. // // If a newline character is read, then we also add line to lines and clear it. // // Special care has to be taken to account for 'words' that exceed the width // of a line. If we encounter such a word, we have to wrap it over multiple // lines. uint last = 0; for (Common::String::const_iterator x = str.begin(); x != str.end(); ++x) { const byte c = *x; const int w = getCharWidth(c) + getKerningOffset(last, c); last = c; const bool wouldExceedWidth = (lineWidth + tmpWidth + w > maxWidth); // If this char is a whitespace, then it represents a potential // 'wrap point' where wrapping could take place. Everything that // came before it can now safely be added to the line, as we know // that it will not have to be wrapped. if (Common::isSpace(c)) { line += tmpStr; lineWidth += tmpWidth; tmpStr.clear(); tmpWidth = 0; // If we encounter a line break (\n), or if the new space would // cause the line to overflow: start a new line if (c == '\n' || wouldExceedWidth) { wrapper.add(line, lineWidth); continue; } } // If the max line width would be exceeded by adding this char, // insert a line break. if (wouldExceedWidth) { // Commit what we have so far, *if* we have anything. // If line is empty, then we are looking at a word // which exceeds the maximum line width. if (lineWidth > 0) { wrapper.add(line, lineWidth); // Trim left side while (tmpStr.size() && Common::isSpace(tmpStr[0])) { tmpStr.deleteChar(0); // This is not very fast, but it is the simplest way to // assure we do not mess something up because of kerning. tmpWidth = getStringWidth(tmpStr); } } else { wrapper.add(tmpStr, tmpWidth); } } tmpWidth += w; tmpStr += c; } // If some text is left over, add it as the final line line += tmpStr; lineWidth += tmpWidth; if (lineWidth > 0) { wrapper.add(line, lineWidth); } return wrapper.actualMaxLineWidth; }
/** * Writes a specified string within a given area with support for word wrapping and text alignment types * * @s String to display * @bounds Bounds to display the text within * @align Text alignment mode */ void GfxFont::writeLines(const char *s, const Rect &bounds, TextAlign align) { int lineNum = 0; // Lock the surface for access _gfxManager->lockSurface(); while (*s) { const char *msgP = s; int numChars = getStringFit(msgP, bounds.width()); _position.y = bounds.top + lineNum * getHeight(); switch (align) { case ALIGN_RIGHT: // Right aligned text _position.x = bounds.right - getStringWidth(s, numChars); writeString(s, numChars); break; case ALIGN_CENTER: // Center aligned text _position.x = bounds.left + (bounds.width() / 2) - (getStringWidth(s, numChars) / 2); writeString(s, numChars); break; case ALIGN_JUSTIFIED: { // Justified text // Get the number of words in the string portion int charCtr = 0, numWords = 0; while (charCtr < numChars) { if (s[charCtr] == ' ') ++numWords; ++charCtr; } // If end of string, count final word if (*msgP == '\0') ++numWords; // Display the words of the string int spareWidth = bounds.width() - getStringWidth(s, numChars); charCtr = 0; _position.x = bounds.left; while (charCtr < numChars) { writeChar(s[charCtr]); if ((numWords > 0) && (s[charCtr] == ' ')) { int separationWidth = spareWidth / numWords; spareWidth -= separationWidth; --numWords; _position.x += separationWidth; } ++charCtr; } break; } case ALIGN_LEFT: default: // Standard text _position.x = bounds.left; writeString(s, numChars); break; } // Next line s = msgP; ++lineNum; } // Release the surface lock _gfxManager->unlockSurface(); }
//-------------------------------------------------------------- void ofxFreeType2::drawTextArea(string s, int x, int y, int width, int height, ofTextAlignment alignment, bool bHideOverflow, bool bDrawOutlines) { //Check to see that the font has been loaded! if (!bFaceLoaded){ ofLog(OF_LOG_ERROR,"Error : font not allocated, please load font first!"); return; }; if (bDrawOutlines && !bMakeContours){ ofLog(OF_LOG_ERROR,"Error : contours not created for this font - call loadFont with makeContours set to true"); return; } //Keep Track of Cursor Position int xPos = 0; int yPos = 0; //Record Lines vector <string> lines = getTextAreaLines(s,width); string formattedText = ""; switch (alignment) { case OF_TEXT_ALIGN_LEFT: //Add all lines together, seperate with '\n' for(int i=0; i<lines.size(); i++) { //Check for overflow, if we are hiding it we are finished if(bHideOverflow && yPos + lineHeight > height) { break; } //Add Text formattedText += lines[i]; //Advance line if(i!=lines.size()-1) { formattedText += '\n'; yPos += lineHeight; } } //Draw the line as string if(bDrawOutlines) { drawStringAsShapes(formattedText, x, y); } else { drawString(formattedText, x, y); } break; case OF_TEXT_ALIGN_CENTER: //Draw each line individually, aligning each individually yPos = y; for(int i=0; i<lines.size();i++) { //Check for overflow, if we are hiding it we are finished if(bHideOverflow && yPos - y + lineHeight > height) { break; } xPos = x+ width/2 - getStringWidth(lines[i])/2; if(bDrawOutlines) { drawStringAsShapes(lines[i], xPos, yPos); } else { drawString(lines[i], xPos, yPos); } yPos += lineHeight; } break; case OF_TEXT_ALIGN_RIGHT: //Draw each line individually, aligning each individually yPos = y; for(int i=0; i<lines.size();i++) { //Check for overflow, if we are hiding it we are finished if(bHideOverflow && yPos - y + lineHeight > height) { break; } xPos = x + width - getStringWidth(lines[i]); if(bDrawOutlines) { drawStringAsShapes(lines[i], xPos, yPos); } else { drawString(lines[i], xPos, yPos); } yPos += lineHeight; } default: break; } }
/** * Returns the width of the given string in the current font * * @s String to return the width of */ int GfxFont::getStringWidth(const char *s) { return getStringWidth(s, strlen(s)); }
void IFont::renderTextCenter(SDL_Surface * surface, const std::string & data, const SDL_Color & color, const Point & pos) const { Point size(getStringWidth(data), getLineHeight()); renderText(surface, data, color, pos - size / 2); }
void SmushFont::drawStringWrap(const char *str, byte *buffer, int dst_width, int dst_height, int x, int y, int left, int right, bool center) { debugC(DEBUG_SMUSH, "SmushFont::drawStringWrap(%s, %d, %d, %d, %d, %d)", str, x, y, left, right, center); const int width = right - left; char *s = strdup(str); char *words[MAX_WORDS]; int word_count = 0; char *tmp = s; while (tmp) { assert(word_count < MAX_WORDS); words[word_count++] = tmp; tmp = strpbrk(tmp, " \t\r\n"); if (tmp == 0) break; *tmp++ = 0; } int i = 0, max_width = 0, height = 0, line_count = 0; char *substrings[MAX_WORDS]; int substr_widths[MAX_WORDS]; const int space_width = getCharWidth(' '); i = 0; while (i < word_count) { char *substr = words[i++]; int substr_width = getStringWidth(substr); while (i < word_count) { int word_width = getStringWidth(words[i]); if ((substr_width + space_width + word_width) >= width) break; substr_width += word_width + space_width; *(words[i]-1) = ' '; // Convert 0 byte back to space i++; } substrings[line_count] = substr; substr_widths[line_count++] = substr_width; if (max_width < substr_width) max_width = substr_width; height += getStringHeight(substr); } if (y > dst_height - height) { y = dst_height - height; } if (center) { max_width = (max_width + 1) / 2; x = left + width / 2; if (x < left + max_width) x = left + max_width; if (x > right - max_width) x = right - max_width; for (i = 0; i < line_count; i++) { drawSubstring(substrings[i], buffer, dst_width, x - substr_widths[i] / 2, y); y += getStringHeight(substrings[i]); } } else { if (x > dst_width - max_width) x = dst_width - max_width; for (i = 0; i < line_count; i++) { drawSubstring(substrings[i], buffer, dst_width, x, y); y += getStringHeight(substrings[i]); } } free(s); }
uint16 Font::getStringWidth(const char *str) { return getStringWidth(str, strlen(str)); }
Common::String Font::handleEllipsis(const Common::String &input, int w) const { Common::String s = input; int width = getStringWidth(s); if (width > w && s.hasSuffix("...")) { // String is too wide. Check whether it ends in an ellipsis // ("..."). If so, remove that and try again! s.deleteLastChar(); s.deleteLastChar(); s.deleteLastChar(); width = getStringWidth(s); } if (width > w) { Common::String str; // String is too wide. So we shorten it "intelligently" by // replacing parts of the string by an ellipsis. There are // three possibilities for this: replace the start, the end, or // the middle of the string. What is best really depends on the // context; but unless we want to make this configurable, // replacing the middle seems to be a good compromise. const int ellipsisWidth = getStringWidth("..."); // SLOW algorithm to remove enough of the middle. But it is good enough // for now. const int halfWidth = (w - ellipsisWidth) / 2; int w2 = 0; Common::String::unsigned_type last = 0; uint i = 0; for (; i < s.size(); ++i) { const Common::String::unsigned_type cur = s[i]; int charWidth = getCharWidth(cur) + getKerningOffset(last, cur); if (w2 + charWidth > halfWidth) break; last = cur; w2 += charWidth; str += cur; } // At this point we know that the first 'i' chars are together 'w2' // pixels wide. We took the first i-1, and add "..." to them. str += "..."; last = '.'; // The original string is width wide. Of those we already skipped past // w2 pixels, which means (width - w2) remain. // The new str is (w2+ellipsisWidth) wide, so we can accommodate about // (w - (w2+ellipsisWidth)) more pixels. // Thus we skip ((width - w2) - (w - (w2+ellipsisWidth))) = // (width + ellipsisWidth - w) int skip = width + ellipsisWidth - w; for (; i < s.size() && skip > 0; ++i) { const Common::String::unsigned_type cur = s[i]; skip -= getCharWidth(cur) + getKerningOffset(last, cur); last = cur; } // Append the remaining chars, if any for (; i < s.size(); ++i) { str += s[i]; } return str; } else { return s; } }
void HUD::drawGameOver(int score, int multiplier, int timeRemaining, int sizeX, int sizeY) { drawHUD(score, multiplier, timeRemaining); //Draw a transparent grey quad over the screen to dim for pausing //Set colour glColor4f(0.4f,0.4f,0.4f,0.9f); glBegin(GL_QUADS); glVertex2f(0,0); glVertex2f(0,sizeY); glVertex2f(sizeX, sizeY); glVertex2f(sizeX, 0); glEnd(); //set the colour back to normal glColor4fv(scoreTextColour); //write "TIME OVER" printWithColour(pauseFont, (sizeX/2)-(pauseFont.h*3),sizeY/2+(sizeY/3),scoreTextColour,"TIME OVER"); if(GO_scoreTimer > 0)GO_scoreTimer--;//count down until we should show the score if(GO_scoreTimer == 0) //once our artificial interval is over { //If the scoretimer has hit zero we can display the score //ticking up to the score the player has reached char scoreAstext[10]; sprintf(scoreAstext,"%.0f",GO_score); //We want to align the score RIGHT, as is the tradition with scores. So that the text moves //LEFT as the number of digits increases. float offset = getStringWidth(GO_scoreFont,0,0,scoreAstext); //UPDATE: SKIPPING FUNCTIONALITY BE HERE //by way of a skipping flag that is waved by the mainclass via a public if(skipGO_flag)//false by default { GO_score = score;//auto-meet the conditions to end the "ticking-up" loop } if(GO_score<score) {//If GO_score is less than score, //print the score white as it is clocking up printWithColour(scoreTextFont,(sizeX/2)-100, (sizeY/2)+(sizeY/3)-((GO_scoreFont.h*2)-5),GO_scoreColour, "SCORE:"); printWithColour(GO_scoreFont, (sizeX/2)+(sizeX/3)-offset,(sizeY/2)+(sizeY/3)-((GO_scoreFont.h*2)-5),GO_scoreColour,scoreAstext); float scorePerFrame = score/120;//continue adding to GO_score GO_score += scorePerFrame;//divided by the number of frames we want it to take }else{ //if the GO_score has reached its destination, still draw it, //but start pulsating //ALSO throughout the 'clocking up', GO_Score can become //distorted slightly through rounding up and whatnot. //So once we're up here, let's just draw the ACTUAL score. char actualScoreAsText[10]; _itoa(score, actualScoreAsText, 10); printWithColour(scoreTextFont,(sizeX/2)-100, (sizeY/2)+(sizeY/3)-((GO_scoreFont.h*2)-5),GO_scoreColour, "SCORE:"); printWithColour(GO_scoreFont, (sizeX/2)+(sizeX/3)-offset,(sizeY/2)+(sizeY/3)-((GO_scoreFont.h*2)-5),GO_scoreColour,actualScoreAsText); pulsateColour(white,blue, GO_scoreColour, CS_GO_score, 20); //retry float retryOffset = getStringWidth(GO_retryFont,0,0,"Press 'r' to retry")/2; float quitOffset = getStringWidth(GO_retryFont,0,0,"Press 'q' to return to the menu")/2; printWithColour(GO_retryFont, (sizeX/2) - retryOffset,100, white,"Press 'r' to retry"); printWithColour(GO_retryFont, (sizeX/2) - quitOffset,100-(GO_retryFont.h+3), white,"Press 'q' to return to the menu"); } } }
CCMutableArray<StringLabel*>* TagString::parse( bool useTag ) { string cut = ""; int start_idx = 0; float zen_width = 0; // 全角幅を取得 { StringLabel* label_zen = StringLabel::init( "1", ccc3(0,0,0), baseFontSize ); #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) zen_width = (int)(label_zen->getContentSize().width); #else zen_width = label_zen->getContentSize().width; #endif } ///////////////////////////////////////////// // 変数タグの置換 start_idx = 0; for( ;; ) { int tag_start1 = tagStr.find( "<param=", start_idx ); if( tag_start1 == string::npos ) break; int tag_start2 = tagStr.find( ">", tag_start1 ); string param_str = tagStr.substr( tag_start1+7, tag_start2-(tag_start1+7) ); // 変数の値取得 string value = ParamList::shared()->getValue( param_str ); if( !value.empty() ) { // 文字列の置換 tagStr.replace( tag_start1, tag_start2-tag_start1+1, value ); start_idx = 0; continue; } start_idx = tag_start2 + 1; } //tagStr->getStringWidth() ///////////////////////////////////////////// // 自動改行チェック if( autoKaigyouFlg ) { vector< string > list = StringComparator::comparate( tagStr ); bool tag_start = false; float total_size = 0; string conv_str = ""; for( int i = 0; i < list.size(); i++ ) { if (useTag) { if( list[i] == "<" ) { tag_start = true; } if( list[i] == ">" ) { tag_start = false; conv_str.append( list[i] ); continue; } if( tag_start ) { // 改行チェック if( list[i] == "b" ) { if( list[i+1] == "r" ) { total_size = 0; } } conv_str.append( list[i] ); continue; } } float strw = 0; // 半角 if( list[i].length() == 1 ) { StringLabel* label = StringLabel::init( list[i].c_str(), ccc3(0,0,0), baseFontSize ); strw = label->getContentSize().width; } // 全角 else { strw = zen_width; } total_size += strw; // 改行を挿入 if( width > 0 && total_size > width ) { //CCLog( "kaigyou2 total_size=%d", total_size ); // 改行コードを入れる conv_str.append( "<br>" ); total_size = strw; } else { if (list[i] == "\n") total_size = 0; } conv_str.append( list[i] ); } tagStr = conv_str; } ///////////////////////////////////////////// // 改行、カラー、フォントサイズ、アンカー解析 int line = 0; start_idx = 0; int active_anchor = 0; int active_font_size = baseFontSize; ccColor3B active_color = baseColor; //CCLog( "tag_str=%s", tagStr.c_str() ); bool brflg = false; for( ;; ) { // 開始タグ判定 int tag_start = tagStr.find( "<", start_idx ); if( tag_start != string::npos && useTag ) { // 表示文字列を取得 cut = tagStr.substr( start_idx, tag_start - (start_idx) ); //CCLog( "cut=%s actuve=%d", cut.c_str(), active_anchor ); if( !cut.empty() || brflg ) { parseList->addObject( new ColorString( cut, active_color, active_font_size, line, active_anchor ) ); } int tag_close = tagStr.find( ">", tag_start ); // タグ文字列取得 string param_str = tagStr.substr( tag_start+1, tag_close-(tag_start+1) ); // アンカー if( param_str.find( "left" ) != string::npos ) { active_anchor = ALIGN_LEFT; } if( param_str.find( "center" ) != string::npos ) { active_anchor = ALIGN_CENTER; } if( param_str.find( "right" ) != string::npos ) { active_anchor = ALIGN_RIGHT; } // 改行 if( param_str.find( "br" ) != string::npos ) { line += 1; brflg = true; } // カラー設定 if( param_str.find( "color=" ) != string::npos ) { // 色情報の切り出し string color_str = param_str.substr( 6, param_str.length()-6 ); // 色成分に分解 char *csv = const_cast<char*>( color_str.c_str() ); int red = CommonUtils::StrToInt( strtok( csv, ":" ) ); int green = CommonUtils::StrToInt( strtok( NULL, ":" ) ); int blue = CommonUtils::StrToInt( strtok( NULL, ":" ) ); active_color = ccc3( red, green, blue ); } // フォントサイズ if( param_str.find( "size=" ) != string::npos ) { string size_str = param_str.substr( 5, param_str.length()-5 ); active_font_size = CommonUtils::StrToInt( size_str ); } // カラー 終了タグ if( param_str.find( "/color" ) != string::npos ) { active_color = baseColor; } // アンカー 終了タグ if( param_str.find( "/center" ) != string::npos ) { active_anchor = ALIGN_LEFT; } if( param_str.find( "/right" ) != string::npos ) { active_anchor = ALIGN_LEFT; } // フォントサイズ 終了タグ if( param_str.find( "/size" ) != string::npos ) { active_font_size = baseFontSize; } start_idx = tag_close + 1; } else { /* for( ;; ) { // 改行コードがある場合 tag_start = tagStr.find( "\n", start_idx ); if (tag_start != string::npos) { // 表示文字列を取得 cut = tagStr.substr( start_idx, tag_start - (start_idx) ); if( !cut.empty() ) { parseList->addObject( new ColorString( cut, active_color, active_font_size, line, active_anchor ) ); line += 1; } start_idx = tag_start + 1; } else { break; } } */ cut = tagStr.substr( start_idx, tagStr.length() - (start_idx) ); if( !cut.empty() ) { //CCLog( "cut=%s", cut.c_str() ); parseList->addObject( new ColorString( cut, active_color, active_font_size, line, active_anchor ) ); } break; } } int linecnt = getLineCount(); float basex = 0; float basey = 0; // アライン設定 if( baseAlign == TEXT_ALIGN_CENTER_TOP ) { basex = ( ( width - getStringWidth() )/2 ); } if( baseAlign == TEXT_ALIGN_RIGHT_TOP ) { basex = width - getStringWidth(); } if( baseAlign == TEXT_ALIGN_LEFT_MIDDLE ) { basey = ( ( height - getStringHeight() )/2 ); } if( baseAlign == TEXT_ALIGN_CENTER_MIDDLE ) { basex = ( ( width - getStringWidth() )/2 ); basey = ( ( height - getStringHeight() )/2 ); } if( baseAlign == TEXT_ALIGN_RIGHT_MIDDLE ) { basex = width - getStringWidth(); basey = ( ( height - getStringHeight() )/2 ); } if( baseAlign == TEXT_ALIGN_CENTER_BOTTOM ) { basex = ( ( width - getStringWidth() )/2 ); basey = height - getStringHeight(); } if( baseAlign == TEXT_ALIGN_RIGHT_BOTTOM ) { basex = width - getStringWidth(); basey = height - getStringHeight(); } if( baseAlign == TEXT_ALIGN_LEFT_BOTTOM ) { basey = height - getStringHeight(); } float dispx = basex; float dispy = basey; // 返却用のリスト CCMutableArray<StringLabel*>* ret = new CCMutableArray<StringLabel*>; ret->autorelease(); // ラベルを生成 for( int i = 0; i < linecnt; i++ ) { CCMutableArray<ColorString*> *list = getStringList( i ); float lh = getStringLineHeight( i ); float lw = getStringLineWidth( i ); // 下合わせ dispy += lh; for( int j = 0; j < list->count(); j++ ) { ColorString* cstr = list->getObjectAtIndex( j ); // アライン if( j == 0 ) { if( cstr->getAlign() == ALIGN_LEFT ) dispx = 0; if( cstr->getAlign() == ALIGN_CENTER ) dispx = ((width-lw)/2); if( cstr->getAlign() == ALIGN_RIGHT ) dispx = width - lw; } // テキストを設定 StringLabel* label = cstr->getStrLabel(); label->setAlign( TEXT_ALIGN_LEFT_BOTTOM ); //label->setPosition( dispx, dispy ); label->setOffsetX( dispx ); label->setOffsetY( dispy ); ret->addObject( label ); // ラベルサイズ取得 CCSize size = label->getContentSize(); dispx += size.width; } dispx = basex; } return ret; }
void Font::drawString(Surface *dst, const Common::String &sOld, int x, int y, int w, uint32 color, TextAlign align, int deltax, bool useEllipsis) const { assert(dst != 0); const int leftX = x, rightX = x + w; uint i; Common::String s = sOld; int width = getStringWidth(s); Common::String str; if (useEllipsis && width > w && s.hasSuffix("...")) { // String is too wide. Check whether it ends in an ellipsis // ("..."). If so, remove that and try again! s.deleteLastChar(); s.deleteLastChar(); s.deleteLastChar(); width = getStringWidth(s); } if (useEllipsis && width > w) { // String is too wide. So we shorten it "intelligently" by // replacing parts of the string by an ellipsis. There are // three possibilities for this: replace the start, the end, or // the middle of the string. What is best really depends on the // context; but unless we want to make this configurable, // replacing the middle seems to be a good compromise. const int ellipsisWidth = getStringWidth("..."); // SLOW algorithm to remove enough of the middle. But it is good enough // for now. const int halfWidth = (w - ellipsisWidth) / 2; int w2 = 0; uint last = 0; for (i = 0; i < s.size(); ++i) { const uint cur = s[i]; int charWidth = getCharWidth(cur) + getKerningOffset(last, cur); if (w2 + charWidth > halfWidth) break; last = cur; w2 += charWidth; str += cur; } // At this point we know that the first 'i' chars are together 'w2' // pixels wide. We took the first i-1, and add "..." to them. str += "..."; last = '.'; // The original string is width wide. Of those we already skipped past // w2 pixels, which means (width - w2) remain. // The new str is (w2+ellipsisWidth) wide, so we can accommodate about // (w - (w2+ellipsisWidth)) more pixels. // Thus we skip ((width - w2) - (w - (w2+ellipsisWidth))) = // (width + ellipsisWidth - w) int skip = width + ellipsisWidth - w; for (; i < s.size() && skip > 0; ++i) { const uint cur = s[i]; skip -= getCharWidth(cur) + getKerningOffset(last, cur); last = cur; } // Append the remaining chars, if any for (; i < s.size(); ++i) { str += s[i]; } width = getStringWidth(str); } else { str = s; } if (align == kTextAlignCenter) x = x + (w - width)/2; else if (align == kTextAlignRight) x = x + w - width; x += deltax; uint last = 0; for (i = 0; i < str.size(); ++i) { const uint cur = str[i]; x += getKerningOffset(last, cur); last = cur; w = getCharWidth(cur); if (x+w > rightX) break; if (x >= leftX) drawChar(dst, str[i], x, y, color); x += w; } }