/**
 * This function is called when the visual item was positioned in the
 * backpack.
 */
void WeaponBackpackItem::updated(void)
{
	if(!mText) return;

	// here we have to put the number of units if we can
	Ogre::String str;
	getAmmoText(str);
	if(str.empty()){
		// hide the text?
		return;
	}
	// set the text
	mText->setCaption(str);
	positionText();
}
Example #2
0
bool OsmAnd::TextRasterizer_P::rasterize(
    SkBitmap& targetBitmap,
    const QString& text_,
    const Style& style,
    QVector<SkScalar>* const outGlyphWidths,
    float* const outExtraTopSpace,
    float* const outExtraBottomSpace,
    float* const outLineSpacing) const
{
    // Prepare text and break by lines
    const auto text = ICU::convertToVisualOrder(text_);
    const auto lineRefs = style.wrapWidth > 0
                          ? ICU::getTextWrappingRefs(text, style.wrapWidth)
                          : (QVector<QStringRef>() << QStringRef(&text));

    // Obtain paints from lines and style
    auto paints = evaluatePaints(lineRefs, style);

    // Measure text
    SkScalar maxLineWidthInPixels = 0;
    measureText(paints, maxLineWidthInPixels);

    // Measure glyphs (if requested and there's no halo)
    if (outGlyphWidths && style.haloRadius == 0)
        measureGlyphs(paints, *outGlyphWidths);

    // Process halo if exists
    if (style.haloRadius > 0)
    {
        measureHalo(style, paints);

        if (outGlyphWidths)
            measureHaloGlyphs(style, paints, *outGlyphWidths);
    }

    // Set output line spacing
    if (outLineSpacing)
    {
        float lineSpacing = 0.0f;
        for (const auto& linePaint : constOf(paints))
            lineSpacing = qMax(lineSpacing, linePaint.maxFontLineSpacing);

        *outLineSpacing = lineSpacing;
    }

    // Calculate extra top and bottom space
    if (outExtraTopSpace)
    {
        SkScalar maxTop = 0;
        for (const auto& linePaint : constOf(paints))
            maxTop = qMax(maxTop, linePaint.maxFontTop);

        *outExtraTopSpace = qMax(0.0f, maxTop - paints.first().maxFontTop);
    }
    if (outExtraBottomSpace)
    {
        SkScalar maxBottom = 0;
        for (const auto& linePaint : constOf(paints))
            maxBottom = qMax(maxBottom, linePaint.maxFontBottom);

        *outExtraBottomSpace = qMax(0.0f, maxBottom - paints.last().maxFontBottom);
    }

    // Position text horizontally and vertically
    const auto textArea = positionText(paints, maxLineWidthInPixels, style.textAlignment);

    // Calculate bitmap size
    auto bitmapWidth = qCeil(textArea.width());
    auto bitmapHeight = qCeil(textArea.height());
    if (style.backgroundBitmap)
    {
        // Clear extra spacing
        if (outExtraTopSpace)
            *outExtraTopSpace = 0.0f;
        if (outExtraBottomSpace)
            *outExtraBottomSpace = 0.0f;

        // Enlarge bitmap if shield is larger than text
        bitmapWidth = qMax(bitmapWidth, style.backgroundBitmap->width());
        bitmapHeight = qMax(bitmapHeight, style.backgroundBitmap->height());

        // Shift text area to proper position in a larger
        const auto offset = SkPoint::Make(
                                (bitmapWidth - qCeil(textArea.width())) / 2.0f,
                                (bitmapHeight - qCeil(textArea.height())) / 2.0f);
        for (auto& linePaint : paints)
        {
            for (auto& textPaint : linePaint.textPaints)
                textPaint.positionedBounds.offset(offset);
        }
    }

    // Check if bitmap size was successfully calculated
    if (bitmapWidth <= 0 || bitmapHeight <= 0)
    {
        LogPrintf(LogSeverityLevel::Error,
                  "Failed to rasterize text '%s': resulting bitmap size %dx%d is invalid",
                  qPrintable(text),
                  bitmapWidth,
                  bitmapHeight);
        return false;
    }

    // Create a bitmap that will be hold entire symbol (if target is empty)
    if (targetBitmap.isNull())
    {
        if (!targetBitmap.tryAllocPixels(SkImageInfo::MakeN32Premul(bitmapWidth, bitmapHeight)))
        {
            LogPrintf(LogSeverityLevel::Error,
                      "Failed to allocate bitmap of size %dx%d",
                      qPrintable(text),
                      bitmapWidth,
                      bitmapHeight);
            return false;
        }

        targetBitmap.eraseColor(SK_ColorTRANSPARENT);
    }
    SkBitmapDevice target(targetBitmap);
    SkCanvas canvas(&target);

    // If there is background this text, rasterize it also
    if (style.backgroundBitmap)
    {
        canvas.drawBitmap(*style.backgroundBitmap,
                          (bitmapWidth - style.backgroundBitmap->width()) / 2.0f,
                          (bitmapHeight - style.backgroundBitmap->height()) / 2.0f,
                          nullptr);
    }

    // Rasterize text halo first (if enabled)
    if (style.haloRadius > 0)
    {
        for (const auto& linePaint : paints)
        {
            for (const auto& textPaint : linePaint.textPaints)
            {
                const auto haloPaint = getHaloPaint(textPaint.paint, style);

                canvas.drawText(
                    textPaint.text.constData(), textPaint.text.length()*sizeof(QChar),
                    textPaint.positionedBounds.left(), textPaint.positionedBounds.top(),
                    haloPaint);
            }
        }
    }

    // Rasterize text itself
    for (const auto& linePaint : paints)
    {
        for (const auto& textPaint : linePaint.textPaints)
        {
            canvas.drawText(
                textPaint.text.constData(), textPaint.text.length()*sizeof(QChar),
                textPaint.positionedBounds.left(), textPaint.positionedBounds.top(),
                textPaint.paint);
        }
    }

    canvas.flush();

    return true;
}