static float getAverageY (const Font& font, const char* chars, bool getTop) { GlyphArrangement ga; ga.addLineOfText (font, chars, 0, 0); Array<float> y; DefaultElementComparator<float> sorter; for (int i = 0; i < ga.getNumGlyphs(); ++i) { Path p; ga.getGlyph (i).createPath (p); Rectangle<float> bounds (p.getBounds()); if (! p.isEmpty()) y.addSorted (sorter, getTop ? bounds.getY() : bounds.getBottom()); } float median = y[y.size() / 2]; float total = 0; int num = 0; for (int i = 0; i < y.size(); ++i) { if (std::abs (median - y.getUnchecked(i)) < 0.05f * (float) standardHeight) { total += y.getUnchecked(i); ++num; } } return num < 4 ? 0.0f : total / (num * (float) standardHeight); }
void paint (Graphics& g) override { double startTime = 0.0; { // A ScopedSaveState will return the Graphics context to the state it was at the time of // construction when it goes out of scope. We use it here to avoid clipping the fps text const Graphics::ScopedSaveState state (g); if (controls.clipToRectangle.getToggleState()) clipToRectangle (g); if (controls.clipToPath .getToggleState()) clipToPath (g); if (controls.clipToImage .getToggleState()) clipToImage (g); g.setImageResamplingQuality (controls.quality.getToggleState() ? Graphics::highResamplingQuality : Graphics::mediumResamplingQuality); // take a note of the time before the render startTime = Time::getMillisecondCounterHiRes(); // then let the demo draw itself.. drawDemo (g); } double now = Time::getMillisecondCounterHiRes(); double filtering = 0.08; const double elapsedMs = now - startTime; averageTimeMs += (elapsedMs - averageTimeMs) * filtering; const double sinceLastRender = now - lastRenderStartTime; lastRenderStartTime = now; const double effectiveFPS = 1000.0 / averageTimeMs; const double actualFPS = sinceLastRender > 0 ? (1000.0 / sinceLastRender) : 0; averageActualFPS += (actualFPS - averageActualFPS) * filtering; GlyphArrangement ga; ga.addFittedText (displayFont, "Time: " + String (averageTimeMs, 2) + " ms\nEffective FPS: " + String (effectiveFPS, 1) + "\nActual FPS: " + String (averageActualFPS, 1), 0, 10.0f, getWidth() - 10.0f, (float) getHeight(), Justification::topRight, 3); g.setColour (Colours::white.withAlpha (0.5f)); g.fillRect (ga.getBoundingBox (0, ga.getNumGlyphs(), true).getSmallestIntegerContainer().expanded (4)); g.setColour (Colours::black); ga.draw (g); }
void Graphics::drawText (const String& text, const Rectangle<float>& area, Justification justificationType, bool useEllipsesIfTooBig) const { if (text.isNotEmpty() && context.clipRegionIntersects (area.getSmallestIntegerContainer())) { GlyphArrangement arr; arr.addCurtailedLineOfText (context.getFont(), text, 0.0f, 0.0f, area.getWidth(), useEllipsesIfTooBig); arr.justifyGlyphs (0, arr.getNumGlyphs(), area.getX(), area.getY(), area.getWidth(), area.getHeight(), justificationType); arr.draw (*this); } }
void Graphics::drawText (const String& text, const int x, const int y, const int width, const int height, const Justification& justificationType, const bool useEllipsesIfTooBig) const { if (text.isNotEmpty() && context->clipRegionIntersects (Rectangle<int> (x, y, width, height))) { GlyphArrangement arr; arr.addCurtailedLineOfText (context->getFont(), text, 0.0f, 0.0f, (float) width, useEllipsesIfTooBig); arr.justifyGlyphs (0, arr.getNumGlyphs(), (float) x, (float) y, (float) width, (float) height, justificationType); arr.draw (*this); } }