QString StatusLabel::squeeze(const QString& s, const QFontMetrics& fm, uint width) {
  uint currentWidth = fm.width(s);
  
  if (s.isEmpty() || currentWidth <= width) {
     return s;
  }

  QString str(s);
  uint ellipsisWidth = fm.width("...");
  
  if (currentWidth > ellipsisWidth) {
    const uint maxWidth = width - ellipsisWidth;
    const uint emWidth  = fm.maxWidth( );
    int truncate;
  
    while (currentWidth > maxWidth && !str.isEmpty()) {
      truncate = (currentWidth-maxWidth)/emWidth;
      if (truncate == 0) {
        truncate = 1;
      }
      str.truncate(str.length()-truncate);  
      currentWidth = fm.width(str); 
    }
    str += "...";
  } else {
    str = "...";
  }
    
  return str;
}
void FreyaMessageDialog::DefinitionContent(const QString &content)
{
    QFontMetrics fm = m_ContentLab->fontMetrics();
    int w = fm.maxWidth()+20;
    int h = fm.height();
    int l = content.length();
    int c = qSqrt(l*w*1.0 / (3.0 * h));
    int l1 = l/c;
    m_ContentLab->setText(content);
    m_ContentLab->setFixedSize(w*l1, h*c);
}
void FontRowTable::setRow(int r)
{
    row = r;

    QFontMetrics fm = fontMetrics();
    QString str;
    str.sprintf("mLB=%d mRB=%d mW=%d",
	fm.minLeftBearing(),
	fm.minRightBearing(),
	fm.maxWidth()
	);
	
    emit fontInformation(str);
    update();
}
Exemple #4
0
/**
 * dependant on the screen rotation place the dots
 */
