String alignFunctionCallParams (const String& call, const StringArray& parameters, const int maxLineLength) { String result, currentLine (call); for (int i = 0; i < parameters.size(); ++i) { if (currentLine.length() >= maxLineLength) { result += currentLine.trimEnd() + newLine; currentLine = String::repeatedString (" ", call.length()) + parameters[i]; } else { currentLine += parameters[i]; } if (i < parameters.size() - 1) currentLine << ", "; } return result + currentLine.trimEnd() + ")"; }
void FileUtil::addMapping(Map map) { qDebug("FileUtil::addMapping()"); QStringList fileContent; QFile file("mapping.txt"); file.open(QIODevice::ReadOnly); QString mapLine; qDebug("FileUtil::addMapping task id: %s", map.task.taskId.toStdString().c_str()); mapLine.append(map.task.taskId); mapLine.append(" "); mapLine.append(map.coreProject.id); mapLine.append(" "); mapLine.append(map.coreTask.id); mapLine.append("\n"); qDebug("FileUtil::addMapping line: %s", mapLine.toStdString().c_str()); bool replaced = false; while (!file.atEnd()) { QString currentLine(file.readLine()); if (currentLine.startsWith(map.task.taskId)) { qDebug("FileUtil::addMapping map found, replacing: %s with %s", currentLine.toStdString().c_str(), mapLine.toStdString().c_str()); currentLine = mapLine; replaced = true; } fileContent << currentLine; } file.close(); if (!replaced) { qDebug("FileUtil::addMapping map found, adding line to the end of the file"); fileContent << mapLine; } file.open(QIODevice::Truncate | QIODevice::WriteOnly); QString l; qDebug("FileUtil::addMapping saving contents to file"); foreach (l, fileContent) { file.write(l.toStdString().c_str()); }
void UBGraphicsDelegateFrame::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { if (None == mCurrentTool) return; QLineF move = QLineF(mStartingPoint, event->scenePos()); qreal moveX = move.length() * cos((move.angle() - mAngle) * PI / 180); qreal moveY = -move.length() * sin((move.angle() - mAngle) * PI / 180); qreal width = delegated()->boundingRect().width() * mTotalScaleX; qreal height = delegated()->boundingRect().height() * mTotalScaleY; if (mOperationMode == Scaling) { if(!rotating()) { mTranslateX = moveX; // Perform the resize if (resizingBottomRight()) { // ----------------------------------------------------- // ! We want to keep the aspect ratio with this resize ! // ----------------------------------------------------- qreal scaleX; qreal scaleY; if(!mMirrorX) { scaleX = (width + moveX) / width; } else { scaleX = (width - moveX) / width; } if(!mMirrorY) { scaleY = (height + moveY) / height; } else { scaleY = (height - moveY) / height; } qreal scaleFactor = (scaleX + scaleY) / 2; // Do not allow resizing of image size under frame size if (canResizeBottomRight(width, height, scaleFactor)) { if (mRespectRatio) { mScaleX = scaleFactor; mScaleY = scaleFactor; } else { mScaleX = scaleX; mScaleY = scaleY; } } } else if (resizingLeft() || resizingRight()) { if(width != 0) { qreal scaleX = 0.0; if(resizingLeft()) { scaleX = (width - moveX) / width; } else if(resizingRight()) { scaleX = (width + moveX) / width; } if(mDelegate->isFlippable() && qAbs(scaleX) != 0) { if((qAbs(width * scaleX)) < 2*mFrameWidth) { bool negative = (scaleX < 0)?true:false; if(negative) { if(mMirrorX) scaleX = 2*mFrameWidth/width; else scaleX = -2*mFrameWidth/width; } else { scaleX = -1; mFlippedX = !mFlippedX; } } mScaleX = scaleX; } else if (scaleX > 1 || (width * scaleX) > 2 * mFrameWidth) { mScaleX = scaleX; if(resizingLeft()) { mTranslateX = moveX; } } } } else if(resizingTop() || resizingBottom()) { if(height != 0) { qreal scaleY = 0.0; if(resizingTop()) { scaleY = (height - moveY) / height; } else if(resizingBottom()) { scaleY = (height + moveY) / height; } if(mDelegate->isFlippable() && qAbs(scaleY) != 0) { if((qAbs(height * scaleY)) < 2*mFrameWidth) { bool negative = (scaleY < 0)?true:false; if(negative) { if(mMirrorY) scaleY = 2*mFrameWidth/width; else scaleY = -2*mFrameWidth/width; } else { scaleY = -1; mFlippedY = !mFlippedY; } } mScaleY = scaleY; } else if (scaleY > 1 || (height * scaleY) > 2 * mFrameWidth) { mScaleY = scaleY; if(resizingTop()) { mTranslateY = moveY; } } } } } } if (rotating()) { mTranslateX = 0; mTranslateY = 0; QLineF startLine(sceneBoundingRect().center(), event->lastScenePos()); QLineF currentLine(sceneBoundingRect().center(), event->scenePos()); mAngle += startLine.angleTo(currentLine); if ((int)mAngle % 45 >= 45 - mAngleTolerance || (int)mAngle % 45 <= mAngleTolerance) { mAngle = qRound(mAngle / 45) * 45; mAngleOffset += startLine.angleTo(currentLine); if ((int)mAngleOffset % 360 > mAngleTolerance && (int)mAngleOffset % 360 < 360 - mAngleTolerance) { mAngle += mAngleOffset; mAngleOffset = 0; } } else if ((int)mAngle % 30 >= 30 - mAngleTolerance || (int)mAngle % 30 <= mAngleTolerance) { mAngle = qRound(mAngle / 30) * 30; mAngleOffset += startLine.angleTo(currentLine); if ((int)mAngleOffset % 360 > mAngleTolerance && (int)mAngleOffset % 360 < 360 - mAngleTolerance) { mAngle += mAngleOffset; mAngleOffset = 0; } } setCursorFromAngle(QString::number((int)mAngle % 360)); } else if (moving()) { mTranslateX = move.dx(); mTranslateY = move.dy(); moveLinkedItems(move); } if (mOperationMode == Scaling || moving() || rotating()) { QTransform tr = buildTransform(); if (resizingRight() || resizingBottom() || resizingBottomRight()) { QPointF ref; // we just detects coordinates of corner before and after scaling and then moves object at diff between them. if (resizingBottomRight() && (mMirrorX || mMirrorY)) { if (mFlippedX && !mMirrorX && mFlippedY)// && !mMirrorY) { mTranslateX += mInitialTransform.map(delegated()->boundingRect().bottomLeft()).x() - tr.map(delegated()->boundingRect().bottomLeft()).x(); mTranslateY += mInitialTransform.map(delegated()->boundingRect().bottomLeft()).y() - tr.map(delegated()->boundingRect().bottomLeft()).y(); } else if ((mFlippedX || mMirrorX) && (mFlippedY || mMirrorY)) { mTranslateX += mInitialTransform.map(delegated()->boundingRect().bottomRight()).x() - tr.map(delegated()->boundingRect().bottomRight()).x(); mTranslateY += mInitialTransform.map(delegated()->boundingRect().bottomRight()).y() - tr.map(delegated()->boundingRect().bottomRight()).y(); } else if (mFlippedX || mMirrorX) { mTranslateX += mInitialTransform.map(delegated()->boundingRect().topRight()).x() - tr.map(delegated()->boundingRect().topRight()).x(); mTranslateY += mInitialTransform.map(delegated()->boundingRect().topRight()).y() - tr.map(delegated()->boundingRect().topRight()).y(); } else if (mFlippedY || mMirrorY) { mTranslateX += mInitialTransform.map(delegated()->boundingRect().bottomLeft()).x() - tr.map(delegated()->boundingRect().bottomLeft()).x(); mTranslateY += mInitialTransform.map(delegated()->boundingRect().bottomLeft()).y() - tr.map(delegated()->boundingRect().bottomLeft()).y(); } else { mTranslateX += mInitialTransform.map(delegated()->boundingRect().bottomRight()).x() - tr.map(delegated()->boundingRect().bottomRight()).x(); mTranslateY += mInitialTransform.map(delegated()->boundingRect().bottomRight()).y() - tr.map(delegated()->boundingRect().bottomRight()).y(); } } else { mTranslateX += mInitialTransform.map(delegated()->boundingRect().topLeft()).x() - tr.map(delegated()->boundingRect().topLeft()).x(); mTranslateY += mInitialTransform.map(delegated()->boundingRect().topLeft()).y() - tr.map(delegated()->boundingRect().topLeft()).y(); } } else if (resizingTop() || resizingLeft()) { QPointF bottomRight = tr.map(delegated()->boundingRect().bottomRight()); QPointF fixedPoint = mInitialTransform.map(delegated()->boundingRect().bottomRight()); mTranslateX += fixedPoint.x() - bottomRight.x(); mTranslateY += fixedPoint.y() - bottomRight.y(); } delegated()->setTransform(buildTransform()); } else // resizing/resizing horizontally { if (resizingBottomRight()) { static QSizeF incV = QSizeF(); static QSizeF incH = QSizeF(); if (mMirrorX && mMirrorY) mCurrentTool = ResizeTop; else mCurrentTool = ResizeBottom; incV = resizeDelegate(moveX, moveY); mOriginalSize += incV; if (mMirrorX && mMirrorY) mCurrentTool = ResizeLeft; else mCurrentTool = ResizeRight; move = QLineF(event->lastScenePos(), event->scenePos()); moveX = move.length() * cos((move.angle() - mAngle) * PI / 180); moveY = -move.length() * sin((move.angle() - mAngle) * PI / 180); mFixedPoint = getFixedPointFromPos(); incH = resizeDelegate(moveX, moveY); mOriginalSize -= incV; mOriginalSize += incH; mCurrentTool = ResizeBottomRight; } else resizeDelegate(moveX, moveY); } event->accept(); }
void QQuickTextNodeEngine::addTextBlock(QTextDocument *textDocument, const QTextBlock &block, const QPointF &position, const QColor &textColor, const QColor &anchorColor, int selectionStart, int selectionEnd) { Q_ASSERT(textDocument); #ifndef QT_NO_IM int preeditLength = block.isValid() ? block.layout()->preeditAreaText().length() : 0; int preeditPosition = block.isValid() ? block.layout()->preeditAreaPosition() : -1; #endif QVarLengthArray<QTextLayout::FormatRange> colorChanges; mergeFormats(block.layout(), &colorChanges); QPointF blockPosition = textDocument->documentLayout()->blockBoundingRect(block).topLeft() + position; if (QTextList *textList = block.textList()) { QPointF pos = blockPosition; QTextLayout *layout = block.layout(); if (layout->lineCount() > 0) { QTextLine firstLine = layout->lineAt(0); Q_ASSERT(firstLine.isValid()); setCurrentLine(firstLine); QRectF textRect = firstLine.naturalTextRect(); pos += textRect.topLeft(); if (block.textDirection() == Qt::RightToLeft) pos.rx() += textRect.width(); const QTextCharFormat charFormat = block.charFormat(); QFont font(charFormat.font()); QFontMetricsF fontMetrics(font); QTextListFormat listFormat = textList->format(); QString listItemBullet; switch (listFormat.style()) { case QTextListFormat::ListCircle: listItemBullet = QChar(0x25E6); // White bullet break; case QTextListFormat::ListSquare: listItemBullet = QChar(0x25AA); // Black small square break; case QTextListFormat::ListDecimal: case QTextListFormat::ListLowerAlpha: case QTextListFormat::ListUpperAlpha: case QTextListFormat::ListLowerRoman: case QTextListFormat::ListUpperRoman: listItemBullet = textList->itemText(block); break; default: listItemBullet = QChar(0x2022); // Black bullet break; }; QSizeF size(fontMetrics.width(listItemBullet), fontMetrics.height()); qreal xoff = fontMetrics.width(QLatin1Char(' ')); if (block.textDirection() == Qt::LeftToRight) xoff = -xoff - size.width(); setPosition(pos + QPointF(xoff, 0)); QTextLayout layout; layout.setFont(font); layout.setText(listItemBullet); // Bullet layout.beginLayout(); QTextLine line = layout.createLine(); line.setPosition(QPointF(0, 0)); layout.endLayout(); QList<QGlyphRun> glyphRuns = layout.glyphRuns(); for (int i=0; i<glyphRuns.size(); ++i) addUnselectedGlyphs(glyphRuns.at(i)); } } int textPos = block.position(); QTextBlock::iterator blockIterator = block.begin(); while (!blockIterator.atEnd()) { QTextFragment fragment = blockIterator.fragment(); QString text = fragment.text(); if (text.isEmpty()) continue; QTextCharFormat charFormat = fragment.charFormat(); QFont font(charFormat.font()); QFontMetricsF fontMetrics(font); int fontHeight = fontMetrics.descent() + fontMetrics.ascent(); int valign = charFormat.verticalAlignment(); if (valign == QTextCharFormat::AlignSuperScript) setPosition(QPointF(blockPosition.x(), blockPosition.y() - fontHeight / 2)); else if (valign == QTextCharFormat::AlignSubScript) setPosition(QPointF(blockPosition.x(), blockPosition.y() + fontHeight / 6)); else setPosition(blockPosition); if (text.contains(QChar::ObjectReplacementCharacter)) { QTextFrame *frame = qobject_cast<QTextFrame *>(textDocument->objectForFormat(charFormat)); if (frame && frame->frameFormat().position() == QTextFrameFormat::InFlow) { int blockRelativePosition = textPos - block.position(); QTextLine line = block.layout()->lineForTextPosition(blockRelativePosition); if (!currentLine().isValid() || line.lineNumber() != currentLine().lineNumber()) { setCurrentLine(line); } QQuickTextNodeEngine::SelectionState selectionState = (selectionStart < textPos + text.length() && selectionEnd >= textPos) ? QQuickTextNodeEngine::Selected : QQuickTextNodeEngine::Unselected; addTextObject(QPointF(), charFormat, selectionState, textDocument, textPos); } textPos += text.length(); } else { if (charFormat.foreground().style() != Qt::NoBrush) setTextColor(charFormat.foreground().color()); else if (charFormat.isAnchor()) setTextColor(anchorColor); else setTextColor(textColor); int fragmentEnd = textPos + fragment.length(); #ifndef QT_NO_IM if (preeditPosition >= 0 && (preeditPosition + block.position()) >= textPos && (preeditPosition + block.position()) <= fragmentEnd) { fragmentEnd += preeditLength; } #endif if (charFormat.background().style() != Qt::NoBrush) { QTextLayout::FormatRange additionalFormat; additionalFormat.start = textPos - block.position(); additionalFormat.length = fragmentEnd - textPos; additionalFormat.format = charFormat; colorChanges << additionalFormat; } textPos = addText(block, charFormat, textColor, colorChanges, textPos, fragmentEnd, selectionStart, selectionEnd); } ++blockIterator; } #ifndef QT_NO_IM if (preeditLength >= 0 && textPos <= block.position() + preeditPosition) { setPosition(blockPosition); textPos = block.position() + preeditPosition; QTextLine line = block.layout()->lineForTextPosition(preeditPosition); if (!currentLine().isValid() || line.lineNumber() != currentLine().lineNumber()) { setCurrentLine(line); } textPos = addText(block, block.charFormat(), textColor, colorChanges, textPos, textPos + preeditLength, selectionStart, selectionEnd); } #endif setCurrentLine(QTextLine()); // Reset current line because the text layout changed m_hasContents = true; }
void UBGraphicsTriangle::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { if (!mResizing1 && !mResizing2 && !mRotating) { QGraphicsItem::mouseMoveEvent(event); } else { QPoint currPos = sceneTransform().inverted().map(event->screenPos()); if (mResizing1) { if (mOrientation == TopLeft || mOrientation == BottomLeft) { int deltaX = currPos.x() - lastPos.x(); if (lastRect.width() + deltaX < sMinWidth) deltaX = sMinWidth - lastRect.width(); setRect(QRectF(lastRect.left(), lastRect.top(), lastRect.width() + deltaX, lastRect.height()), mOrientation); } else { int deltaX = lastPos.x() - currPos.x(); if (lastRect.width() + deltaX < sMinWidth) deltaX = sMinWidth - lastRect.width(); setRect(QRectF(lastRect.left() - deltaX, lastRect.top(), lastRect.width() + deltaX, lastRect.height()), mOrientation); } } //-----------------------------------------------// if (mResizing2) { if (mOrientation == BottomRight || mOrientation == BottomLeft) { int deltaY = lastPos.y() - currPos.y(); if (lastRect.height() + deltaY < sMinHeight) deltaY = sMinHeight - lastRect.height(); setRect(QRectF(lastRect.left(), lastRect.top() - deltaY, lastRect.width(), lastRect.height() + deltaY), mOrientation); } else { int deltaY = currPos.y() - lastPos.y(); if (lastRect.height() + deltaY < sMinHeight) deltaY = sMinHeight - lastRect.height(); setRect(QRectF(lastRect.left(), lastRect.top(), lastRect.width(), lastRect.height() + deltaY), mOrientation); } } //-----------------------------------------------// if (mRotating) { QLineF currentLine(rotationCenter(), event->pos()); QLineF lastLine(rotationCenter(), event->lastPos()); rotateAroundCenter(currentLine.angleTo(lastLine)); } //-----------------------------------------------// event->accept(); } }
void TextObject::createBitmap() { if (_created) destroyBitmap(); Common::String msg = parseMsgText(_textID, NULL); Common::String message; const char *c = msg.c_str(); // remove spaces (NULL_TEXT) from the end of the string, // while this helps make the string unique it screws up // text justification for (int i = (int)msg.size() - 1; c[i] == TEXT_NULL; i--) msg.deleteLastChar(); // remove char of id 13 from the end of the string, for (int i = (int)msg.size() - 1; c[i] == 13; i--) msg.deleteLastChar(); // format the output message to incorporate line wrapping // (if necessary) for the text object const int SCREEN_WIDTH = _width ? _width : 640; const int SCREEN_MARGIN = 75; // If the speaker is too close to the edge of the screen we have to make // some room for the subtitles. if (_isSpeech){ if (_x < SCREEN_MARGIN) { _x = SCREEN_MARGIN; } else if (SCREEN_WIDTH - _x < SCREEN_MARGIN) { _x = SCREEN_WIDTH - SCREEN_MARGIN; } } // The maximum width for any line of text is determined by the justification // mode. Note that there are no left/right margins -- this is consistent // with GrimE. int maxWidth; if (_justify == CENTER) { maxWidth = 2 * MIN(_x, SCREEN_WIDTH - _x); } else if (_justify == LJUSTIFY) { maxWidth = SCREEN_WIDTH - _x; } else if (_justify == RJUSTIFY) { maxWidth = _x; } // We break the message to lines not longer than maxWidth _numberLines = 1; int lineWidth = 0; int maxLineWidth = 0; for (int i = 0; i < (int)msg.size(); i++) { lineWidth += MAX(_font->getCharWidth(msg[i]), _font->getCharDataWidth(msg[i])); if (lineWidth > maxWidth) { if (message.contains(' ')) { while (msg[i] != ' ' && i > 0) { lineWidth -= MAX(_font->getCharWidth(msg[i]), _font->getCharDataWidth(msg[i])); message.deleteLastChar(); --i; } } else if (msg[i] != ' ') { // if it is a unique word int dashWidth = MAX(_font->getCharWidth('-'), _font->getCharDataWidth('-')); while (lineWidth + dashWidth > maxWidth) { lineWidth -= MAX(_font->getCharWidth(msg[i]), _font->getCharDataWidth(msg[i])); message.deleteLastChar(); --i; } message += '-'; } message += '\n'; _numberLines++; if (lineWidth > maxLineWidth) { maxLineWidth = lineWidth; } lineWidth = 0; continue; // don't add the space back } if (lineWidth > maxLineWidth) maxLineWidth = lineWidth; message += msg[i]; } // If the text object is a speech subtitle, the y parameter is the // coordinate of the bottom of the text block (instead of the top). It means // that every extra line pushes the previous lines up, instead of being // printed further down the screen. const int SCREEN_TOP_MARGIN = 16; if (_isSpeech) { _y -= _numberLines * _font->getHeight(); if (_y < SCREEN_TOP_MARGIN) { _y = SCREEN_TOP_MARGIN; } } _textObjectHandle = (GfxBase::TextObjectHandle **)malloc(sizeof(long) * _numberLines); _bitmapWidthPtr = new int[_numberLines]; for (int j = 0; j < _numberLines; j++) { int nextLinePos, cutLen; const char *pos = strchr(message.c_str(), '\n'); if (pos) { nextLinePos = pos - message.c_str(); cutLen = nextLinePos + 1; } else { nextLinePos = message.size(); cutLen = nextLinePos; } Common::String currentLine(message.c_str(), message.c_str() + nextLinePos); _bitmapWidthPtr[j] = 0; for (unsigned int i = 0; i < currentLine.size(); ++i) { _bitmapWidthPtr[j] += MAX(_font->getCharWidth(currentLine[i]), _font->getCharDataWidth(currentLine[i])); } _textBitmap = new uint8[_font->getHeight() * (_bitmapWidthPtr[j] + 1)]; memset(_textBitmap, 0, _font->getHeight() * (_bitmapWidthPtr[j] + 1)); // Fill bitmap int startOffset = 0; for (unsigned int d = 0; d < currentLine.size(); d++) { int ch = currentLine[d]; int8 startingLine = _font->getCharStartingLine(ch) + _font->getBaseOffsetY(); int32 charDataWidth = _font->getCharDataWidth(ch); int32 charWidth = _font->getCharWidth(ch); int8 startingCol = _font->getCharStartingCol(ch); for (int line = 0; line < _font->getCharDataHeight(ch); line++) { int offset = startOffset + ((_bitmapWidthPtr[j] + 1) * (line + startingLine)); for (int r = 0; r < charDataWidth; r++) { const byte pixel = *(_font->getCharData(ch) + r + (charDataWidth * line)); byte *dst = _textBitmap + offset + startingCol + r; if (*dst == 0 && pixel != 0) _textBitmap[offset + startingCol + r] = pixel; } if (line + startingLine >= _font->getHeight()) break; } startOffset += charWidth; } _textObjectHandle[j] = g_driver->createTextBitmap(_textBitmap, _bitmapWidthPtr[j] + 1, _font->getHeight(), _fgColor); delete[] _textBitmap; for (int count = 0; count < cutLen; count++) message.deleteChar(0); } _created = true; }
bool ScreenWindow::atEndOfOutput() const { return currentLine() == (lineCount()-windowLines()); }
bool ScreenWindow::isSelected( int column , int line ) { return _screen->isSelected( column , qMin(line + currentLine(),endWindowLine()) ); }
void ScreenWindow::getSelectionEnd( int& column , int& line ) { _screen->getSelectionEnd(column,line); line -= currentLine(); }
// return the index of the line at the end of this window, or if this window // goes beyond the end of the screen, the index of the line at the end // of the screen. // // when passing a line number to a Screen method, the line number should // never be more than endWindowLine() // int ScreenWindow::endWindowLine() const { return qMin(currentLine() + windowLines() - 1, lineCount() - 1); }
vector<VertexObject*> DivideAndConquerFor3DCH::find2DConvexHull( list<VertexObject*> *pointSet ) { vector<VertexObject*> upper; vector<VertexObject*> lower; list<VertexObject*>::iterator pointIter; D3DXVECTOR2 midLine( pointSet->back()->v->x - pointSet->front()->v->x, pointSet->back()->v->y - pointSet->front()->v->y ); for( pointIter = pointSet->begin(); pointIter != pointSet->end(); pointIter++ ) { D3DXVECTOR2 currentLine( (*pointIter)->v->x - pointSet->front()->v->x, (*pointIter)->v->y - pointSet->front()->v->y ); float crossProduct = midLine.x * currentLine.y - midLine.y * currentLine.x; if( crossProduct > 0 || (*pointIter) == pointSet->front() || (*pointIter) == pointSet->back() ) { upper.push_back( (*pointIter) ); } } list<VertexObject*>::reverse_iterator re_pointIter; midLine = D3DXVECTOR2( pointSet->front()->v->x - pointSet->back()->v->x, pointSet->front()->v->y - pointSet->back()->v->y ); for( re_pointIter = pointSet->rbegin(); re_pointIter != pointSet->rend(); re_pointIter++ ) { D3DXVECTOR2 currentLine( (*re_pointIter)->v->x - pointSet->back()->v->x, (*re_pointIter)->v->y - pointSet->back()->v->y ); float crossProduct = midLine.x * currentLine.y - midLine.y * currentLine.x; if( crossProduct > 0 || (*re_pointIter) == pointSet->front() || (*re_pointIter) == pointSet->back() ) { lower.push_back( (*re_pointIter) ); } } vector<VertexObject*> upperChain; vector<VertexObject*> lowerChain; upperChain.push_back( upper[ 0 ] ); upperChain.push_back( upper[ 1 ] ); for( int i = 2; i < upper.size(); i++ ) { for( ; upperChain.size() >= 2 ; ) { int upperChainSize = upperChain.size(); D3DXVECTOR2 currentLine( upper[ i ]->v->x - upperChain[ upperChainSize - 1 ]->v->x, upper[ i ]->v->y - upperChain[ upperChainSize - 1 ]->v->y ); D3DXVECTOR2 preLine( upperChain[ upperChainSize - 1 ]->v->x - upperChain[ upperChainSize - 2 ]->v->x, upperChain[ upperChainSize - 1 ]->v->y - upperChain[ upperChainSize - 2 ]->v->y ); float crossProduct = preLine.x * currentLine.y - preLine.y * currentLine.x; if( crossProduct > 0 ) { upperChain.pop_back(); } else { break; } } upperChain.push_back( upper[ i ] ); } lowerChain.push_back( lower[ 0 ] ); lowerChain.push_back( lower[ 1 ] ); for( int i = 2; i < lower.size(); i++ ) { for( ; lowerChain.size() >= 2 ; ) { int lowerChainSize = lowerChain.size(); D3DXVECTOR2 currentLine( lower[ i ]->v->x - lowerChain[ lowerChainSize - 1 ]->v->x, lower[ i ]->v->y - lowerChain[ lowerChainSize - 1 ]->v->y ); D3DXVECTOR2 preLine( lowerChain[ lowerChainSize - 1 ]->v->x - lowerChain[ lowerChainSize - 2 ]->v->x, lowerChain[ lowerChainSize - 1 ]->v->y - lowerChain[ lowerChainSize - 2 ]->v->y ); float crossProduct = preLine.x * currentLine.y - preLine.y * currentLine.x; if( crossProduct > 0 ) { lowerChain.pop_back(); } else { break; } } lowerChain.push_back( lower[ i ] ); } upperChain.pop_back(); lowerChain.pop_back(); for( int i = 0; i < lowerChain.size(); i++ ) { upperChain.push_back( lowerChain[ i ] ); } return upperChain; }
CC_FILE_ERROR SinusxFilter::loadFile(QString filename, ccHObject& container, LoadParameters& parameters) { //open file QFile file(filename); if (!file.open(QFile::ReadOnly)) return CC_FERR_READING; QTextStream stream(&file); QString currentLine("C"); ccPolyline* currentPoly = 0; ccPointCloud* currentVertices = 0; unsigned lineNumber = 0; CurveType curveType = INVALID; unsigned cpIndex = 0; CC_FILE_ERROR result = CC_FERR_NO_ERROR; CCVector3d Pshift(0,0,0); bool firstVertex = true; while (!currentLine.isEmpty() && file.error() == QFile::NoError) { currentLine = stream.readLine(); ++lineNumber; if (currentLine.startsWith("C ")) { //ignore comments continue; } else if (currentLine.startsWith("B")) { //new block if (currentPoly) { if ( currentVertices && currentVertices->size() != 0 && currentVertices->resize(currentVertices->size()) && currentPoly->addPointIndex(0,currentVertices->size()) ) { container.addChild(currentPoly); } else { delete currentPoly; } currentPoly = 0; currentVertices = 0; } //read type QStringList tokens = currentLine.split(QRegExp("\\s+"),QString::SkipEmptyParts); if (tokens.size() < 2 || tokens[1].length() > 1) { ccLog::Warning(QString("[SinusX] Line %1 is corrupted").arg(lineNumber)); result = CC_FERR_MALFORMED_FILE; continue; } QChar curveTypeChar = tokens[1].at(0); curveType = INVALID; if (curveTypeChar == SHORTCUT[CUREV_S]) curveType = CUREV_S; else if (curveTypeChar == SHORTCUT[CURVE_P]) curveType = CURVE_P; else if (curveTypeChar == SHORTCUT[CURVE_N]) curveType = CURVE_N; else if (curveTypeChar == SHORTCUT[CURVE_C]) curveType = CURVE_C; if (curveType == INVALID) { ccLog::Warning(QString("[SinusX] Unhandled curve type '%1' on line '%2'!").arg(curveTypeChar).arg(lineNumber)); result = CC_FERR_MALFORMED_FILE; continue; } //TODO: what about the local coordinate system and scale?! (7 last values) if (tokens.size() > 7) { } //block is ready currentVertices = new ccPointCloud("vertices"); currentPoly = new ccPolyline(currentVertices); currentPoly->addChild(currentVertices); currentVertices->setEnabled(false); cpIndex = 0; } else if (currentPoly) { if (currentLine.startsWith("CN")) { if (currentLine.length() > 3) { QString name = currentLine.right(currentLine.length()-3); currentPoly->setName(name); } } else if (currentLine.startsWith("CP")) { QStringList tokens = currentLine.split(QRegExp("\\s+"),QString::SkipEmptyParts); switch (cpIndex) { case 0: //first 'CP' line { //expected: CP + 'connected' + 'closed' flags bool ok = (tokens.size() == 3); if (ok) { bool ok1 = true, ok2 = true; int isConnected = tokens[1].toInt(&ok1); int isClosed = tokens[2].toInt(&ok2); ok = ok1 && ok2; if (ok) { if (isConnected == 0) { //points are not connected?! //--> we simply hide the polyline and display its vertices currentPoly->setVisible(false); currentVertices->setEnabled(true); } currentPoly->setClosed(isClosed != 0); } } if (!ok) { ccLog::Warning(QString("[SinusX] Line %1 is corrupted (expected: 'CP connected_flag closed_flag')").arg(lineNumber)); result = CC_FERR_MALFORMED_FILE; continue; } ++cpIndex; } break; case 1: //second 'CP' line { if (curveType == CUREV_S) { ++cpIndex; //no break: we go directly to the next case (cpIndex = 2) } else if (curveType == CURVE_P) { //nothing particular for profiles (they are not handled in the same way in CC!) ++cpIndex; break; } else if (curveType == CURVE_N) { //expected: CP + const_altitude bool ok = (tokens.size() == 2); if (ok) { double z = tokens[1].toDouble(&ok); if (ok) currentPoly->setMetaData(ccPolyline::MetaKeyConstAltitude(),QVariant(z)); } if (!ok) { ccLog::Warning(QString("[SinusX] Line %1 is corrupted (expected: 'CP const_altitude')").arg(lineNumber)); result = CC_FERR_MALFORMED_FILE; continue; } ++cpIndex; break; } else if (curveType == CURVE_C) { //skip the next 16 values int skipped = tokens.size()-1; //all but the 'CP' keyword while (skipped < 16 && !currentLine.isEmpty() && file.error() == QFile::NoError) { currentLine = stream.readLine(); ++lineNumber; tokens = currentLine.split(QRegExp("\\s+"),QString::SkipEmptyParts); skipped += tokens.size(); } assert(skipped == 16); //no more than 16 normally! ++cpIndex; break; } else { assert(false); ++cpIndex; break; } } case 2: { //CP + base plane: 0 = (XY), 1 = (YZ), 2 = (ZX) bool ok = (tokens.size() == 2); if (ok) { int vertDir = 2; QChar basePlaneChar = tokens[1].at(0); if (basePlaneChar == '0') vertDir = 2; else if (basePlaneChar == '1') vertDir = 0; else if (basePlaneChar == '2') vertDir = 1; else ok = false; if (ok) currentPoly->setMetaData(ccPolyline::MetaKeyUpDir(),QVariant(vertDir)); } if (!ok) { ccLog::Warning(QString("[SinusX] Line %1 is corrupted (expected: 'CP base_plane')").arg(lineNumber)); result = CC_FERR_MALFORMED_FILE; continue; } } ++cpIndex; break; default: //ignored break; } } else if (!currentLine.isEmpty()) { assert(currentVertices); //shoud be a point! QStringList tokens = currentLine.split(QRegExp("\\s+"),QString::SkipEmptyParts); bool ok = (tokens.size() == 4); if (ok) { CCVector3d Pd; Pd.x = tokens[0].toDouble(&ok); if (ok) { Pd.y = tokens[1].toDouble(&ok); if (ok) { Pd.z = tokens[2].toDouble(&ok); if (ok) { //resize vertex cloud if necessary if ( currentVertices->size() == currentVertices->capacity() && !currentVertices->reserve(currentVertices->size() + 10)) { delete currentPoly; return CC_FERR_NOT_ENOUGH_MEMORY; } //first point: check for 'big' coordinates if (firstVertex/*currentVertices->size() == 0*/) { firstVertex = false; if (HandleGlobalShift(Pd,Pshift,parameters)) { if (currentPoly) currentPoly->setGlobalShift(Pshift); else currentVertices->setGlobalShift(Pshift); ccLog::Warning("[SinusX::loadFile] Polyline has been recentered! Translation: (%.2f ; %.2f ; %.2f)",Pshift.x,Pshift.y,Pshift.z); } } currentVertices->addPoint(CCVector3::fromArray((Pd+Pshift).u)); } } } } if (!ok) { ccLog::Warning(QString("[SinusX] Line %1 is corrupted (expected: 'X Y Z Key ...')").arg(lineNumber)); result = CC_FERR_MALFORMED_FILE; continue; } } } } //don't forget the last polyline! if (currentPoly) { if ( currentVertices && currentVertices->size() != 0 && currentVertices->resize(currentVertices->size()) && currentPoly->addPointIndex(0,currentVertices->size()) ) { container.addChild(currentPoly); } } return result; }
void TextObject::setupText() { Common::String msg = LuaBase::instance()->parseMsgText(_textID.c_str(), NULL); Common::String message; // remove spaces (NULL_TEXT) from the end of the string, // while this helps make the string unique it screws up // text justification // remove char of id 13 from the end of the string, int pos = msg.size() - 1; while (pos >= 0 && (msg[pos] == ' ' || msg[pos] == 13)) { msg.deleteLastChar(); pos = msg.size() - 1; } delete[] _lines; if (msg.size() == 0) { _lines = NULL; return; } if (g_grim->getGameType() == GType_MONKEY4) { if (_x == 0) _x = 320; if (_y == 0) _y = 240; } // format the output message to incorporate line wrapping // (if necessary) for the text object const int SCREEN_WIDTH = _width ? _width : 640; const int SCREEN_MARGIN = 75; // If the speaker is too close to the edge of the screen we have to make // some room for the subtitles. if (_isSpeech){ if (_x < SCREEN_MARGIN) { _x = SCREEN_MARGIN; } else if (SCREEN_WIDTH - _x < SCREEN_MARGIN) { _x = SCREEN_WIDTH - SCREEN_MARGIN; } } // The maximum width for any line of text is determined by the justification // mode. Note that there are no left/right margins -- this is consistent // with GrimE. int maxWidth = 0; if (_justify == CENTER) { maxWidth = 2 * MIN(_x, SCREEN_WIDTH - _x); } else if (_justify == LJUSTIFY) { maxWidth = SCREEN_WIDTH - _x; } else if (_justify == RJUSTIFY) { maxWidth = _x; } // We break the message to lines not longer than maxWidth Common::String currLine; _numberLines = 1; int lineWidth = 0; int maxLineWidth = 0; for (uint i = 0; i < msg.size(); i++) { lineWidth += MAX(_font->getCharWidth(msg[i]), _font->getCharDataWidth(msg[i])); if (lineWidth > maxWidth) { bool wordSplit = false; if (currLine.contains(' ')) { while (msg[i] != ' ' && i > 0) { lineWidth -= MAX(_font->getCharWidth(msg[i]), _font->getCharDataWidth(msg[i])); message.deleteLastChar(); --i; } } else if (msg[i] != ' ') { // if it is a unique word int dashWidth = MAX(_font->getCharWidth('-'), _font->getCharDataWidth('-')); while (lineWidth + dashWidth > maxWidth) { lineWidth -= MAX(_font->getCharWidth(msg[i]), _font->getCharDataWidth(msg[i])); message.deleteLastChar(); --i; } message += '-'; wordSplit = true; } message += '\n'; currLine.clear(); _numberLines++; if (lineWidth > maxLineWidth) { maxLineWidth = lineWidth; } lineWidth = 0; if (wordSplit) { lineWidth += MAX(_font->getCharWidth(msg[i]), _font->getCharDataWidth(msg[i])); } else { continue; // don't add the space back } } if (lineWidth > maxLineWidth) maxLineWidth = lineWidth; message += msg[i]; currLine += msg[i]; } // If the text object is a speech subtitle, the y parameter is the // coordinate of the bottom of the text block (instead of the top). It means // that every extra line pushes the previous lines up, instead of being // printed further down the screen. const int SCREEN_TOP_MARGIN = 16; if (_isSpeech) { _y -= _numberLines * _font->getHeight(); if (_y < SCREEN_TOP_MARGIN) { _y = SCREEN_TOP_MARGIN; } } _lines = new Common::String[_numberLines]; for (int j = 0; j < _numberLines; j++) { int nextLinePos, cutLen; const char *breakPos = strchr(message.c_str(), '\n'); if (breakPos) { nextLinePos = breakPos - message.c_str(); cutLen = nextLinePos + 1; } else { nextLinePos = message.size(); cutLen = nextLinePos; } Common::String currentLine(message.c_str(), message.c_str() + nextLinePos); _lines[j] = currentLine; int width = _font->getStringLength(currentLine); if (width > _maxLineWidth) _maxLineWidth = width; for (int count = 0; count < cutLen; count++) message.deleteChar(0); } _elapsedTime = 0; }
std::vector<double> Pinger::runPingProcessInstance(const uint16_t requestCount, const double delay){ this->progressMutex.lock(); this->progress = 0; this->progressMutex.unlock(); /* if(delay < 0.2){ delay = 0.2;//on UNIX only root can run ping with delay less than 0.2 } */ std::string interval = std::to_string(delay); std::replace(interval.begin(), interval.end(), ',', '.'); std::string command = "ping -c " + std::to_string(requestCount + this->skip) + " -i " + interval + " " + this->host; command += " 2>&1";//redirect stderr to stdout FILE *ping_descriptor = popen(command.c_str(), "r"); if(ping_descriptor == nullptr){ std::lock_guard<std::mutex> lg(this->sysCallMutex); throw std::runtime_error(strerror(errno)); } const uint32_t bufferSize = 1000; std::unique_ptr<char> buffer(new char[bufferSize]); std::vector<double> lags; int32_t skipCounter = this->skip;//пропускаем первый результат double progressStep = 1.0 / (requestCount + skipCounter); do{ if(fgets(buffer.get(), bufferSize, ping_descriptor) != buffer.get() && ferror(ping_descriptor) != 0){ std::lock_guard<std::mutex> lg(this->sysCallMutex); throw std::runtime_error(strerror(errno)); } if(this->stopFlag) break; std::string currentLine(buffer.get()); if(currentLine.find("ping: ") == 0)//ping notified us about an error throw std::runtime_error(currentLine.substr(6)); std::pair<bool, double> lagTime = extractPingTime_ms(currentLine); if(lagTime.first){//если в строке было время - записываем его и посылаем сигнал this->progressMutex.lock(); if(this->progress + progressStep <= 1.0){//если шагов больше чем requestCount - не переполняем счетчик this->progress += progressStep; } this->progressMutex.unlock(); //skip, if required if(skipCounter --> 0)//brand new '-->' operator: "Goes to ..." continue; lags.push_back(lagTime.second); } }while(feof(ping_descriptor) == 0 && this->stopFlag == false); this->sysCallMutex.lock(); int status = pclose(ping_descriptor); int exitStatus = WEXITSTATUS(status); this->sysCallMutex.unlock(); if(exitStatus != 0){ throw std::runtime_error("Ping failed"); } if(this->stopFlag == false){ this->progressMutex.lock(); this->progress = 1.0; this->progressMutex.unlock(); } return lags; }