Beispiel #1
0
void OsmAnd::TextRasterizer_P::measureHalo(const Style& style, QVector<LinePaint>& paints) const
{
    for (auto& linePaint : paints)
    {
        linePaint.maxBoundsTop = 0;
        linePaint.minBoundsTop = std::numeric_limits<SkScalar>::max();

        for (auto& textPaint : linePaint.textPaints)
        {
            const auto haloPaint = getHaloPaint(textPaint.paint, style);

            SkPaint::FontMetrics metrics;
            textPaint.height = haloPaint.getFontMetrics(&metrics);
            linePaint.maxFontHeight = qMax(linePaint.maxFontHeight, textPaint.height);
            linePaint.minFontHeight = qMin(linePaint.minFontHeight, textPaint.height);
            linePaint.maxFontLineSpacing = qMax(linePaint.maxFontLineSpacing, metrics.fLeading);
            linePaint.minFontLineSpacing = qMin(linePaint.minFontLineSpacing, metrics.fLeading);
            linePaint.maxFontTop = qMax(linePaint.maxFontTop, -metrics.fTop);
            linePaint.minFontTop = qMin(linePaint.minFontTop, -metrics.fTop);
            linePaint.maxFontBottom = qMax(linePaint.maxFontBottom, metrics.fBottom);
            linePaint.minFontBottom = qMin(linePaint.minFontBottom, metrics.fBottom);

            SkRect haloBounds;
            haloPaint.measureText(
                textPaint.text.constData(),
                textPaint.text.length()*sizeof(QChar),
                &haloBounds);
            textPaint.bounds.join(haloBounds);

            linePaint.maxBoundsTop = qMax(linePaint.maxBoundsTop, -textPaint.bounds.top());
            linePaint.minBoundsTop = qMin(linePaint.minBoundsTop, -textPaint.bounds.top());
        }
    }
}
Beispiel #2
0
void WMeasurePaintDevice::drawText(const WRectF& rect,
				   WFlags<AlignmentFlag> flags,
				   TextFlag textFlag, const WString& text,
				   const WPointF *clipPoint)
{
  if (clipPoint && painter()) {
    if (!painter()->clipPathTransform().map(painter()->clipPath())
	  .isPointInPath(painter()->worldTransform().map(*clipPoint)))
      return;
  }

  double w = 0, h = 0;
  WString line = text;

  WFontMetrics fm = fontMetrics();

  for (;;) {
    WTextItem t = measureText(line, rect.width(),
			      textFlag == TextWordWrap ? true : false);

    h += fm.height();
    w = std::max(w, t.width());

    if (t.text() == line)
      break;
    else
      line = WString
	::fromUTF8(line.toUTF8().substr(t.text().toUTF8().length()));
  }

  AlignmentFlag horizontalAlign = flags & AlignHorizontalMask;
  AlignmentFlag verticalAlign = flags & AlignVerticalMask;

  double x, y;

  switch (horizontalAlign) {
  case AlignLeft:
    x = rect.left(); break;
  case AlignCenter:
    x = rect.left() + (rect.width() - w) / 2; break;
  case AlignRight:
  default:
    x = rect.right() - w; break;
  }

  switch (verticalAlign) {
  case AlignTop:
    y = rect.top(); break;
  case AlignMiddle:
    y = rect.top() + (rect.height() - h) / 2; break;
  case AlignBottom:
  default:
    y = rect.bottom() - h; break;
  }

  expandBounds(WRectF(x, y, w, h));
}
Beispiel #3
0
Font::FONT_RECT Font::measureText(const char* text) throw(invalid_argument, runtime_error) {

    ASSERT(
        (text != 0),
        invalid_argument("text")
    );

    return measureText(string(text));

}
Beispiel #4
0
Font::FONT_RECT Font::measureText(const wstring& wText) throw(runtime_error) {

    try {

        return measureText(wText.c_str());

    } catch(const invalid_argument&){}

    //return FTBBox();

}
int GUISliderValue::Render(void)
{
	if (!isConditionTrue())
	{
		mRendered = false;
		return 0;
	}

	if(mLabel)
	{
		int w, h;
		mLabel->GetCurrentBounds(w, h);
		if (w != mLabelW) {
			mLabelW = w;
			int textX = mRenderX + (mRenderW/2 - mLabelW/2);
			mLabel->SetRenderPos(textX, mRenderY);
		}
		int res = mLabel->Render();
		if(res < 0)
			return res;
	}

	// line
	gr_color(mLineColor.red, mLineColor.green, mLineColor.blue, mLineColor.alpha);
	gr_fill(mLineX, mLineY, lineW, mLineH);

	// slider
	uint32_t sliderX = (mValuePct*lineW)/100 + mLineX;
	sliderX -= mSliderW/2;

	gr_color(mSliderColor.red, mSliderColor.green, mSliderColor.blue, mSliderColor.alpha);
	gr_fill(sliderX, mSliderY, mSliderW, mSliderH);

	void *fontResource = NULL;
	if(mFont) fontResource = mFont->GetResource();
	gr_color(mTextColor.red, mTextColor.green, mTextColor.blue, mTextColor.alpha);
	if(mShowRange)
	{
		int rangeY = (mLineY - mLineH/2) - mFontHeight/2;
		gr_textEx(mRenderX + mPadding/2, rangeY, mMinStr.c_str(), fontResource);
		gr_textEx(mLineX + lineW + mPadding/2, rangeY, mMaxStr.c_str(), fontResource);
	}

	if(mValueStr && mShowCurr)
	{
		sprintf(mValueStr, "%d", mValue);
		int textW = measureText(mValueStr);
		gr_textEx(mRenderX + (mRenderW/2 - textW/2), mSliderY+mSliderH, mValueStr, fontResource);
	}

	mRendered = true;
	return 0;
}
int BaseFontTT::getTextHeight(const byte *text, int width) {
	WideString textStr;

	if (_gameRef->_textEncoding == TEXT_UTF8) {
		textStr = StringUtil::utf8ToWide((const char *)text);
	} else {
		textStr = StringUtil::ansiToWide((const char *)text);
	}


	int textWidth, textHeight;
	measureText(textStr, width, -1, textWidth, textHeight);

	return textHeight;
}
Beispiel #7
0
void Font::renderText(const wchar_t* wText, float x, float y, float width, float height) throw(invalid_argument, runtime_error) {

    ASSERT(
        (wText != 0),
        invalid_argument("wText")
    );

    std::lock_guard<std::mutex> guard(synchroMutex_);

    if(font_ == 0) {
        return;
    }

    size_t textLen = wcslen(wText);

    if(width >= 0.0f) {

        Font::FONT_RECT rect = measureText(wText);

        if(rect.width > width) {

            float pixPerChar     = rect.width / textLen;

            float excess         = rect.width - width;

            size_t charsForErase = static_cast<size_t>(lround(excess / pixPerChar));

            textLen -= charsForErase;

        }

    }

    glPushMatrix();
    glPushAttrib(GL_COLOR_BUFFER_BIT);

    glColor3fv(color_.c_array());

    font_->Render(wText,
                    textLen,
                    FTPoint(static_cast<FTGL_FLOAT>(x), static_cast<FTGL_FLOAT>(y)),
                    FTPoint(),
                    FTGL::RENDER_ALL);

    glPopAttrib();
    glPopMatrix();

}
int BaseFontTT::getTextWidth(const byte *text, int maxLength) {
	WideString textStr;

	if (_gameRef->_textEncoding == TEXT_UTF8) {
		textStr = StringUtil::utf8ToWide((const char *)text);
	} else {
		textStr = StringUtil::ansiToWide((const char *)text);
	}

	if (maxLength >= 0 && textStr.size() > (uint32)maxLength) {
		textStr = WideString(textStr.c_str(), (uint32)maxLength);
	}
	//text = text.substr(0, MaxLength); // TODO: Remove

	int textWidth, textHeight;
	measureText(textStr, -1, -1, textWidth, textHeight);

	return textWidth;
}
Beispiel #9
0
Font::FONT_RECT Font::measureText(const string& text) throw(runtime_error) {

    return measureText(UTF8_to_UTF16(text));

}
Beispiel #10
0
/*
** Create a dialog for the output of a shell command.  The dialog lives until
** the user presses the Dismiss button, and is then destroyed
*/
static void createOutputDialog(Widget parent, char *text)
{
    Arg al[50];
    int ac, rows, cols, hasScrollBar, wrapped;
    Widget form, textW, button;
    XmString st1;

    /* measure the width and height of the text to determine size for dialog */
    measureText(text, MAX_OUT_DIALOG_COLS, &rows, &cols, &wrapped);
    if (rows > MAX_OUT_DIALOG_ROWS) {
    	rows = MAX_OUT_DIALOG_ROWS;
    	hasScrollBar = True;
    } else
    	hasScrollBar = False;
    if (cols > MAX_OUT_DIALOG_COLS)
    	cols = MAX_OUT_DIALOG_COLS;
    if (cols == 0)
    	cols = 1;
    /* Without completely emulating Motif's wrapping algorithm, we can't
       be sure that we haven't underestimated the number of lines in case
       a line has wrapped, so let's assume that some lines could be obscured
       */
    if (wrapped)
	hasScrollBar = True;
    ac = 0;
    form = CreateFormDialog(parent, "shellOutForm", al, ac);

    ac = 0;
    XtSetArg(al[ac], XmNlabelString, st1=MKSTRING("OK")); ac++;
    XtSetArg(al[ac], XmNmarginWidth, BUTTON_WIDTH_MARGIN); ac++;
    XtSetArg(al[ac], XmNhighlightThickness, 0);  ac++;
    XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_FORM);  ac++;
    XtSetArg(al[ac], XmNtopAttachment, XmATTACH_NONE);  ac++;
    button = XmCreatePushButtonGadget(form, "ok", al, ac);
    XtManageChild(button);
    XtVaSetValues(form, XmNdefaultButton, button, NULL);
    XtVaSetValues(form, XmNcancelButton, button, NULL);
    XmStringFree(st1);
    XtAddCallback(button, XmNactivateCallback, destroyOutDialogCB,
    	    XtParent(form));
    
    ac = 0;
    XtSetArg(al[ac], XmNrows, rows);  ac++;
    XtSetArg(al[ac], XmNcolumns, cols);  ac++;
    XtSetArg(al[ac], XmNresizeHeight, False);  ac++;
    XtSetArg(al[ac], XmNtraversalOn, False); ac++;
    XtSetArg(al[ac], XmNwordWrap, True);  ac++;
    XtSetArg(al[ac], XmNscrollHorizontal, False);  ac++;
    XtSetArg(al[ac], XmNscrollVertical, hasScrollBar);  ac++;
    XtSetArg(al[ac], XmNhighlightThickness, 0);  ac++;
    XtSetArg(al[ac], XmNspacing, 0);  ac++;
    XtSetArg(al[ac], XmNeditMode, XmMULTI_LINE_EDIT);  ac++;
    XtSetArg(al[ac], XmNeditable, False);  ac++;
    XtSetArg(al[ac], XmNvalue, text);  ac++;
    XtSetArg(al[ac], XmNtopAttachment, XmATTACH_FORM);  ac++;
    XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM);  ac++;
    XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_WIDGET);  ac++;
    XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM);  ac++;
    XtSetArg(al[ac], XmNbottomWidget, button);  ac++;
    textW = XmCreateScrolledText(form, "outText", al, ac);
    AddMouseWheelSupport(textW);
    XtManageChild(textW);
    
    XtVaSetValues(XtParent(form), XmNtitle, "Output from Command", NULL);
    ManageDialogCenteredOnPointer(form);
}
GUISliderValue::GUISliderValue(xml_node<>* node) : GUIObject(node)
{
	xml_attribute<>* attr;
	xml_node<>* child;

	mMin = 0;
	mMax = 100;
	mValue = 0;
	mLineH = 2;
	mLinePadding = 10;
	mSliderW = 5;
	mSliderH = 30;
	mLineX = 0;
	mLineY = 0;
	mValueStr = NULL;
	mAction = NULL;
	mShowCurr = true;
	mShowRange = false;
	mChangeOnDrag = false;
	mRendered = false;

	mLabel = NULL;
	ConvertStrToColor("white", &mTextColor);
	ConvertStrToColor("white", &mLineColor);
	ConvertStrToColor("blue", &mSliderColor);

	if (!node)
	{
		LOGERR("GUISliderValue created without XML node\n");
		return;
	}

	mLabel = new GUIText(node);
	if(mLabel->Render() < 0)
	{
		delete mLabel;
		mLabel = NULL;
	}

	mAction = new GUIAction(node);

	child = node->first_node("font");
	if (child)
	{
		attr = child->first_attribute("resource");
		if (attr)
			mFont = PageManager::FindResource(attr->value());

		attr = child->first_attribute("color");
		if (attr)
		{
			std::string color = attr->value();
			ConvertStrToColor(color, &mTextColor);
		}
	}

	// Load the placement
	LoadPlacement(node->first_node("placement"), &mRenderX, &mRenderY, &mRenderW);

	child = node->first_node("colors");
	if (child)
	{
		attr = child->first_attribute("line");
		if (attr)
			ConvertStrToColor(attr->value(), &mLineColor);

		attr = child->first_attribute("slider");
		if (attr)
			ConvertStrToColor(attr->value(), &mSliderColor);
	}

	child = node->first_node("data");
	if (child)
	{
		attr = child->first_attribute("variable");
		if (attr)
			mVariable = attr->value();

		attr = child->first_attribute("min");
		if (attr)
		{
			mMinStr = gui_parse_text(attr->value());
			mMin = atoi(mMinStr.c_str());
		}

		attr = child->first_attribute("max");
		if (attr)
		{
			mMaxStr = gui_parse_text(attr->value());
			mMax = atoi(mMaxStr.c_str());
		}

		if (mMin > mMax)
			mMin = mMax;

		attr = child->first_attribute("default");
		if (attr)
		{
			string parsevalue = gui_parse_text(attr->value());
			int def = atoi(parsevalue.c_str());

			if (def < mMin)      def = mMin;
			else if (def > mMax) def = mMax;
			DataManager::SetValue(mVariable, def);
		}

		attr = child->first_attribute("showrange");
		if (attr)
			mShowRange = atoi(attr->value());

		attr = child->first_attribute("showcurr");
		if (attr)
			mShowCurr = atoi(attr->value());

		attr = child->first_attribute("changeondrag");
		if (attr)
			mChangeOnDrag = atoi(attr->value());
	}

	child = node->first_node("dimensions");
	if (child)
	{
		attr = child->first_attribute("lineh");
		if (attr)
		{
			string parsevalue = gui_parse_text(attr->value());
			mLineH = atoi(parsevalue.c_str());
		}

		attr = child->first_attribute("linepadding");
		if (attr)
		{
			string parsevalue = gui_parse_text(attr->value());
			mPadding = atoi(parsevalue.c_str());
		}

		attr = child->first_attribute("sliderw");
		if (attr)
		{
			string parsevalue = gui_parse_text(attr->value());
			mSliderW = atoi(parsevalue.c_str());
		}

		attr = child->first_attribute("sliderh");
		if (attr)
		{
			string parsevalue = gui_parse_text(attr->value());
			mSliderH = atoi(parsevalue.c_str());
		}
	}

	gr_getFontDetails(mFont ? mFont->GetResource() : NULL, (unsigned*) &mFontHeight, NULL);

	if(mShowCurr)
	{
		int maxLen = std::max(strlen(mMinStr.c_str()), strlen(mMaxStr.c_str()));
		mValueStr = new char[maxLen+1];
	}

	loadValue(true);

	mLinePadding = mPadding;
	if (mShowRange)
	{
		int textW = std::max(measureText(mMaxStr), measureText(mMinStr));
		mLinePadding += textW;
	}

	SetRenderPos(mRenderX, mRenderY, mRenderW);
}
Beispiel #12
0
WTextItem FontSupport::measureText(const WFont& font, const WString& text,
				   double maxWidth, bool wordWrap)
{
  PANGO_LOCK;

  enabledFontFormats = enabledFontFormats_;

  /*
   * Note: accurate measuring on a bitmap requires that the transformation
   * is applied, because hinting may push chars to boundaries e.g. when
   * rotated (or scaled too?)
   */
  std::string utf8 = text.toUTF8();
  const char *s = utf8.c_str();

  if (wordWrap) {
    int utflen = g_utf8_strlen(s, -1);
    PangoLogAttr *attrs = new PangoLogAttr[utflen + 1];
    PangoLanguage *language = pango_language_from_string("en-US");

    pango_get_log_attrs(s, utf8.length(), -1, language, attrs, utflen + 1);

    double w = 0, nextW = -1;

    int current = 0;
    int measured = 0;
    int end = 0;

    bool maxWidthReached = false;

    for (int i = 0; i < utflen + 1; ++i) {
      if (i == utflen || attrs[i].is_line_break) {
	int cend = g_utf8_offset_to_pointer(s, end) - s;

	WTextItem ti
	  = measureText(font, WString::fromUTF8(utf8.substr(measured,
							    cend - measured)),
			-1, false);

	if (isEpsilonMore(w + ti.width(), maxWidth)) {
	  nextW = ti.width();
	  maxWidthReached = true;
	  break;
	} else {
	  measured = cend;
	  current = g_utf8_offset_to_pointer(s, i) - s;
	  w += ti.width();

	  if (i == utflen) {
	    w += measureText(font, WString::fromUTF8(utf8.substr(measured)),
			     -1, false).width();
	    measured = utf8.length();
	  }
	}
      }

      if (!attrs[i].is_white)
	end = i + 1;
    }

    delete[] attrs;

    if (maxWidthReached) {
      return WTextItem(WString::fromUTF8(utf8.substr(0, current)), w, nextW);
    } else {
      /*
       * For some reason, the sum of the individual widths is a bit less
       * (for longer stretches of text), so we re-measure it !
       */
      w = measureText(font, WString::fromUTF8(utf8.substr(0, measured)),
		      -1, false).width();
      return WTextItem(text, w);
    }
  } else {
    std::vector<PangoGlyphString *> glyphs;
    int width;

    GList *items = layoutText(font, utf8, glyphs, width);

    double w = pangoUnitsToDouble(width);

    for (unsigned i = 0; i < glyphs.size(); ++i)
      pango_glyph_string_free(glyphs[i]);

    g_list_foreach(items, (GFunc) pango_item_free, nullptr);
    g_list_free(items);

    return WTextItem(text, w);
  }
}
Beispiel #13
0
void Dashboard::measureText(const string& text, int size, bool mono, int& width, int& height)
{
    measureText(text.c_str(), size, mono, width, height);
}
Beispiel #14
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;
}