static QString g_insert_ldot( const QString& name, const QFontMetrics& fontMetrics ) {
    uint  maxPixels = qApp->desktop()->width()-90;
    uint nameWidth = fontMetrics.width(name);

    if (maxPixels < nameWidth) {
        QString tmp = name;
        const uint em = fontMetrics.maxWidth();
        maxPixels -= fontMetrics.width("...");

        while (maxPixels < nameWidth && !tmp.isEmpty()) {
            int delta = (nameWidth - maxPixels) / em;
            delta = kClamp(delta, 1, delta); // no max

            tmp.remove(0, delta);
            nameWidth = fontMetrics.width(tmp);
        }

        return ("..." + tmp);
    }

    return name;
}
QSize TopicEdit::minimumSizeHint() const
{
    QFontMetrics fm = fontMetrics();
    int m = frameWidth() * 2;
    return QSize( fm.maxWidth() + m, fm.height() + QMAX( 2*1, fm.leading()) +  m );
}
void StelQGLRenderer::drawText(const TextParams& params)
{
	statistics[TEXT_DRAWS] += 1.0;
	StelQGLTextureBackend* currentTexture = currentlyBoundTextures[0];

	if(params.string_.length() == 0)
	{
		return;
	}

	viewport.enablePainting();
	if(currentFontSet)
	{
		viewport.setFont(currentFont);
	}
	QPainter* painter = viewport.getPainter();
	Q_ASSERT_X(NULL != painter, Q_FUNC_INFO, 
	           "Trying to draw text but painting is disabled");

	QFontMetrics fontMetrics = painter->fontMetrics();

	StelProjectorP projector = NULL == params.projector_
	                         ? StelApp::getInstance().getCore()->getProjection2d() 
	                         : params.projector_;
	Vec3f win;
	if(params.doNotProject_) 
	{
		win = params.position_;
	}
	else if(!projector->project(params.position_, win))
	{
		viewport.disablePainting();
		return;
	}

	const int x = win[0];
	const int y = win[1];

	// Avoid drawing if outside viewport.
	// We do a worst-case approximation as getting exact text dimensions is expensive.
	// We also account for rotation by assuming the worst case in bot X and Y 
	// (culling with a rotating rectangle would be expensive)
	const int cullDistance = 
		std::max(fontMetrics.height(), params.string_.size() * fontMetrics.maxWidth());
	const Vec4i viewXywh = projector->getViewportXywh();
	const int viewMinX = viewXywh[0];
	const int viewMinY = viewXywh[1];
	const int viewMaxX = viewMinX + viewXywh[2];
	const int viewMaxY = viewMinY + viewXywh[3];

	if(y + cullDistance < viewMinY || y - cullDistance > viewMaxY ||
	   x + cullDistance < viewMinX || x - cullDistance > viewMaxX)
	{
		viewport.disablePainting();
		return;
	}

	if(projector->useGravityLabels() && !params.noGravity_)
	{
		drawTextGravityHelper(params, *painter, x, y, projector);
		return;
	}
	
	const int pixelSize   = painter->font().pixelSize();
	// Strings drawn by drawText() can differ by text, font size, or the font itself.
	const QByteArray hash = params.string_.toUtf8() + QByteArray::number(pixelSize) + 
	                        painter->font().family().toUtf8();
	StelQGLTextureBackend* textTexture = textTextureCache.object(hash);

	// No texture in cache for this string, need to draw it.
	if (NULL == textTexture) 
	{
		const QRect extents = fontMetrics.boundingRect(params.string_);

		// Width and height of the text. 
		// Texture width/height is required to be at least equal to this.
		//
		// Both X and Y need to be at least 1 so we don't create an empty image 
		// (doesn't work with textures)
		const int requiredWidth  = std::max(1, extents.width() + 1 + static_cast<int>(0.02f * extents.width()));
		const int requiredHeight = std::max(1, extents.height());
		// Create temporary image and render text into it

		// QImage is used solely to reuse existing QGLTextureBackend constructor 
		// function. QPixmap could be used as well (not sure which is faster, 
		// needs profiling)
		QImage image = areNonPowerOfTwoTexturesSupported() 
		             ? QImage(requiredWidth, requiredHeight, QImage::Format_ARGB32_Premultiplied) 
		             : QImage(StelUtils::smallestPowerOfTwoGreaterOrEqualTo(requiredWidth), 
		                      StelUtils::smallestPowerOfTwoGreaterOrEqualTo(requiredHeight),
		                      QImage::Format_ARGB32);
		image.fill(Qt::transparent);

		QPainter fontPainter(&image);
		fontPainter.setFont(painter->font());
		fontPainter.setRenderHints(QPainter::TextAntialiasing, true);
		fontPainter.setPen(Qt::white);

		// The second argument ensures the text is positioned correctly even if 
		// the image is enlarged to power-of-two.
		fontPainter.drawText(-extents.x(), 
		                     image.height() - requiredHeight - extents.y(), 
		                     params.string_);

		textTexture = StelQGLTextureBackend::constructFromImage
			(this, QString(), TextureParams().filtering(TextureFiltering_Linear), image);
		const QSize size = textTexture->getDimensions();
		if(!textTexture->getStatus() == TextureStatus_Loaded)
		{
			qWarning() << "Texture error: " << textTexture->getErrorMessage();
			Q_ASSERT_X(false, Q_FUNC_INFO, "Failed to construct a text texture");
		}
		textTextureCache.insert(hash, textTexture, 4 * size.width() * size.height());
	}

	// Even if NPOT textures are not supported, we always draw the full rectangle 
	// of the texture. The extra space is fully transparent, so it's not an issue.

	// Shortcut variables to calculate the rectangle.
	const QSize size   = textTexture->getDimensions();
	const float w      = size.width();
	const float h      = size.height();
	const float xShift = params.xShift_;
	const float yShift = params.yShift_;

	const float angleDegrees = 
		params.angleDegrees_ + 
		(params.noGravity_ ? 0.0f : projector->getDefaultAngleForGravityText());
	// Zero out very small angles.
	// 
	// (this could also be used to optimize the case with zero angled
	//  to avoid sin/cos if needed)
	const bool  angled = std::fabs(angleDegrees) >= 1.0f * M_PI / 180.f;
	const float cosr   = angled  ? std::cos(angleDegrees * M_PI / 180.0) : 1.0f;
	const float sinr   = angled  ? std::sin(angleDegrees * M_PI / 180.0) : 0.0f;

	// Corners of the (possibly rotated) texture rectangle.
	const Vec2f ne(round(x + cosr * xShift       - sinr * yShift),
	               round(y + sinr * xShift       + cosr * yShift));
	const Vec2f nw(round(x + cosr * (w + xShift) - sinr * yShift),
	               round(y + sinr * (w + xShift) + cosr * yShift));
	const Vec2f se(round(x + cosr * xShift       - sinr * (h + yShift)),
	               round(y + sinr * xShift       + cosr * (h + yShift)));
	const Vec2f sw(round(x + cosr * (w + xShift) - sinr * (h + yShift)),
	               round(y + sinr * (w + xShift) + cosr * (h + yShift)));

	// Construct the text vertex buffer if it doesn't exist yet, otherwise clear it.
	if(NULL == textBuffer)
	{
		textBuffer = createVertexBuffer<TexturedVertex>(PrimitiveType_TriangleStrip);
	}
	else
	{
		textBuffer->unlock();
		textBuffer->clear();
	}

	textBuffer->addVertex(TexturedVertex(ne, Vec2f(0.0f, 0.0f)));
	textBuffer->addVertex(TexturedVertex(nw, Vec2f(1.0f, 0.0f)));
	textBuffer->addVertex(TexturedVertex(se, Vec2f(0.0f, 1.0f)));
	textBuffer->addVertex(TexturedVertex(sw, Vec2f(1.0f, 1.0f)));
	textBuffer->lock();

	// Draw.
	const BlendMode oldBlendMode = blendMode;
	setBlendMode(BlendMode_Alpha);
	textTexture->bind(0);
	drawVertexBuffer(textBuffer);
	setBlendMode(oldBlendMode);

	// Reset user-bound texture.
	if(NULL != currentTexture)
	{
		currentTexture->bind(0);
	}
	viewport.disablePainting();
}
QSize FontRowTable::cellSize() const
{
    QFontMetrics fm = fontMetrics();
    return QSize( fm.maxWidth(), fm.lineSpacing()+1 );
}