This section explains the DrawText API sample implementation that is included in Scaleform 4.x. The DrawText API has been included in Scaleform SDK to provide ease in drawing simple text objects on the screen without overheads on memory and performance criteria. The sample code describes classes used in DrawText API to draw text and can be easily included in your text engines to display text.
The basic steps include setting up the window, loading the movie data, and adding a display handle to capture and render the text.
FxPlayerApp class is the player application class which defines all the properties and functions for setting up the window, loading the movie and rendering the text. FxPlayerApp inherits from the FxPlayerAppBase class which is the base class where the window, render thread and graphics are created and initialized.
OnInit method of the FxPlayerApp initializes the DrawText instances, creates the text and applies various text transformations. OnUpdateFrame method applies transformation matrix on the text to create animation.
class FxPlayerApp : public FxPlayerAppBase { public: FxPlayerApp(); virtual boolOnInit(Platform::ViewConfig& config); virtual voidOnUpdateFrame(bool needRepaint); Ptr<GFx::DrawTextManager> pDm1, pDm2; Ptr<GFx::DrawText> ptxt11, ptxt12, ptxt21, ptxt22, ptxtImg, pblurTxt, pglowTxt, pdropShTxt, pblurglowTxt; float Angle; UInt32 Color; };
The DrawText sample describes how to render text using two different instances of DrawTextManager class interface.
Method 1
In this example, DrawTextManager instance is created using a pointer to GFx::Loader to inherit all states from the loader.
pDm1 = *new DrawTextManager(&mLoader);
Here, we use the system fonts for the text to be displayed and thus GFx::FontProvider is used for the purpose. The FontProvider is created in FxPlayerAppBase::OnInit.
pDm1->SetFontProvider(mLoader.GetFontProvider());
As mentioned in the API, there are several ways of creating DrawText instance by using either plain text or HTML text. In this example, DrawText instances are created using plain text and Scaleform::String.
// Create text using plain text and default text parameters. DrawTextManager::TextParams defParams = pDm1->GetDefaultTextParams(); defParams.TextColor = Color(0xF0, 0, 0, 0xFF); // red, alpha = 255 defParams.FontName = "Arial"; defParams.FontSize = 16; pDm1->SetDefaultTextParams(defParams);
The text is created by calling CreateText method and uses the default text parameters set by the previous call to SetDefaultTextParams.
ptxt11 = *pDm1->CreateText ("Plain text, red, Arial, 16pts",RectF(20, 20, 500, 400));
The GetTextExtent method of DrawTextManager class measures the dimensions of the text rectangle. And DrawText class can be availed for manipulations on the text such as formating the font, aligning the text or changing the position of text object.
// Create text with using String and TextParams String str( "Scaleform GFx is a light-weight high-performance rich media vector graphics and user interface (UI) engine."); GFx::DrawTextManager::TextParams params; params.FontName = "Arial"; params.FontSize = 14; params.FontStyle = DrawText::Italic; params.Multiline = true; params.WordWrap = true; params.HAlignment = DrawText::Align_Justify; sz = pDm1->GetTextExtent(str, 200, ¶ms); ptxt12 = *pDm1->CreateText(str, RectF(200, 300, sz), ¶ms); ptxt12->SetColor(Render::Color(0, 0, 255, 130), 0, 1);
Once the text is created using the system fonts, set viewport for the DrawText, capture current DrawText state and add DrawText DisplayHandle to the RenderThread:
Render::Size<unsigned> viewSize = GetViewSize(); Render::Viewport dmViewport(viewSize.Width, viewSize.Height, int(viewSize.Width * GetSafeArea().Width), int(viewSize.Height * GetSafeArea().Height), int(viewSize.Width - 2 * viewSize.Width * GetSafeArea().Width), int(viewSize.Height - 2 * viewSize.Height * GetSafeArea().Height)); pDm1->SetViewport(dmViewport); pDm1->Capture(); pRenderThread->AddDisplayHandle(pDm1->GetDisplayHandle(), FxRenderThread::DHCAT_Overlay, false);
Method 2
This example creates an instance of DrawTextManger which uses a MovieDef pointer to share the fonts contained in MovieDef. The font for the text is obtained from the SWF file loaded in MovieDef. Please refer to Scaleform Integration Tutorial for an understanding of Scaleform and loading movie objects.
Ptr<MovieDef> pmovieDef = *mLoader.CreateMovie("drawtext_fonts.swf", Loader::LoadAll); pDm2 = *new DrawTextManager(pmovieDef);
In differing from the previous example, we display the text using HTML text instead of plain text (but, of course, the HTML might be used in the previous example as well). The dimensions of the text rectangle is calculated by using the DrawTextManager::GetHtmlExtent method.
// Create HTML text, using fonts from ScaleformMovieDef const wchar_t* html = L"<P>o123 <FONT FACE=\"Times New Roman\" SIZE =\"140\">"L"А<b><i><FONT COLOR='#3484AA'>б</FONT></i>рак</b>адабрА!</FONT></P>" L"<P><FONT FACE='Arial Unicode MS'>Hànyǔ; 华语/華語</FONT></P>" L"<P><FONT FACE='Batang'>한국어/조선말</FONT></P>" L"<P><FONT FACE='Symbol'>Privet!</FONT></P>"; Scaleform::DrawTextManager::TextParams defParams2 = pDm2->GetDefaultTextParams(); defParams2.TextColor = Color(0xF0,0,0,0xFF); //red,alpha = 255 defParams2.Multiline = true; defParams2.WordWrap = false; SizeF htmlSz = pDm2->GetHtmlTextExtent(HtmlText, 0, &defParams2); ptxt22 = *pDm2->CreateHtmlText(HtmlText, RectF(00, 100, htmlSz), &defParams2);
We also need to create text to demonstrate text animation:
SizeF sz; sz = pDm2->GetTextExtent("Animated"); ptxt21 = *pDm2->CreateText("Animated", RectF(600, 400, sz)); ptxt21->SetColor(Render::Color(0, 0, 255, 255)); Angle = 0;
and filters:
SizeF sz; Ptr<Scaleform::DrawText> pglowTxt pglowTxt = *pDm2->CreateText("Glow", RectF(800, 350, SizeF(200, 220))); pglowTxt->SetColor(Render::Color(120, 30, 192, 255)); pglowTxt->SetFontSize(72); Scaleform::DrawText::Filter glowF(Scaleform::DrawText::Filter_Glow); glowF.Glow.BlurX = glowF.Glow.BlurY = 2; glowF.Glow.Strength = 1000; glowF.Glow.Color = Render::Color(0, 0, 0, 255).ToColor32(); pglowTxt->SetFilters(&glowF);
Set viewport for the DrawText, capture current DrawText state and add DrawText DisplayHandle to the RenderThread:
pDm2->SetViewport(dmViewport); pDm2->Capture(); pRenderThread->AddDisplayHandle(pDm2->GetDisplayHandle(), FxRenderThread::DHCAT_Overlay, false);
As an example, rotate and change color of text created by using SetMatrix and SetCxform methods of DrawText. We do it inside the FxPlayerApp::OnUpdateFrame:
void FxPlayerApp::OnUpdateFrame( bool needRepaint ) { DrawText::Matrix txt21matrix; Angle += 1; RectF r = ptxt21->GetRect(); txt21matrix.AppendTranslation(-r.x1, -r.y1); txt21matrix.AppendRotation(Angle*3.14159f / 180.f); txt21matrix.AppendScaling(2); txt21matrix.AppendTranslation(r.x1, r.y1); ptxt21->SetMatrix(txt21matrix); pDm2->Capture(); FxPlayerAppBase::OnUpdateFrame(needRepaint); }
NOTE: Copy the drawtext_fonts.swf from the Bin/Samples directory into the same directory where the executable is located (if you run the executable manually) or into the project directory (e.g.: Projects/Win32/Msvc90/Samples/DrawText, if run from the Visual Studio 2008). Otherwise, instead of most of the glyphs you will just see rectangles.
Screenshot: