/** * 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 ofxBlackText::loadTextFrom(const string& path){ ifstream fs( ofToDataPath(path).c_str()); if (fs.is_open()){ // agregar font != NULL string palabra; vector <string> palabras; palabras.clear(); // Load the data to a temporal vector call ´file´ while(!(fs >> palabra).fail()) palabras.push_back(palabra); fs.close(); wordBlock tmpWord; for (int i = 0; i < palabras.size(); i++){ tmpWord.rawWord = palabras[i]; tmpWord.width = defaultFont->stringWidth(tmpWord.rawWord); tmpWord.height = defaultFont->stringHeight(tmpWord.rawWord); tmpWord.color.r = tmpWord.color.g = tmpWord.color.b = 255; words.push_back(tmpWord); //add spaces into the words vector if it is not the last word. if (i != palabras.size()) words.push_back(blankSpaceWord); } for(int i=0;i < words.size(); i++) ofLog(OF_LOG_VERBOSE, "Loaded word: %i, %s\n", i, words[i].rawWord.c_str()); wrapTextForceLines(1); wrapTextX(width); // Setea el largo height = getTextHeight(); }
/** * 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() || getTextHeight() > getHeight()) && _text[_text.size()-1] != L'.') { setSmall(); } }
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 Slider::onPreferredSize(PreferredSizeEvent& ev) { int min_w = getFont()->textLength(convertValueToText(m_min)); int max_w = getFont()->textLength(convertValueToText(m_max)); int w = MAX(min_w, max_w); int h = getTextHeight(); w += border().width(); h += border().height(); ev.setPreferredSize(w, h); }
void Label::onPreferredSize(PreferredSizeEvent& ev) { gfx::Size sz(0, 0); if (hasText()) { // Labels are not UIString sz.w = getFont()->textLength(getText().c_str()); sz.h = getTextHeight(); } sz.w += border().width(); sz.h += border().height(); ev.setPreferredSize(sz); }
bool TextBox::onProcessMessage(Message* msg) { switch (msg->type()) { case kKeyDownMessage: if (hasFocus()) { View* view = View::getView(this); if (view) { gfx::Rect vp = view->getViewportBounds(); gfx::Point scroll = view->getViewScroll(); int textheight = getTextHeight(); switch (static_cast<KeyMessage*>(msg)->scancode()) { case kKeyLeft: scroll.x -= vp.w/2; view->setViewScroll(scroll); break; case kKeyRight: scroll.x += vp.w/2; view->setViewScroll(scroll); break; case kKeyUp: scroll.y -= vp.h/2; view->setViewScroll(scroll); break; case kKeyDown: scroll.y += vp.h/2; view->setViewScroll(scroll); break; case kKeyPageUp: scroll.y -= (vp.h-textheight); view->setViewScroll(scroll); break; case kKeyPageDown: scroll.y += (vp.h-textheight); view->setViewScroll(scroll); break; case kKeyHome: scroll.y = 0; view->setViewScroll(scroll); break; case kKeyEnd: scroll.y = getBounds().h - vp.h; view->setViewScroll(scroll); break; default: return Widget::onProcessMessage(msg); } } return true; } break; case kMouseDownMessage: { View* view = View::getView(this); if (view) { captureMouse(); m_oldPos = static_cast<MouseMessage*>(msg)->position(); set_mouse_cursor(kScrollCursor); return true; } break; } case kMouseMoveMessage: { View* view = View::getView(this); if (view && hasCapture()) { gfx::Point scroll = view->getViewScroll(); gfx::Point newPos = static_cast<MouseMessage*>(msg)->position(); scroll += m_oldPos - newPos; view->setViewScroll(scroll); m_oldPos = newPos; } break; } case kMouseUpMessage: { View* view = View::getView(this); if (view && hasCapture()) { releaseMouse(); set_mouse_cursor(kArrowCursor); return true; } break; } case kMouseWheelMessage: { View* view = View::getView(this); if (view) { gfx::Point scroll = view->getViewScroll(); scroll += static_cast<MouseMessage*>(msg)->wheelDelta() * getTextHeight()*3; view->setViewScroll(scroll); } break; } } return Widget::onProcessMessage(msg); }
/** * Creates a dimensioning line (line with one, two or no arrows and a text). * * @param forceAutoText Automatically reposition the text label. */ void RS_Dimension::updateCreateDimensionLine(const RS_Vector& p1, const RS_Vector& p2, bool arrow1, bool arrow2, bool forceAutoText) { // general scale (DIMSCALE) double dimscale = getGeneralScale(); // text height (DIMTXT) double dimtxt = getTextHeight()*dimscale; // text distance to line (DIMGAP) double dimgap = getDimensionLineGap()*dimscale; // length of dimension line: double distance = p1.distanceTo(p2); // arrow size: double arrowSize = getArrowSize()*dimscale; // do we have to put the arrows outside of the line? bool outsideArrows = (distance<arrowSize*2.5); // arrow angles: double arrowAngle1, arrowAngle2; // Create dimension line: RS_Line* dimensionLine = new RS_Line(this, RS_LineData(p1, p2)); dimensionLine->setPen(RS_Pen(RS2::FlagInvalid)); dimensionLine->setLayer(NULL); addEntity(dimensionLine); if (outsideArrows==false) { arrowAngle1 = dimensionLine->getAngle2(); arrowAngle2 = dimensionLine->getAngle1(); } else { arrowAngle1 = dimensionLine->getAngle1(); arrowAngle2 = dimensionLine->getAngle2(); // extend dimension line outside arrows RS_Vector dir; dir.setPolar(arrowSize*2, arrowAngle2); dimensionLine->setStartpoint(p1 + dir); dimensionLine->setEndpoint(p2 - dir); } double dimtsz=getTickSize()*dimscale; if(dimtsz < 0.01) { //display arrow // Arrows: RS_SolidData sd; RS_Solid* arrow; if (arrow1) { // arrow 1 arrow = new RS_Solid(this, sd); arrow->shapeArrow(p1, arrowAngle1, arrowSize); arrow->setPen(RS_Pen(RS2::FlagInvalid)); arrow->setLayer(NULL); addEntity(arrow); } if (arrow2) { // arrow 2: arrow = new RS_Solid(this, sd); arrow->shapeArrow(p2, arrowAngle2, arrowSize); arrow->setPen(RS_Pen(RS2::FlagInvalid)); arrow->setLayer(NULL); addEntity(arrow); } }else{ //display ticks // Arrows: RS_Line* tick; RS_Vector tickVector; tickVector.setPolar(dimtsz,arrowAngle1 + M_PI*0.25); //tick is 45 degree away if (arrow1) { // tick 1 tick = new RS_Line(this, p1-tickVector, p1+tickVector); tick->setPen(RS_Pen(RS2::FlagInvalid)); tick->setLayer(NULL); addEntity(tick); } if (arrow2) { // tick 2: tick = new RS_Line(this, p2-tickVector, p2+tickVector); tick->setPen(RS_Pen(RS2::FlagInvalid)); tick->setLayer(NULL); addEntity(tick); } } // Text label: RS_MTextData textData; RS_Vector textPos; double dimAngle1 = dimensionLine->getAngle1(); double textAngle; bool corrected=false; if (getAlignText()) textAngle =0.0; else textAngle = RS_Math::makeAngleReadable(dimAngle1, true, &corrected); if (data.middleOfText.valid && !forceAutoText) { textPos = data.middleOfText; } else { textPos = dimensionLine->getMiddlePoint(); if (!getAlignText()) { RS_Vector distV; // rotate text so it's readable from the bottom or right (ISO) // quadrant 1 & 4 if (corrected) { distV.setPolar(dimgap + dimtxt/2.0, dimAngle1-M_PI/2.0); } else { distV.setPolar(dimgap + dimtxt/2.0, dimAngle1+M_PI/2.0); } // move text away from dimension line: textPos+=distV; } //// the next update should still be able to adjust this //// auto text position. leave it invalid data.middleOfText = textPos; } textData = RS_MTextData(textPos, dimtxt, 30.0, RS_MTextData::VAMiddle, RS_MTextData::HACenter, RS_MTextData::LeftToRight, RS_MTextData::Exact, 1.0, getLabel(), "standard", textAngle); RS_MText* text = new RS_MText(this, textData); // move text to the side: RS_Vector distH; if (text->getUsedTextWidth()>distance) { distH.setPolar(text->getUsedTextWidth()/2.0 +distance/2.0+dimgap, textAngle); text->move(distH); } text->setPen(RS_Pen(RS2::FlagInvalid)); text->setLayer(NULL); //horizontal text, split dimensionLine if (getAlignText()) { double w =text->getUsedTextWidth()/2+dimgap; double h = text->getUsedTextHeight()/2+dimgap; RS_Vector v1 = textPos - RS_Vector(w, h); RS_Vector v2 = textPos + RS_Vector(w, h); RS_Line l[] = { RS_Line(NULL, RS_LineData(v1, RS_Vector(v2.x, v1.y))), RS_Line(NULL, RS_LineData(RS_Vector(v2.x, v1.y), v2)), RS_Line(NULL, RS_LineData(v2, RS_Vector(v1.x, v2.y))), RS_Line(NULL, RS_LineData(RS_Vector(v1.x, v2.y), v1)) }; RS_VectorSolutions sol1, sol2; int inters= 0; do { sol1 = RS_Information::getIntersection(dimensionLine, &(l[inters++]), true); } while (!sol1.hasValid() && inters < 4); if (!sol1.hasValid()) { do { sol2 = RS_Information::getIntersection(dimensionLine, &(l[inters++]), true); } while (!sol2.hasValid() && inters < 4); } //are text intersecting dimensionLine? if (sol1.hasValid() && sol2.hasValid()) { //yes, split dimension line RS_Line* dimensionLine2 = (RS_Line*)dimensionLine->clone(); v1 = sol1.get(0); v2 = sol2.get(0); if (p1.distanceTo(v1) < p1.distanceTo(v2)) { dimensionLine->setEndpoint(v1); dimensionLine2->setStartpoint(v2); } else { dimensionLine->setEndpoint(v2); dimensionLine2->setStartpoint(v1); } addEntity(dimensionLine2); } } addEntity(text); }
bool ListBox::onProcessMessage(Message* msg) { switch (msg->type()) { case kOpenMessage: centerScroll(); break; case kMouseDownMessage: captureMouse(); case kMouseMoveMessage: if (hasCapture()) { gfx::Point mousePos = static_cast<MouseMessage*>(msg)->position(); int select = getSelectedIndex(); View* view = View::getView(this); bool pick_item = true; if (view) { gfx::Rect vp = view->getViewportBounds(); if (mousePos.y < vp.y) { int num = MAX(1, (vp.y - mousePos.y) / 8); selectIndex(select-num); pick_item = false; } else if (mousePos.y >= vp.y + vp.h) { int num = MAX(1, (mousePos.y - (vp.y+vp.h-1)) / 8); selectIndex(select+num); pick_item = false; } } if (pick_item) { Widget* picked; if (view) { picked = view->getViewport()->pick(mousePos); } else { picked = pick(mousePos); } /* if the picked widget is a child of the list, select it */ if (picked && hasChild(picked)) { if (ListItem* pickedItem = dynamic_cast<ListItem*>(picked)) selectChild(pickedItem); } } return true; } break; case kMouseUpMessage: releaseMouse(); break; case kMouseWheelMessage: { View* view = View::getView(this); if (view) { gfx::Point scroll = view->getViewScroll(); scroll += static_cast<MouseMessage*>(msg)->wheelDelta() * getTextHeight()*3; view->setViewScroll(scroll); } break; } case kKeyDownMessage: if (hasFocus() && !getChildren().empty()) { int select = getSelectedIndex(); View* view = View::getView(this); int bottom = MAX(0, getChildren().size()-1); KeyMessage* keymsg = static_cast<KeyMessage*>(msg); switch (keymsg->scancode()) { case kKeyUp: // Select previous element. if (select >= 0) select--; // Or select the bottom of the list if there is no // selected item. else select = bottom; break; case kKeyDown: select++; break; case kKeyHome: select = 0; break; case kKeyEnd: select = bottom; break; case kKeyPageUp: if (view) { gfx::Rect vp = view->getViewportBounds(); select -= vp.h / getTextHeight(); } else select = 0; break; case kKeyPageDown: if (view) { gfx::Rect vp = view->getViewportBounds(); select += vp.h / getTextHeight(); } else select = bottom; break; case kKeyLeft: case kKeyRight: if (view) { gfx::Rect vp = view->getViewportBounds(); gfx::Point scroll = view->getViewScroll(); int sgn = (keymsg->scancode() == kKeyLeft) ? -1: 1; scroll.x += vp.w/2*sgn; view->setViewScroll(scroll); } break; default: return Widget::onProcessMessage(msg); } selectIndex(MID(0, select, bottom)); return true; } break; case kDoubleClickMessage: onDoubleClickItem(); return true; } return Widget::onProcessMessage(msg); }
/** * Updates the sub entities of this dimension. Called when the * dimension or the position, alignment, .. changes. * * @param autoText Automatically reposition the text label */ void RS_DimAngular::update(bool /*autoText*/) { RS_DEBUG->print("RS_DimAngular::update"); clear(); if (isUndone()) { return; } // distance from entities (DIMEXO) double dimexo = getExtensionLineOffset(); // extension line extension (DIMEXE) double dimexe = getExtensionLineExtension(); // text height (DIMTXT) double dimtxt = getTextHeight(); // text distance to line (DIMGAP) double dimgap = getDimensionLineGap(); // find out center: RS_Vector center = getCenter(); if (!center.valid) { return; } double ang1 = 0.0; double ang2 = 0.0; bool reversed = false; RS_Vector p1; RS_Vector p2; getAngles(ang1, ang2, reversed, p1, p2); double rad = edata.definitionPoint4.distanceTo(center); RS_Line* line; RS_Vector dir; double len; double dist; // 1st extension line: dist = center.distanceTo(p1); len = rad - dist + dimexe; dir.setPolar(1.0, ang1); line = new RS_Line(this, RS_LineData(center + dir*dist + dir*dimexo, center + dir*dist + dir*len)); line->setPen(RS_Pen(RS2::FlagInvalid)); line->setLayer(NULL); addEntity(line); // 2nd extension line: dist = center.distanceTo(p2); len = rad - dist + dimexe; dir.setPolar(1.0, ang2); line = new RS_Line(this, RS_LineData(center + dir*dist + dir*dimexo, center + dir*dist + dir*len)); line->setPen(RS_Pen(RS2::FlagInvalid)); line->setLayer(NULL); addEntity(line); // Create dimension line (arc): RS_Arc* arc = new RS_Arc(this, RS_ArcData(center, rad, ang1, ang2, reversed)); arc->setPen(RS_Pen(RS2::FlagInvalid)); arc->setLayer(NULL); addEntity(arc); // length of dimension arc: double distance = arc->getLength(); // do we have to put the arrows outside of the arc? bool outsideArrows = (distance<getArrowSize()*2); // arrow angles: double arrowAngle1, arrowAngle2; double arrowAng; if (rad>1.0e-6) { arrowAng = getArrowSize() / rad; } else { arrowAng = 0.0; } RS_Vector v1, v2; if (!arc->isReversed()) { v1.setPolar(rad, arc->getAngle1()+arrowAng); } else { v1.setPolar(rad, arc->getAngle1()-arrowAng); } v1+=arc->getCenter(); arrowAngle1 = arc->getStartpoint().angleTo(v1); if (!arc->isReversed()) { v2.setPolar(rad, arc->getAngle2()-arrowAng); } else { v2.setPolar(rad, arc->getAngle2()+arrowAng); } v2+=arc->getCenter(); arrowAngle2 = arc->getEndpoint().angleTo(v2); if (!outsideArrows) { arrowAngle1 = arrowAngle1+M_PI; arrowAngle2 = arrowAngle2+M_PI; } // Arrows: RS_SolidData sd; RS_Solid* arrow; // arrow 1 arrow = new RS_Solid(this, sd); arrow->shapeArrow(arc->getStartpoint(), arrowAngle1, getArrowSize()); arrow->setPen(RS_Pen(RS2::FlagInvalid)); arrow->setLayer(NULL); addEntity(arrow); // arrow 2: arrow = new RS_Solid(this, sd); arrow->shapeArrow(arc->getEndpoint(), arrowAngle2, getArrowSize()); arrow->setPen(RS_Pen(RS2::FlagInvalid)); arrow->setLayer(NULL); addEntity(arrow); // text label: RS_TextData textData; RS_Vector textPos = arc->getMiddlePoint(); RS_Vector distV; double textAngle; double dimAngle1 = textPos.angleTo(arc->getCenter())-M_PI/2.0; // rotate text so it's readable from the bottom or right (ISO) // quadrant 1 & 4 if (dimAngle1>M_PI/2.0*3.0+0.001 || dimAngle1<M_PI/2.0+0.001) { distV.setPolar(dimgap, dimAngle1+M_PI/2.0); textAngle = dimAngle1; } // quadrant 2 & 3 else { distV.setPolar(dimgap, dimAngle1-M_PI/2.0); textAngle = dimAngle1+M_PI; } // move text away from dimension line: textPos+=distV; textData = RS_TextData(textPos, dimtxt, 30.0, RS2::VAlignBottom, RS2::HAlignCenter, RS2::LeftToRight, RS2::Exact, 1.0, getLabel(), "standard", textAngle); RS_Text* text = new RS_Text(this, textData); // move text to the side: text->setPen(RS_Pen(RS2::FlagInvalid)); text->setLayer(NULL); addEntity(text); calculateBorders(); }
/** * Updates the sub entities of this dimension. Called when the * dimension or the position, alignment, .. changes. * * @param autoText Automatically reposition the text label */ void RS_DimRadial::updateDim(bool autoText) { RS_DEBUG->print("RS_DimRadial::update"); clear(); if (isUndone()) { return; } // dimension line: //updateCreateDimensionLine(data.definitionPoint, edata.definitionPoint, //false, true); // general scale (DIMSCALE) double dimscale = getGeneralScale(); RS_Vector p1 = data.definitionPoint; RS_Vector p2 = edata.definitionPoint; double angle = p1.angleTo(p2); // text height (DIMTXT) double dimtxt = getTextHeight()*dimscale; // text distance to line (DIMGAP) double dimgap = getDimensionLineGap()*dimscale; // arrow size: double arrowSize = getArrowSize()*dimscale; // length of dimension line: double length = p1.distanceTo(p2); RS_Pen pen(getDimensionLineColor(), getDimensionLineWidth(), RS2::LineByBlock); RS_MTextData textData; textData = RS_MTextData(RS_Vector(0.0,0.0), dimtxt, 30.0, RS_MTextData::VAMiddle, RS_MTextData::HACenter, RS_MTextData::LeftToRight, RS_MTextData::Exact, 1.0, getLabel(), getTextStyle(), // "standard", 0.0); RS_MText* text = new RS_MText(this, textData); double textWidth = text->getSize().x; // do we have to put the arrow / text outside of the arc? bool outsideArrow = (length<arrowSize*2+textWidth); double arrowAngle; if (outsideArrow) { length += arrowSize*2 + textWidth; arrowAngle = angle+M_PI; } else { arrowAngle = angle; } // create arrow: RS_SolidData sd; RS_Solid* arrow; arrow = new RS_Solid(this, sd); arrow->shapeArrow(p2, arrowAngle, arrowSize); // arrow->setPen(RS_Pen(RS2::FlagInvalid)); arrow->setPen(pen); arrow->setLayer(NULL); addEntity(arrow); RS_Vector p3; p3.setPolar(length, angle); p3 += p1; // Create dimension line: RS_Line* dimensionLine = new RS_Line(this, RS_LineData(p1, p3)); dimensionLine->setPen(pen); // dimensionLine->setPen(RS_Pen(RS2::FlagInvalid)); dimensionLine->setLayer(NULL); addEntity(dimensionLine); RS_Vector distV; double textAngle; // rotate text so it's readable from the bottom or right (ISO) // quadrant 1 & 4 if (angle>M_PI_2*3.0+0.001 || angle<M_PI_2+0.001) { distV.setPolar(dimgap + dimtxt/2.0, angle+M_PI_2); textAngle = angle; } // quadrant 2 & 3 else { distV.setPolar(dimgap + dimtxt/2.0, angle-M_PI_2); textAngle = angle+M_PI; } // move text label: RS_Vector textPos; if (data.middleOfText.valid && !autoText) { textPos = data.middleOfText; } else { if (outsideArrow) { textPos.setPolar(length-textWidth/2.0-arrowSize, angle); } else { textPos.setPolar(length/2.0, angle); } textPos+=p1; // move text away from dimension line: textPos += distV; data.middleOfText = textPos; } text->rotate(RS_Vector(0.0,0.0), textAngle); text->move(textPos); text->setPen(RS_Pen(getTextColor(), RS2::WidthByBlock, RS2::SolidLine)); // text->setPen(RS_Pen(RS2::FlagInvalid)); text->setLayer(NULL); addEntity(text); calculateBorders(); }
void TextBlock::draw(){ float yAlig = y; if (vAlignment == OF_TEXT_ALIGN_BOTTOM){ yAlig = y + height - getTextHeight(); } else if (vAlignment == OF_TEXT_ALIGN_MIDDLE){ yAlig = getCenter().y - getTextHeight()*0.5; } if (hAlignment == OF_TEXT_ALIGN_LEFT){ string strToDraw; int currentWordID; float drawX; float drawY; float currX = 0; if (words.size() > 0){ for(int l=0;l < lines.size(); l++){ for(int w=0;w < lines[l].wordsID.size(); w++){ currentWordID = lines[l].wordsID[w]; drawX = x + currX; drawY = yAlig + (font->getLineHeight() * (l + 1)); ofPushMatrix(); font->drawString(words[currentWordID].rawWord.c_str(), drawX, drawY); currX += words[currentWordID].width; ofPopMatrix(); } currX = 0; } } } else if (hAlignment == OF_TEXT_ALIGN_RIGHT){ string strToDraw; int currentWordID; float drawX; float drawY; float currX = 0; if (words.size() > 0) { for(int l=0;l < lines.size(); l++){ for(int w=lines[l].wordsID.size() - 1; w >= 0; w--){ currentWordID = lines[l].wordsID[w]; drawX = -currX - words[currentWordID].width; drawY = font->getLineHeight() * (l + 1); ofPushMatrix(); //Move to top left point using pre-scaled co-ordinates ofTranslate(x + width, yAlig, 0.0f); font->drawString(words[currentWordID].rawWord.c_str(), drawX, drawY); currX += words[currentWordID].width; ofPopMatrix(); } currX = 0; } } } else if (hAlignment == OF_TEXT_ALIGN_JUSTIFIED){ string strToDraw; int currentWordID; float drawX; float drawY; int spacesN; float nonSpaceWordWidth; float pixelsPerSpace; float currX = 0; if (words.size() > 0) { for(int l=0;l < lines.size(); l++){ //Find number of spaces and width of other words; spacesN = 0; nonSpaceWordWidth = 0; for(int w = 0; w < lines[l].wordsID.size(); w++){ currentWordID = lines[l].wordsID[w]; if (words[currentWordID].rawWord == " ") spacesN++; else nonSpaceWordWidth += words[currentWordID].width; } pixelsPerSpace = (width - x - nonSpaceWordWidth) / spacesN; for(int w=0;w < lines[l].wordsID.size(); w++){ currentWordID = lines[l].wordsID[w]; drawX = currX; drawY = font->getLineHeight() * (l + 1); ofPushMatrix(); //Move to top left point using pre-scaled co-ordinates ofTranslate(x, yAlig, 0.0f); if (words[currentWordID].rawWord != " ") { font->drawString(words[currentWordID].rawWord.c_str(), drawX, drawY); currX += words[currentWordID].width; } else { currX += pixelsPerSpace; } ofPopMatrix(); } currX = 0; } } } else if (hAlignment == OF_TEXT_ALIGN_CENTER ){ string strToDraw; int currentWordID; float drawX; float drawY; float lineWidth; float currX = 0; if (words.size() > 0) { for(int l=0;l < lines.size(); l++){ //Get the length of the line. lineWidth = 0; for(int w=0;w < lines[l].wordsID.size(); w++){ currentWordID = lines[l].wordsID[w]; lineWidth += words[currentWordID].width; } for(int w=0;w < lines[l].wordsID.size(); w++){ currentWordID = lines[l].wordsID[w]; drawX = -(lineWidth / 2) + currX; drawY = font->getLineHeight() * (l + 1); ofPushMatrix(); //Move to central point using pre-scaled co-ordinates ofTranslate(getCenter().x, yAlig, 0.0f); font->drawString(words[currentWordID].rawWord.c_str(), drawX, drawY); currX += words[currentWordID].width; ofPopMatrix(); } currX = 0; } } } }
//-------------------------------------------------------------- void ofxMuiTextBlock::update() { if(needsUpdate) { displayText = text; applyCaps(displayText,capsStyle); ofRectangle goalBox(0,0,getTextWidth(),getTextHeight()); float wrappedWidth = 0; float wrappedHeight = 0; vector<string> lines; vector<int> breakPos; vector<ofVec2f> charPos; vector<float> lineWidths; ofRectangle boundingBox; string delimiters = " "; breakLines(font, displayText, breakPos, charPos, lineWidths, lines, boundingBox, goalBox, lineBreakMode, delimiters, truncationMode, truncationString); string::iterator begin = displayText.begin(); vector<int>::iterator bpBegin = breakPos.begin(); vector<int>::iterator bpIt = breakPos.begin(); vector<int>::iterator bpEnd = breakPos.end(); while(bpIt != bpEnd) { //int i = *bpIt; displayText.insert(*bpIt,"\n"); ++bpIt; } //cout << "lines=" << lines.size() << endl; /* applyLineTruncationMode(font, displayText, sWidth, getTextWidth(), lineBreakMode, truncationString); */ /* if(lineBreakMode != LINE_BREAK_MODE_WORD_NONE && isFixedWidth()) { // TODO // TODO, this CAN depend on alignent as well switch (lineBreakMode) { case LINE_BREAK_MODE_WORD_NONE: case LINE_BREAK_MODE_WORD_WRAP: case LINE_BREAK_MODE_CHARACTER_WRAP: case LINE_BREAK_MODE_CLIP: case LINE_BREAK_MODE_HEAD_TRUNCATION: case LINE_BREAK_MODE_TAIL_TRUNCATION: case LINE_BREAK_MODE_MIDDLE_TRUNCATION: break; } //string testString = displayText; } */ // displayStringBoundingBox = font->getStringBoundingBox(displayText,0,0); //cout << "display text rect for (displayText)=>" << displayText << "<| " << ofxMuiRectUtils::toString(&displayTextRect) << endl; /* switch(orientation) { case OF_ORIENTATION_UNKNOWN: // if unknown, use default case OF_ORIENTATION_DEFAULT: case OF_ORIENTATION_180: //cout << labelFont ->getSize() << endl; // place anchor on upper left corner displayStringBoundingBox.x = 0;// displayStringBoundingBox.y = 0;//y += displayTextRect.height; break; case OF_ORIENTATION_90_RIGHT: case OF_ORIENTATION_90_LEFT: float tmp = displayStringBoundingBox.width; displayStringBoundingBox.width = displayStringBoundingBox.height; displayStringBoundingBox.height = tmp; displayStringBoundingBox.y = 0; break; } */ //cout << "display text rect: " << ofxMuiRectUtils::toString(&displayTextRect) << endl; // setContentBoxWidth(displayStringBoundingBox.width); // should always be 0,0 //setContentBoxHeight(displayStringBoundingBox.height); // should always be 0,0 // setHitBox(getContentBox()); // the whole thing //TODO PARENT NEEDS LAYOUT UPDATE WHEN LABEL PROPOERTIES ARE SET DURING SETUP //setParentNeedsLayoutUpdate(true); } needsUpdate = false; // just did it! }
/** * Creates a dimensioning line (line with one, two or no arrows and a text). * * @param forceAutoText Automatically reposition the text label. */ void RS_Dimension::updateCreateDimensionLine(const RS_Vector& p1, const RS_Vector& p2, bool arrow1, bool arrow2, bool forceAutoText) { // general scale (DIMSCALE) double dimscale = getGeneralScale(); // text height (DIMTXT) double dimtxt = getTextHeight()*dimscale; // text distance to line (DIMGAP) double dimgap = getDimensionLineGap()*dimscale; // length of dimension line: double distance = p1.distanceTo(p2); // arrow size: double arrowSize = getArrowSize()*dimscale; // do we have to put the arrows outside of the line? bool outsideArrows = (distance<arrowSize*2.5); // arrow angles: double arrowAngle1, arrowAngle2; RS_Pen pen(getDimensionLineColor(), getDimensionLineWidth(), RS2::LineByBlock); // Create dimension line: RS_Line* dimensionLine = new RS_Line{this, p1, p2}; dimensionLine->setPen(pen); // dimensionLine->setPen(RS_Pen(RS2::FlagInvalid)); dimensionLine->setLayer(nullptr); addEntity(dimensionLine); if (outsideArrows==false) { arrowAngle1 = dimensionLine->getAngle2(); arrowAngle2 = dimensionLine->getAngle1(); } else { arrowAngle1 = dimensionLine->getAngle1(); arrowAngle2 = dimensionLine->getAngle2(); // extend dimension line outside arrows RS_Vector dir = RS_Vector::polar(arrowSize*2, arrowAngle2); dimensionLine->setStartpoint(p1 + dir); dimensionLine->setEndpoint(p2 - dir); } double dimtsz=getTickSize()*dimscale; if(dimtsz < 0.01) { //display arrow // Arrows: RS_SolidData sd; RS_Solid* arrow; if (arrow1) { // arrow 1 arrow = new RS_Solid(this, sd); arrow->shapeArrow(p1, arrowAngle1, arrowSize); // arrow->setPen(RS_Pen(RS2::FlagInvalid)); arrow->setPen(pen); arrow->setLayer(nullptr); addEntity(arrow); } if (arrow2) { // arrow 2: arrow = new RS_Solid(this, sd); arrow->shapeArrow(p2, arrowAngle2, arrowSize); // arrow->setPen(RS_Pen(RS2::FlagInvalid)); arrow->setPen(pen); arrow->setLayer(nullptr); addEntity(arrow); } }else{ //display ticks // Arrows: RS_Line* tick; RS_Vector tickVector = RS_Vector::polar(dimtsz,arrowAngle1 + M_PI*0.25); //tick is 45 degree away if (arrow1) { // tick 1 tick = new RS_Line(this, p1-tickVector, p1+tickVector); tick->setPen(pen); // tick->setPen(RS_Pen(RS2::FlagInvalid)); tick->setLayer(nullptr); addEntity(tick); } if (arrow2) { // tick 2: tick = new RS_Line(this, p2-tickVector, p2+tickVector); tick->setPen(pen); // tick->setPen(RS_Pen(RS2::FlagInvalid)); tick->setLayer(nullptr); addEntity(tick); } } // Text label: RS_MTextData textData; RS_Vector textPos; double dimAngle1 = dimensionLine->getAngle1(); double textAngle; bool corrected=false; if (getAlignText()) textAngle =0.0; else textAngle = RS_Math::makeAngleReadable(dimAngle1, true, &corrected); if (data.middleOfText.valid && !forceAutoText) { textPos = data.middleOfText; } else { textPos = dimensionLine->getMiddlePoint(); if (!getAlignText()) { // rotate text so it's readable from the bottom or right (ISO) // quadrant 1 & 4 double const a = corrected?-M_PI_2:M_PI_2; RS_Vector distV = RS_Vector::polar(dimgap + dimtxt/2.0, dimAngle1+a); // move text away from dimension line: textPos+=distV; } //// the next update should still be able to adjust this //// auto text position. leave it invalid data.middleOfText = textPos; } textData = RS_MTextData(textPos, dimtxt, 30.0, RS_MTextData::VAMiddle, RS_MTextData::HACenter, RS_MTextData::LeftToRight, RS_MTextData::Exact, 1.0, getLabel(), getTextStyle(), // "standard", textAngle); RS_MText* text = new RS_MText(this, textData); // move text to the side: RS_Vector distH; if (text->getUsedTextWidth()>distance) { distH.setPolar(text->getUsedTextWidth()/2.0 +distance/2.0+dimgap, textAngle); text->move(distH); } text->setPen(RS_Pen(getTextColor(), RS2::WidthByBlock, RS2::SolidLine)); // text->setPen(RS_Pen(RS2::FlagInvalid)); text->setLayer(nullptr); //horizontal text, split dimensionLine if (getAlignText()) { double w =text->getUsedTextWidth()/2+dimgap; double h = text->getUsedTextHeight()/2+dimgap; RS_Vector v1 = textPos - RS_Vector{w, h}; RS_Vector v2 = textPos + RS_Vector{w, h}; RS_EntityContainer c; c.addRectangle(v1, v2); RS_VectorSolutions sol1; for(RS_Entity* e: c) { sol1.push_back( RS_Information::getIntersection(dimensionLine, e, true) ); } //are text intersecting dimensionLine? if (sol1.size()>1) { //yes, split dimension line RS_Line* dimensionLine2 = static_cast<RS_Line*>(dimensionLine->clone()); v1 = sol1.get(0); v2 = sol1.get(1); if (p1.distanceTo(v1) < p1.distanceTo(v2)) { dimensionLine->setEndpoint(v1); dimensionLine2->setStartpoint(v2); } else { dimensionLine->setEndpoint(v2); dimensionLine2->setStartpoint(v1); } addEntity(dimensionLine2); } } addEntity(text); }
unsigned int surface_c::renderText(const fontParams_s * par, const std::string & t) { // make some safety checks, empty strings are not output bool onlySpace = true; for (size_t i = 0; i < t.length(); i++) if (t[i] != ' ') { onlySpace = false; break; } if ( (t.length() == 0) || (onlySpace) ) { return 1; } std::vector<std::string> words = split(t.c_str(), ' ');; int ypos = par->box.y; if (par->alignment == ALN_CENTER) ypos += (par->box.h-getTextHeight(par, t))/2; unsigned int word = 0; unsigned int lines = 0; while (word < words.size()) { std::string curLine = words[word]; word++; lines++; while (word < words.size()) { int w; TTF_SizeUTF8(fonts[par->font], (curLine+words[word]).c_str(), &w, 0); if (w > par->box.w) break; curLine = curLine + " " + words[word]; word++; } SDL_Surface * vv = TTF_RenderUTF8_Blended(fonts[par->font], curLine.c_str(), par->color); SDL_Surface * vb = NULL; if (par->shadow) { SDL_Color bg; bg.r = bg.g = bg.b = 0; vb = TTF_RenderUTF8_Blended(fonts[par->font], curLine.c_str(), bg); } if (par->alignment == ALN_TEXT) { SDL_Rect r = par->box; r.w = vv->w; r.h = vv->h; r.y = ypos; if (par->shadow == 1) { int sa = 1; if (par->font == FNT_BIG) sa = 2; r.x-=sa; r.y-=sa; SDL_BlitSurface(vb, 0, video, &r); r.x+=sa; SDL_BlitSurface(vb, 0, video, &r); r.x+=sa; SDL_BlitSurface(vb, 0, video, &r); r.y+=sa; SDL_BlitSurface(vb, 0, video, &r); r.y+=sa; SDL_BlitSurface(vb, 0, video, &r); r.x-=sa; SDL_BlitSurface(vb, 0, video, &r); r.x-=sa; SDL_BlitSurface(vb, 0, video, &r); r.y-=sa; SDL_BlitSurface(vb, 0, video, &r); r.x+=sa; } else if (par->shadow == 2) { int sa = 1; r.x+=sa; r.y+=sa; SDL_BlitSurface(vb, 0, video, &r); r.x-=sa; r.y-=sa; } SDL_BlitSurface(vv, 0, video, &r); } else if (par->alignment == ALN_TEXT_CENTER || par->alignment == ALN_CENTER) { SDL_Rect r; r.x = par->box.x + (par->box.w - vv->w)/2; r.y = ypos; r.w = vv->w; r.h = vv->h; if (par->shadow == 1) { int sa = 1; if (par->font == FNT_BIG) sa = 2; r.x-=sa; r.y-=sa; SDL_BlitSurface(vb, 0, video, &r); r.x+=sa; SDL_BlitSurface(vb, 0, video, &r); r.x+=sa; SDL_BlitSurface(vb, 0, video, &r); r.y+=sa; SDL_BlitSurface(vb, 0, video, &r); r.y+=sa; SDL_BlitSurface(vb, 0, video, &r); r.x-=sa; SDL_BlitSurface(vb, 0, video, &r); r.x-=sa; SDL_BlitSurface(vb, 0, video, &r); r.y-=sa; SDL_BlitSurface(vb, 0, video, &r); r.x+=sa; } else if (par->shadow == 2) { int sa = 1; r.x+=sa; r.y+=sa; SDL_BlitSurface(vb, 0, video, &r); r.x-=sa; r.y-=sa; } SDL_BlitSurface(vv, 0, video, &r); } ypos += vv->h; SDL_FreeSurface(vv); if (par->shadow) SDL_FreeSurface(vb); } return lines; }
void StatusBar::onPreferredSize(PreferredSizeEvent& ev) { int s = 4*jguiscale() + getTextHeight() + 4*jguiscale(); ev.setPreferredSize(Size(s, s)); }