static void initStrings(ModeInfo * mi) { imagestruct *ip = &ims[MI_SCREEN(mi)]; char *p, *p2, *p3, buf[BUFSIZ]; int height, w, i, j; p = strncpy(buf, message, BUFSIZ); while (strlen(p) > 0) { p2 = p + strlen(p) - 1; if (*p2 == '\n') *p2 = 0; else break; } for (height = 0; p && height < MAXLINES; height++) { if (!(p2 = (char *) strchr(p, '\n')) || !p2[1]) { p2 = p + strlen(p); } /* p2 now points to the first '\n' */ *p2 = 0; for (w = 0; w < p2 - p; w++) { p3 = p + w; if (*p3 == '\t') /* this should be improved */ *p3 = ' '; } (void) strncpy(ip->strnew[height], p, MAXWIDTH - 1); ip->strnew[height][MAXWIDTH - 1] = '\0'; if (p == p2) break; p = p2 + 1; } ip->lines = height; j = 0; for (i = 0; i < ip->lines; i++) { if (ip->strnew[i] && *(ip->strnew[i])) { ip->textWidth[i] = getTextWidth(ip->strnew[i]) + getTextWidth((char *) "I"); /* add a little more to give some border room */ if (ip->textWidth[i] > ip->textWidth[j]) { j = i; } } ip->pixw = ip->textWidth[j]; } for (i = 0; i < ip->lines; i++) { ip->textStart[i] = (ip->pixw - ip->textWidth[i]) / 2; } ip->text_height = getFontHeight(mode_font); ip->pixh = ip->lines * ip->text_height; }
void ASFont::writeLine(Surface* surface, const std::string& text, int x, int y, HAlign halign) { switch (halign) { case HAlignLeft: break; case HAlignCenter: x -= getTextWidth(text) / 2; break; case HAlignRight: x -= getTextWidth(text); break; } writeLine(surface, text, x, y); }
/** * draws the caption of a button * @retval 0 or error number #TOUCHBUTTON_ERROR_CAPTION_TOO_LONG etc. */ void TouchButton::drawCaption(void) { mFlags |= FLAG_IS_ACTIVE; if (mCaptionSize > 0) { // dont render anything if caption size == 0 if (mCaption != NULL) { int tXCaptionPosition; int tYCaptionPosition; /* * Simple 2 line handling * 1. position first string in the middle of the box * 2. draw second string just below */ char * tPosOfNewline = strchr(mCaption, '\n'); int tCaptionHeight = getTextHeight(mCaptionSize); int tStringlength = strlen(mCaption); if (tPosOfNewline != NULL) { // assume 2 lines of caption tCaptionHeight = 2 * getTextHeight(mCaptionSize); tStringlength = (tPosOfNewline - mCaption); } int tLength = getTextWidth(mCaptionSize) * tStringlength; // try to position the string in the middle of the box if (tLength >= mWidthX) { // String too long here tXCaptionPosition = mPositionX; } else { tXCaptionPosition = mPositionX + ((mWidthX - tLength) / 2); } if (tCaptionHeight >= mHeightY) { // Font height to big tYCaptionPosition = mPositionY; } else { tYCaptionPosition = mPositionY + ((mHeightY - tCaptionHeight) / 2); } LocalDisplay.drawNCharacters(tXCaptionPosition, tYCaptionPosition, (char*) mCaption, getLocalTextSize(mCaptionSize), mCaptionColor, mButtonColor, tStringlength); if (tPosOfNewline != NULL) { // 2. line - position the string in the middle of the box again tStringlength = strlen(mCaption) - tStringlength - 1; tLength = getTextWidth(mCaptionSize) * tStringlength; tXCaptionPosition = mPositionX + ((mWidthX - tLength) / 2); LocalDisplay.drawNCharacters(tXCaptionPosition, tYCaptionPosition + getTextHeight(mCaptionSize), (tPosOfNewline + 1), getLocalTextSize(mCaptionSize), mCaptionColor, mButtonColor, tStringlength); } } } }
void Utils::drawAlignedText ( Adafruit_GFX &tft, const String &text, uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t color, unsigned char textsize, unsigned char alignMode ) { uint16_t textwidth = getTextWidth(text, textsize); uint16_t textx = 0; if (alignMode & HORZ_CENTER) textx = x + (width - textwidth)/2; else if (alignMode & HORZ_LEFT) textx = x; else textx = x + width - textwidth; uint16_t textheight = getTextHeight(text, textsize); uint16_t texty = 0; if (alignMode & VERT_CENTER) texty = y + (height - textheight)/2; else if (alignMode & VERT_TOP) texty = y; else texty = y + height - textheight; tft.setCursor(textx, texty); tft.setTextColor(color); tft.setTextSize(textsize); tft.print(text); }
/////////////////////////////////////////////////////////////// // Box2D Setup void GameObj::setupB2D(double x, double y) { b2BodyDef bodyDef; b2PolygonShape dynamicBox; b2FixtureDef fixtureDef; // if(objType == STATIC) { // bodyDef.type = b2_staticBody; // } else { bodyDef.type = b2_dynamicBody; // } bodyDef.position.Set(x, y); // bodyDef.linearVelocity(Util::meter2Pixel(5)); bodyDef.userData = this; body = settings->getWorld()->CreateBody(&bodyDef); dynamicBox.SetAsBox(Util::meter2Pixel(getTextWidth())/2,Util::meter2Pixel(getTextHeight())/2); // Define another box shape for our dynamic body. fixtureDef.shape = &dynamicBox; // Define the dynamic body fixture. fixtureDef.density = goSettings._density; // Set the box density to be non-zero, so it will be dynamic. fixtureDef.friction = goSettings._friction; // Override the default friction. fixtureDef.filter = getFixtureCollisionFilter(); // fixtureDef.filter.maskBits = getFixtureCollissionFilter().maskBits; body->SetLinearVelocity(b2Vec2(goSettings.getVelocityMax(), 0.0)); body->CreateFixture(&fixtureDef); // Add the shape to the body. }
void Font::writeLine(float x, float y, float z, const char *text, int count, Alignment alignment) { if (count <= 0) count = getTextLength(text); if (alignment == Alignment::CENTER) { float w = getTextWidth(text, count); x -= w / 2; } else if (alignment == Alignment::RIGHT) { float w = getTextWidth(text, count); x -= w; } beginRender(); writeInternal(x, y, z, text, count); endRender(); }
/** * draws the caption of a button * @retval 0 or error number #TOUCHBUTTON_ERROR_CAPTION_TOO_LONG etc. */ int TouchButton::drawCaption(void) { mFlags |= FLAG_IS_ACTIVE; int tRetValue = 0; if (mCaptionSize > 0) { // dont render anything if caption size == 0 if (mCaption != NULL) { int tXCaptionPosition; int tYCaptionPosition; // try to position the string in the middle of the box int tLength = getTextWidth(mCaptionSize) * strlen(mCaption); if (tLength >= mWidth) { // String too long here tXCaptionPosition = mPositionX; tRetValue = TOUCHBUTTON_ERROR_CAPTION_TOO_LONG; } else { tXCaptionPosition = mPositionX + ((mWidth - tLength) / 2); } if (mCaptionSize >= mHeight) { // Font height to big tYCaptionPosition = mPositionY; tRetValue = TOUCHBUTTON_ERROR_CAPTION_TOO_HIGH; } else { tYCaptionPosition = mPositionY + ((mHeight + getTextAscendMinusDescend(mCaptionSize)) / 2); } mDisplay->drawText(tXCaptionPosition, tYCaptionPosition, mCaption, mCaptionSize, mCaptionColor, mButtonColor); } } return tRetValue; }
void FlowArea::render(const xs::Point& pt, IRenderSystem* pRenderSystem) { if (mList.empty()) return; // render float x = pt.x; float y = (float)(pt.y + mRect.bottom); for (FlowItemList::iterator it=mList.begin(); it!=mList.end(); ++it) { FlowItem& item = (*it); float xx = x; float yy = (y - item.offY); // 动画效果居中 if(mIsEffect) { int w = getTextWidth(item.text,item.font); xx -=(w*item.scale/2); } ColorValue color = item.color; if( !mIsChangeA) color.a = 1.0f; if(mIsEffect) gGlobalClient->getFont(item.font)->render2dByScale(xx, yy, 1, color, item.text,item.scale); else gGlobalClient->getFont()->render2d(xx, yy, 1, color, item.text); } }
void Window::onPreferredSize(PreferredSizeEvent& ev) { Widget* manager = getManager(); if (m_isDesktop) { Rect cpos = manager->getChildrenBounds(); ev.setPreferredSize(cpos.w, cpos.h); } else { Size maxSize(0, 0); Size reqSize; UI_FOREACH_WIDGET(getChildren(), it) { Widget* child = *it; if (!child->isDecorative()) { reqSize = child->getPreferredSize(); maxSize.w = MAX(maxSize.w, reqSize.w); maxSize.h = MAX(maxSize.h, reqSize.h); } } if (hasText()) maxSize.w = MAX(maxSize.w, getTextWidth()); ev.setPreferredSize(this->border_width.l + maxSize.w + this->border_width.r, this->border_width.t + maxSize.h + this->border_width.b); }
bool ChoiceTask::init(AdventureScene* scene, SceneManager* smgr) { // 選択肢の描画位置を初期化 int i = 0; for (auto it = m_choices.begin(); it != m_choices.end(); it++, i++) { std::string choice_key = "choice_" + std::to_string(i); DrawableText* choice = dynamic_cast<DrawableText*>(scene->getDrawable(choice_key)); std::string window_key = "choice_window_" + std::to_string(i); DrawableImage* c_window = dynamic_cast<DrawableImage*>(scene->getDrawable(window_key)); choice->setText(it->first); int textWidth = getTextWidth(it->first, choice->getFontHandle()); int windowWidth = c_window->getWidth(); int textPosition = (textWidth > windowWidth) ? 280 : 275 + (windowWidth - textWidth)/2; choice->setPosition(textPosition, i * 400/m_choices.size() + 81); choice->setIsVisible(true); c_window->setPosition(275, i * 400/m_choices.size() + 76); c_window->setIsVisible(true); } m_cursor = 0; // カーソルの描画位置を初期化 setInitialzed(); return true; }
void GfxText32::drawTextBox() { if (_text.size() == 0) { return; } const char *text = _text.c_str(); const char *sourceText = text; int16 textRectWidth = _textRect.width(); _drawPosition.y = _textRect.top; uint charIndex = 0; if (getLongest(&charIndex, textRectWidth) == 0) { error("DrawTextBox GetLongest=0"); } charIndex = 0; uint nextCharIndex = 0; while (*text != '\0') { _drawPosition.x = _textRect.left; uint length = getLongest(&nextCharIndex, textRectWidth); int16 textWidth = getTextWidth(charIndex, length); if (_alignment == kTextAlignCenter) { _drawPosition.x += (textRectWidth - textWidth) / 2; } else if (_alignment == kTextAlignRight) { _drawPosition.x += textRectWidth - textWidth; } drawText(charIndex, length); charIndex = nextCharIndex; text = sourceText + charIndex; _drawPosition.y += _font->getHeight(); } }
void renderStrokeLineFit(float x, float y, float z, char* line, float width, float height, bool forCluster) { string string_line = ""; if (line != NULL) string_line += line; if (string_line != "") { float scalability; if (forCluster) scalability = 100; else scalability = 1; float textWidth; float size = 0.05f; bool fits = false; while (!fits && size < (0.18f*scalability)) { textWidth = getTextWidth(&string_line, size); if (textWidth > (width*0.9)) fits = true; else size += 0.01f; } // Call renderStroke //renderStrokeLine(x, y, z, line, size); renderStrokeStringAdl(x, y, z, string_line, size); } }
LineBreakInfo TextEngine::computeLineBreakInfo(string text, float fontPixelSize, int linePixelWidth) { vector<string> words = getWords(text); int n = words.size(); float spacePixelWidth = getTextWidth(" ", fontPixelSize); vector<vector<int>> lineCosts = computeLineCosts(words, fontPixelSize, n, linePixelWidth, spacePixelWidth); vector<int> startIndices = computeLineBreakStartIndices(lineCosts, n); vector<int> endPositions(n+1, 0); for(int i = startIndices.size()-1; i > 0 ;i--) { int cur = i; int start = startIndices[i]; while( start != i) i--; endPositions[i] = cur; } /// compute LineBreakInfo vector<int> lineBreaks; int curLineWidth = 0, maxLineWidth = 0; int charIndex = 0; for(int i = 0; i<words.size(); i++) { charIndex += (words[i].size()+1); curLineWidth = getTextWidth(words[i], fontPixelSize); int end = endPositions[i+1]; while( (i+1) < end) { i++; charIndex += (words[i].size()+1); curLineWidth += (spacePixelWidth + getTextWidth(words[i], fontPixelSize)); } lineBreaks.push_back(charIndex-1); maxLineWidth = max(maxLineWidth, curLineWidth); } if(!lineBreaks.empty()) lineBreaks.pop_back(); return LineBreakInfo(lineBreaks.size()+1, lineBreaks, maxLineWidth); }
int PrinceEngine::checkMob(Graphics::Surface *screen, Common::Array<Mob> &mobList, bool usePriorityList) { if (_mouseFlag == 0 || _mouseFlag == 3) { return -1; } Common::Point mousePos = _system->getEventManager()->getMousePos(); int mobNumber = getMob(mobList, usePriorityList, mousePos.x + _picWindowX, mousePos.y); if (mobNumber != -1) { Common::String mobName = mobList[mobNumber]._name; if (getLanguage() == Common::DE_DEU) { for (uint i = 0; i < mobName.size(); i++) { switch (mobName[i]) { case '\xc4': mobName.setChar('\x83', i); break; case '\xd6': mobName.setChar('\x84', i); break; case '\xdc': mobName.setChar('\x85', i); break; case '\xdf': mobName.setChar('\x7f', i); break; case '\xe4': mobName.setChar('\x80', i); break; case '\xf6': mobName.setChar('\x81', i); break; case '\xfc': mobName.setChar('\x82', i); break; } } } uint16 textW = getTextWidth(mobName.c_str()); uint16 x = mousePos.x - textW / 2; if (x > screen->w) { x = 0; } if (x + textW > screen->w) { x = screen->w - textW; } uint16 y = mousePos.y - _font->getFontHeight(); if (y > screen->h) { y = _font->getFontHeight() - 2; } _font->drawString(screen, mobName, x, y, screen->w, 216); } return mobNumber; }
uint FontHelper::getTextWidth(const string& text) { if (text.find("\n",0)!=string::npos) { vector<string> textArr; split(textArr,text,"\n"); return getTextWidth(&textArr); } else return getLineWidth(text); }
/** * Changes the string displayed on screen. * @param text Text string. */ void Text::setText(const std::wstring &text) { _text = text; processText(); // If big text won't fit the space, try small text if (_font == _big && getTextWidth() > getWidth() && _text[_text.size()-1] != L'.') { setSmall(); } }
void FontHelper::write(SDL_Surface* surface, const string& text, int x, int y, const unsigned short halign, const unsigned short valign) { switch (halign) { case HAlignCenter: x -= getTextWidth(text)/2; break; case HAlignRight: x -= getTextWidth(text); break; } switch (valign) { case VAlignMiddle: y -= getHalfHeight(); break; case VAlignBottom: y -= getHeight(); break; } write(surface, text, x, y); }
void renderStrokeLine(float x, float y, float z, char* line, float size) { string string_line(line); glPushMatrix(); glTranslatef(x - getTextWidth(&string_line, size) * 0.5f, y - (36.0f*size), z); //glRasterPos3f(x - getTextWidth(&string_line, size) * 0.5f, y - (36.0f*size), z); glScalef(size, size, 1.0f); for (unsigned int c = 0; line[c] != 0; c++) { glutStrokeCharacter(GLUT_STROKE_ROMAN, line[c]); //glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, line[c]); } glPopMatrix(); }
int XTextWidth(XFontStruct* font_struct, _Xconst char* string, int count) { // https://tronche.com/gui/x/xlib/graphics/font-metrics/XTextWidth.html char* text = decodeString(string, count); if (text == NULL) { LOG("Out of memory: Failed to allocate memory in XTextWidth! " "Returning max width of font.\n"); return font_struct->max_bounds.rbearing * count; } int width = getTextWidth(font_struct, text); free(text); return width; }
/********************************************* Status bar **********************************************/ void App::drawStatusBar(){ //Set stuff to make fonts work glEnable(GL_TEXTURE_2D); glColor3f(1,1,1); glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); //Text glColor4f(1,1,1,1); if(fGUITimeout <= 0.0f){ /* if(!isConnected()){ writeTextCentered(iScreenX / 2, iScreenY - 30, "Press any key to display the GUI, \ then use the Servers button to connect to a server"); } */ }else{ writeText(10, 7, "%d fps, %d particles, %0.1f uptime", iFPS, ps()->getActive(), fUptime); if(isConnected()){ //Update the text at the bottom of the screen float w = getTextWidth(mStatusString.c_str()) + 10; writeText(iScreenX - w, iScreenY - 20, mStatusString.c_str()); string s = "Connected to " + mServerAddr + ":" + toString(iServerPort); w = getTextWidth(s.c_str()) + 10; writeText(iScreenX - w, iScreenY - 40, s.c_str()); } } }
void RAttributeEntity::print(QDebug dbg) const { dbg.nospace() << "RAttributeEntity("; REntity::print(dbg); dbg.nospace() << ", alignmentPoint: " << getAlignmentPoint() << ", position: " << getPosition() << ", text: " << getPlainText() << ", tag: " << getTag() << ", block reference ID: " << getParentId() << ", textHeight: " << getTextHeight() << ", textWidth: " << getTextWidth() << ", drawingDirection: " << getDrawingDirection() << ")"; }
void ShowGeometry::update(int x, int y) { char string[20]; sprintf(string, "%d %d", x, y); int width = getTextWidth(string, strlen(string)) + 8; #ifdef CONFIG_USE_XFT int height = m_font->ascent + m_font->descent + 8; #else int height = m_font[screen()]->ascent + m_font[screen()]->descent + 8; #endif int mx = DisplayWidth (display(), screen()) - 1; int my = DisplayHeight(display(), screen()) - 1; XMoveResizeWindow(display(), m_window[screen()], #if CONFIG_GEOMETRY_X_POS < 0 0 #elif CONFIG_GEOMETRY_X_POS > 0 (mx - width) #else (mx - width) / 2 #endif , #if CONFIG_GEOMETRY_X_POS < 0 0 #elif CONFIG_GEOMETRY_X_POS > 0 (my - height) #else (my - height) / 2 #endif , width, height); XClearWindow(display(), m_window[screen()]); XMapRaised(display(), m_window[screen()]); #ifdef CONFIG_USE_XFT XftDrawStringUtf8(m_xftDraw[screen()], &m_xftColour[screen()], m_font, 4, 4 + m_font->ascent, (FcChar8 *)string, strlen(string)); #else XDrawString(display(), m_window[screen()], Border::drawGC(m_windowManager,screen()), 4, 4 + m_font[screen()]->ascent, string, strlen(string)); #endif }
void Character::renderNameAndMessages() const { if(isSeen) { vPoint pos = Master::getInstance().getScreenPosition(position.x, position.y, Master::getInstance().View); sf::Text text; text.setCharacterSize(11); text.setString(name); text.setColor(sf::Color::White); int nameTextX = int(pos.x-getTextWidth(text)/2.f*Master::getInstance().View.distance); int nameTextY = int(pos.y-text.getLocalBounds().height/2.f*Master::getInstance().View.distance-(CHARACTER_RADIUS+10)*Master::getInstance().View.distance); float nameTextWidth = getTextWidth(text); text.setPosition(nameTextX, nameTextY); window.draw(text); char health[100]; sprintf(health, "%d / %d", param[CHARACTER_PARAM_HEALTH], param[CHARACTER_PARAM_MAX_HEALTH]); text.setCharacterSize(8); text.setString(health); text.setColor(sf::Color(220, 50, 50)); text.setPosition(nameTextX+int((nameTextWidth-getTextWidth(text))/2.f), nameTextY-int(10.f*Master::getInstance().View.distance)); window.draw(text); text.setCharacterSize(11); int messageOffsetY = messageOverHead.size()*10; for(std::list <MessageOverHeadClass>::const_iterator it=messageOverHead.begin(); it!=messageOverHead.end(); ++it) { text.setString(it->message); text.setColor(sf::Color(230, 230, 230, (int)it->alpha)); text.setPosition(nameTextX+int((nameTextWidth-getTextWidth(text))/2.f), nameTextY-int(10.f*Master::getInstance().View.distance)-10-messageOffsetY); window.draw(text); messageOffsetY -= 10; } } }
void Font::write(float x, float y, float z, const char *text, int count, Alignment alignment) { if (count <= 0) count = getTextLength(text); // Get first line int pos = 0; int len = findTextChar(text, pos, count, '\n'); if (len == -1) len = count; beginRender(); while (pos < count) { float cx = x; if (alignment == Alignment::CENTER) { float w = getTextWidth(&text[pos], len); cx -= w / 2; } else if (alignment == Alignment::RIGHT) { float w = getTextWidth(&text[pos], len); cx -= w; } writeInternal(cx, y, z, &text[pos], len); y -= getLineHeight(); // Get next line pos += len; int ch = getTextChar(text, pos, &pos); if (ch == '\n') { len = findTextChar(text, pos, count, '\n'); if (len == -1) len = count - pos; else len = len - pos; } } endRender(); }
void FontHelper::write(SDL_Surface* surface, vector<string> *text, int x, int y, const unsigned short halign, const unsigned short valign) { switch (valign) { case VAlignMiddle: y -= getHalfHeight()*text->size(); break; case VAlignBottom: y -= getHeight()*text->size(); break; } for (uint i=0; i<text->size(); i++) { int ix = x; switch (halign) { case HAlignCenter: ix -= getTextWidth(text->at(i))/2; break; case HAlignRight: ix -= getTextWidth(text->at(i)); break; } write(surface, text->at(i), x, y+getHeight()*i); } }
void UninstallerShortcutsListbox::updateListbox() const { SendMessage(m_listbox, WM_SETREDRAW, FALSE, 0); ListBox_ResetContent(m_listbox); size_t maxWidth = 0; for (const wstring& file : m_files) { ListBox_AddString(m_listbox, file.data()); maxWidth = __max(maxWidth, file.size()); } ListBox_SetHorizontalExtent(m_listbox, getTextWidth(m_dialogbox, maxWidth)); SendMessage(m_listbox, WM_SETREDRAW, TRUE, 0); RedrawWindow(m_listbox, NULL, NULL, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN); }
int XTextWidth16(XFontStruct* font_struct, _Xconst XChar2b* string, int count) { // https://tronche.com/gui/x/xlib/graphics/font-metrics/XTextWidth16.html // TODO: Rethink this size_t length; char* text = decodeMbString((const wchar_t *) string, &length); if (text == NULL) { LOG("Out of memory: Failed to allocate memory in %s! " "Returning max width of font.\n", __func__); return font_struct->max_bounds.rbearing * count; } int width = getTextWidth(font_struct, text); free(text); return width; }
vector<vector<int>> TextEngine::computeLineCosts(vector<string> words, float fontPixelSize, int n, int linePixelWidth, float spacePixelWidth) { vector<vector<int>> lineCosts(n+1, vector<int>(n+1, INT_MAX)); for(int y = 1; y <= n; y++) { float wordPixelWidth = getTextWidth(words[y-1], fontPixelSize); int cost = linePixelWidth - wordPixelWidth; lineCosts[y][y] = cost * cost * cost; for(int x = y+1; x <= n; x++) { wordPixelWidth = getTextWidth(words[x-1], fontPixelSize); cost -= (wordPixelWidth + spacePixelWidth); if(cost < 0) break; else lineCosts[y][x] = cost * cost * cost; } } lineCosts[n][n] = 0; return lineCosts; }
void Font::draw(const Common::String &text, Graphics::Surface &surface, int x, int y) { if (!_data) { return; } x = CLIP(x, 0, _screenWidth - getTextWidth(text) + 1); y = CLIP(y, 0, _screenHeight - _maxHeight); const char *character = text.c_str(); while (*character != 0) { drawCharacter(*character, surface, x, y); x += _spacing1 + _characters[*character + 1]._width; character++; } }
void ScrollingTextRenderer::readScript(const std::string& relPath) { std::ifstream ifs(Path::getFullPath(relPath)); std::string dummy, line; while (ifs >> dummy) { if (getTextWidth(line + dummy) >= LINE_SIZE) { addLine(line); line = dummy + ' '; } else { line += dummy + ' '; } } addLine(line); }