ソースを参照

TextSprite Object

This introduced the TextSprite class which can take a FontAssest and
write out characters using the correct spacing.  This is bare bones and
further commits will add remaining functionality.
Peter Robinson 10 年 前
コミット
656640d12c

+ 4 - 0
engine/compilers/VisualStudio 2013/Torque 2D.vcxproj

@@ -279,6 +279,7 @@
     <ClCompile Include="..\..\source\2d\sceneobject\ShapeVector.cc" />
     <ClCompile Include="..\..\source\2d\sceneobject\SkeletonObject.cc" />
     <ClCompile Include="..\..\source\2d\sceneobject\Sprite.cc" />
+    <ClCompile Include="..\..\source\2d\sceneobject\TextSprite.cc" />
     <ClCompile Include="..\..\source\2d\sceneobject\Trigger.cc" />
     <ClCompile Include="..\..\source\2d\scene\ContactFilter.cc" />
     <ClCompile Include="..\..\source\2d\scene\DebugDraw.cc" />
@@ -299,6 +300,7 @@
     <ClCompile Include="..\..\source\audio\audio_ScriptBinding.cc" />
     <ClCompile Include="..\..\source\audio\vorbisStreamSource.cc" />
     <ClCompile Include="..\..\source\bitmapFont\BitmapFont.cc" />
+    <ClCompile Include="..\..\source\bitmapFont\BitmapFontCharacter.cc" />
     <ClCompile Include="..\..\source\Box2D\Collision\b2BroadPhase.cpp" />
     <ClCompile Include="..\..\source\Box2D\Collision\b2CollideCircle.cpp" />
     <ClCompile Include="..\..\source\Box2D\Collision\b2CollideEdge.cpp" />
@@ -723,6 +725,8 @@
     <ClInclude Include="..\..\source\2d\sceneobject\SkeletonObject_ScriptBinding.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\Sprite.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\Sprite_ScriptBinding.h" />
+    <ClInclude Include="..\..\source\2d\sceneobject\TextSprite.h" />
+    <ClInclude Include="..\..\source\2d\sceneobject\TextSprite_ScriptBinding.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\Trigger.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\Trigger_ScriptBinding.h" />
     <ClInclude Include="..\..\source\2d\scene\ContactFilter.h" />

+ 12 - 0
engine/compilers/VisualStudio 2013/Torque 2D.vcxproj.filters

@@ -1437,6 +1437,12 @@
     <ClCompile Include="..\..\source\bitmapFont\BitmapFont.cc">
       <Filter>bitmapFont</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\source\2d\sceneobject\TextSprite.cc">
+      <Filter>2d\sceneobject</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\bitmapFont\BitmapFontCharacter.cc">
+      <Filter>bitmapFont</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\source\audio\audio.h">
@@ -3180,6 +3186,12 @@
     <ClInclude Include="..\..\source\bitmapFont\BitmapFontCharacter.h">
       <Filter>bitmapFont</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\source\2d\sceneobject\TextSprite.h">
+      <Filter>2d\sceneobject</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\2d\sceneobject\TextSprite_ScriptBinding.h">
+      <Filter>2d\sceneobject</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <CustomBuild Include="..\..\source\math\mMath_ASM.asm">

+ 2 - 0
engine/source/2d/assets/FontAsset.h

@@ -66,6 +66,8 @@ public:
     void                    setFontFile( const char* pFontFile );
     inline StringTableEntry getFontFile( void ) const                   { return mFontFile; }
 
+    inline TextureHandle&   getImageTexture(U16 pageID)                         { return mBitmapFont.mTexture[pageID]; }
+
     /// Declare Console Object.
     DECLARE_CONOBJECT(FontAsset);
 

+ 273 - 0
engine/source/2d/sceneobject/TextSprite.cc

@@ -0,0 +1,273 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2013 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+#ifndef _DGL_H_
+#include "graphics/dgl.h"
+#endif
+
+#include "console/consoleTypes.h"
+
+#include "io/bitStream.h"
+
+#include "string/stringBuffer.h"
+
+#include "TextSprite.h"
+
+// Script bindings.
+#include "TextSprite_ScriptBinding.h"
+
+//------------------------------------------------------------------------------
+
+static EnumTable::Enums textAlignmentEnums[] = 
+{
+    { TextSprite::ALIGN_LEFT,      "Left" },
+    { TextSprite::ALIGN_CENTER, "Center" },
+    { TextSprite::ALIGN_RIGHT, "Right" },
+    { TextSprite::ALIGN_JUSTIFY, "Justify" },
+};
+
+static EnumTable gTextAlignmentTable(4, &textAlignmentEnums[0]); 
+
+//-----------------------------------------------------------------------------
+
+TextSprite::TextAlign TextSprite::getTextAlignmentEnum(const char* label)
+{
+    // Search for Mnemonic.
+    for (U32 i = 0; i < (sizeof(textAlignmentEnums) / sizeof(EnumTable::Enums)); i++)
+    {
+        if( dStricmp(textAlignmentEnums[i].label, label) == 0)
+            return (TextAlign)textAlignmentEnums[i].index;
+    }
+
+    // Warn.
+    Con::warnf("TextSprite::getTextAlignmentEnum() - Invalid text alignment of '%s'", label );
+
+    return TextSprite::INVALID_ALIGN;
+}
+
+//-----------------------------------------------------------------------------
+
+const char* TextSprite::getTextAlignmentDescription(const TextSprite::TextAlign alignment)
+{
+    // Search for Mnemonic.
+    for (U32 i = 0; i < (sizeof(textAlignmentEnums) / sizeof(EnumTable::Enums)); i++)
+    {
+        if( textAlignmentEnums[i].index == alignment )
+            return textAlignmentEnums[i].label;
+    }
+
+    // Warn.
+    Con::warnf( "TextSprite::getTextAlignmentDescription() - Invalid text alignment.");
+
+    return StringTable->EmptyString;
+}
+
+//------------------------------------------------------------------------------
+
+IMPLEMENT_CONOBJECT(TextSprite);
+
+//-----------------------------------------------------------------------------
+
+TextSprite::TextSprite() :
+   mFontSize(1.0f),
+   mFontScaleX(1.0f),
+   mFontScaleY(1.0f),
+   mTextAlign(TextSprite::ALIGN_LEFT),
+   mTextVAlign(TextSprite::VALIGN_TOP),
+   mOverflowX(TextSprite::OVERFLOW_X_WRAP),
+   mOverflowY(TextSprite::OVERFLOW_Y_HIDDEN),
+   mAutoLineHeight(true),
+   mCustomLineHeight(1.0f),
+   mKerning(0.0f)
+{
+}
+
+//-----------------------------------------------------------------------------
+
+TextSprite::~TextSprite()
+{
+}
+
+//-----------------------------------------------------------------------------
+
+void TextSprite::initPersistFields()
+{    
+    // Call parent.
+    Parent::initPersistFields();
+
+    addProtectedField("font", TypeFontAssetPtr, Offset(mFontAsset, TextSprite), &setFont, &getFont, &writeFont, "");
+    addProtectedField("text", TypeString, 0, setText, getText, &writeText, "The text to be displayed." );  
+    //addProtectedField("textAlignment", TypeEnum, Offset(mTextAlignment, TextSprite), &setTextAlignment, &defaultProtectedGetFn, &writeTextAlignment, 1, &gTextAlignmentTable, "");
+    addProtectedField("fontSize", TypeVector2, Offset(mFontSize, TextSprite), &setFontSize, &defaultProtectedGetFn,&writeFontSize, "" );
+    //addProtectedField("fontPadding", TypeF32, Offset(mFontPadding, TextSprite), &setFontPadding, &defaultProtectedGetFn, &writeFontPadding, "" );
+}
+
+//-----------------------------------------------------------------------------
+
+bool TextSprite::onAdd()
+{
+    // Call Parent.
+    if(!Parent::onAdd())
+        return false;
+    
+    // Return Okay.
+    return true;
+}
+
+//-----------------------------------------------------------------------------
+
+void TextSprite::onRemove()
+{
+    // Call Parent.
+    Parent::onRemove();
+}
+
+//------------------------------------------------------------------------------
+
+void TextSprite::copyTo(SimObject* object)
+{
+    // Fetch font object.
+    TextSprite* pFontObject = dynamic_cast<TextSprite*>(object);
+
+    // Sanity.
+    AssertFatal(pFontObject != NULL, "TextSprite::copyTo() - Object is not the correct type.");
+
+    // Call parent.
+    Parent::copyTo(object);
+
+    // Copy.
+    pFontObject->setFont(getFont());
+    pFontObject->setText(getText());
+    pFontObject->setFontSize(getFontSize());
+    pFontObject->setFontScaleX(getFontScaleX());
+    pFontObject->setFontScaleY(getFontScaleY());
+    pFontObject->setTextAlignment(getTextAlignment());
+    pFontObject->setTextVAlignment(getTextVAlignment());
+    pFontObject->setOverflowModeX(getOverflowModeX());
+    pFontObject->setOverflowModeY(getOverflowModeY());
+    pFontObject->setAutoLineHeight(getAutoLineHeight());
+    pFontObject->setCustomLineHeight(getCustomLineHeight());
+    pFontObject->setKerning(getKerning());
+}
+
+//------------------------------------------------------------------------------
+
+void TextSprite::scenePrepareRender( const SceneRenderState* pSceneRenderState, SceneRenderQueue* pSceneRenderQueue )
+{
+    // Create a default render request.
+    Scene::createDefaultRenderRequest( pSceneRenderQueue, this );
+}
+
+//------------------------------------------------------------------------------
+
+void TextSprite::sceneRender( const SceneRenderState* pSceneRenderState, const SceneRenderRequest* pSceneRenderRequest, BatchRender* pBatchRenderer )
+{
+    // Finish if no font asset.
+    if ( mFontAsset.isNull() )
+        return;
+
+    // Fetch number of characters to render.
+    const U32 renderCharacters = mText.length();
+
+    // Ignore if no text to render.
+    if( renderCharacters == 0 )
+        return;
+
+    // Get a size ratio
+    const F32 ratio = mFontAsset->mBitmapFont.getSizeRatio(mFontSize);
+
+    // Create a cursor
+    Vector2 cursor(0.0f, mFontAsset->mBitmapFont.mBaseline * ratio);
+
+    // Render all the characters.    
+    for( U32 characterIndex = 0; characterIndex < renderCharacters; ++characterIndex )
+    {
+        // Fetch character.
+        U32 character = mText.getChar( characterIndex );
+
+        RenderLetter(pBatchRenderer, cursor, character, ratio);
+    }
+}
+
+//-----------------------------------------------------------------------------
+
+
+void TextSprite::RenderLetter(BatchRender* pBatchRenderer, Vector2& cursor, U32 charID, F32 ratio)
+{
+   const BitmapFontCharacter bmChar = mFontAsset->mBitmapFont.getCharacter(charID);
+   cursor.x -= (bmChar.mXOffset * ratio);
+
+   Vector2 left = (mRenderOOBB[1] - mRenderOOBB[0]);
+   left.Normalize((F32)cursor.x + (bmChar.mXOffset * ratio));
+
+   Vector2 right = (mRenderOOBB[1] - mRenderOOBB[0]);
+   right.Normalize(bmChar.mWidth * ratio);
+
+   Vector2 top = (mRenderOOBB[3] - mRenderOOBB[0]);
+   top.Normalize((F32)cursor.y - (mFontAsset->mBitmapFont.mBaseline * ratio) + (bmChar.mYOffset * ratio));
+
+   Vector2 bottom = (mRenderOOBB[3] - mRenderOOBB[0]);
+   bottom.Normalize(bmChar.mHeight * ratio);
+
+   Vector2 destOOBB[4];
+   destOOBB[0] = (mRenderOOBB[3] + left - top - bottom);
+   destOOBB[1] = (mRenderOOBB[3] + left + right - top - bottom);
+   destOOBB[2] = (mRenderOOBB[3] + left + right - top);
+   destOOBB[3] = (mRenderOOBB[3] + left - top);
+
+   // Submit batched quad.
+   pBatchRenderer->SubmitQuad(
+      destOOBB[0],
+      destOOBB[1],
+      destOOBB[2],
+      destOOBB[3],
+      bmChar.mOOBB[0],
+      bmChar.mOOBB[1],
+      bmChar.mOOBB[2],
+      bmChar.mOOBB[3],
+      mFontAsset->getImageTexture(bmChar.mPage));
+
+   cursor.x += (bmChar.mXAdvance * ratio);
+}
+
+
+//-----------------------------------------------------------------------------
+
+bool TextSprite::setFont( const char* pFontAssetId )
+{
+    // Set asset.
+    mFontAsset = pFontAssetId;
+
+    // Finish if no font asset.
+    if ( mFontAsset.isNull() )
+        return false;
+    
+    // Return Okay.
+    return true;
+}
+
+//-----------------------------------------------------------------------------
+
+bool TextSprite::setTextAlignment( void* obj, const char* data )
+{
+    static_cast<TextSprite*>( obj )->setTextAlignment( getTextAlignmentEnum(data) ); return false;
+}

+ 182 - 0
engine/source/2d/sceneobject/TextSprite.h

@@ -0,0 +1,182 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2013 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+#ifndef _TEXT_SPRITE_H_
+#define _TEXT_SPRITE_H_
+
+#ifndef _STRINGBUFFER_H_
+#include "string/stringBuffer.h"
+#endif
+
+#ifndef _FONT_ASSET_H_
+#include "2d/assets/FontAsset.h"
+#endif
+
+#ifndef _SCENE_OBJECT_H_
+#include "2d/sceneobject/SceneObject.h"
+#endif
+
+#ifndef _ASSET_PTR_H_
+#include "assets/assetPtr.h"
+#endif
+
+#ifndef _UTILITY_H_
+#include "2d/core/utility.h"
+#endif
+
+//-----------------------------------------------------------------------------
+
+class TextSprite : public SceneObject
+{
+    typedef SceneObject          Parent;
+
+public:
+    enum TextAlign
+    {
+        INVALID_ALIGN,
+
+        ALIGN_LEFT,
+        ALIGN_CENTER,
+        ALIGN_RIGHT,
+        ALIGN_JUSTIFY,
+    };
+
+    enum TextVAlign
+    {
+       INVALID_VALIGN,
+
+       VALIGN_TOP,
+       VALIGN_MIDDLE,
+       VALIGN_BOTTOM,
+    };
+
+    enum OverflowModeX
+    {
+       INVALID_OVERFLOW_X,
+
+       OVERFLOW_X_WRAP,
+       OVERFLOW_X_EXPAND,
+       OVERFLOW_X_HIDDEN,
+       OVERFLOW_X_SHRINK,
+    };
+
+    enum OverflowModeY
+    {
+       INVALID_OVERFLOW_Y,
+
+       OVERFLOW_Y_EXPAND,
+       OVERFLOW_Y_HIDDEN,
+       OVERFLOW_Y_SHRINK,
+    };
+
+private:
+    AssetPtr<FontAsset>     mFontAsset;
+    StringBuffer            mText;
+    F32                     mFontSize;
+    F32                     mFontScaleX;
+    F32                     mFontScaleY;
+    TextAlign               mTextAlign;
+    TextVAlign              mTextVAlign;
+    OverflowModeX           mOverflowX;
+    OverflowModeY           mOverflowY;
+    bool                    mAutoLineHeight;
+    F32                     mCustomLineHeight;
+    F32                     mKerning;
+
+public:
+    TextSprite();
+    ~TextSprite();
+
+    static void initPersistFields();
+
+    bool onAdd();
+    void onRemove();
+    void copyTo(SimObject* object);
+
+    virtual bool canPrepareRender( void ) const                             { return true; }
+    virtual bool validRender( void ) const                                  { return mFontAsset.notNull() && mText.length() > 0; }
+    virtual bool shouldRender( void ) const                                 { return true; }
+    virtual void scenePrepareRender( const SceneRenderState* pSceneRenderState, SceneRenderQueue* pSceneRenderQueue );
+    virtual void sceneRender( const SceneRenderState* pSceneRenderState, const SceneRenderRequest* pSceneRenderRequest, BatchRender* pBatchRenderer );
+
+    bool setFont( const char* pFontAssetId );
+    const char* getFont(void) const                                         { return mFontAsset.getAssetId(); }
+    inline void setText(const StringBuffer& text)                           { mText.set(&text); }
+    inline StringBuffer& getText(void)                                      { return mText; }
+    inline void setFontSize(const F32 size)                                 { mFontSize = size; }
+    inline F32 getFontSize(void) const                                      { return mFontSize; }
+    inline void setFontScaleX(const F32 scale)                              { mFontScaleX = scale; }
+    inline F32 getFontScaleX(void) const                                    { return mFontScaleX; }
+    inline void setFontScaleY(const F32 scale)                              { mFontScaleY = scale; }
+    inline F32 getFontScaleY(void) const                                    { return mFontScaleY; }
+
+    inline void setTextAlignment(const TextAlign alignment)                 { mTextAlign = alignment; }
+    inline TextAlign getTextAlignment(void) const                           { return mTextAlign; }
+    static TextAlign getTextAlignmentEnum(const char* label);
+    static const char* getTextAlignmentDescription(const TextAlign alignment);
+
+    inline void setTextVAlignment(const TextVAlign alignment)               { mTextVAlign = alignment; }
+    inline TextVAlign getTextVAlignment(void) const                         { return mTextVAlign; }
+    static TextVAlign getTextVAlignmentEnum(const char* label);
+    static const char* getTextVAlignmentDescription(const TextVAlign alignment);
+
+    inline void setOverflowModeX(const OverflowModeX mode)                  { mOverflowX = mode; }
+    inline OverflowModeX getOverflowModeX(void) const                       { return mOverflowX; }
+    static OverflowModeX getOverflowModeXEnum(const char* label);
+    static const char* getOverflowModeXDescription(const OverflowModeX mode);
+
+    inline void setOverflowModeY(const OverflowModeY mode)                  { mOverflowY = mode; }
+    inline OverflowModeY getOverflowModeY(void) const                       { return mOverflowY; }
+    static OverflowModeY getOverflowModeYEnum(const char* label);
+    static const char* getOverflowModeYDescription(const OverflowModeY mode);
+
+    inline void setAutoLineHeight(const bool isAuto)                        { mAutoLineHeight = isAuto; }
+    inline bool getAutoLineHeight(void) const                               { return mAutoLineHeight; }
+    inline void setCustomLineHeight(const F32 lineHeight)                   { mCustomLineHeight = lineHeight; }
+    inline F32 getCustomLineHeight(void) const                              { return mCustomLineHeight; }
+
+    inline void setKerning(const F32 kern)                                  { mKerning = kern; }
+    inline F32 getKerning(void) const                                       { return mKerning; }
+
+    // Declare Console Object.
+    DECLARE_CONOBJECT(TextSprite);
+
+protected:
+    static bool setFont(void* obj, const char* data)                        { static_cast<TextSprite*>(obj)->setFont( data ); return false; }
+    static const char* getFont(void* obj, const char* data)                 { return static_cast<TextSprite*>(obj)->getFont(); }
+    static bool writeFont( void* obj, StringTableEntry pFieldName )         { return static_cast<TextSprite*>(obj)->mFontAsset.notNull(); }
+
+    static bool setText( void* obj, const char* data )                      { static_cast<TextSprite*>( obj )->setText( data ); return false; }
+    static const char* getText( void* obj, const char* data )               { return static_cast<TextSprite*>( obj )->getText().getPtr8(); }
+    static bool writeText( void* obj, StringTableEntry pFieldName )         { return static_cast<TextSprite*>(obj)->mText.length() != 0; }
+
+    static bool setFontSize(void* obj, const char* data)                    { static_cast<TextSprite*>(obj)->setFontSize( dAtof(data) ); return false; }
+    static bool writeFontSize(void* obj, StringTableEntry pFieldName)       { return static_cast<TextSprite*>(obj)->getFontSize() != 1.0f; }
+
+    static bool setTextAlignment( void* obj, const char* data );
+    static bool writeTextAlignment( void* obj, StringTableEntry pFieldName ){return static_cast<TextSprite*>(obj)->getTextAlignment() != TextSprite::ALIGN_CENTER; }
+
+private:
+   void RenderLetter(BatchRender* pBatchRenderer, Vector2& cursor, U32 charID, F32 ratio);
+};
+
+#endif // _TEXT_SPRITE_H_

+ 138 - 0
engine/source/2d/sceneobject/TextSprite_ScriptBinding.h

@@ -0,0 +1,138 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2013 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+ConsoleMethodGroupBeginWithDocs(TextSprite, SceneObject)
+
+/*! Sets the image asset to use..
+    @param imageName The image asset to use.
+    @return Returns true on success.
+*/
+ConsoleMethodWithDocs(TextSprite, setFont, ConsoleBool, 3, 3, (fontAssetId))
+{
+    // Set Image.
+    return object->setFont( argv[2] );
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Gets current image asset..
+    @return The current image asset.
+*/
+ConsoleMethodWithDocs(TextSprite, getFont, ConsoleString, 2, 2, ())
+{
+    // Get Image.
+    return object->getFont();
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Set the text to render.
+*/
+ConsoleMethodWithDocs(TextSprite, setText, ConsoleVoid, 3, 3, (text))
+{
+    object->setText(argv[2]);
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Gets the text being rendered.
+*/
+ConsoleMethodWithDocs(TextSprite, getText, ConsoleString, 2, 2, ())
+{
+    return object->getText().getPtr8();
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Set the text alignment to 'left', 'center' or 'right'.
+    @param alignment The text alignment of 'left', 'center' or 'right'.
+    @return No return value.
+*/
+ConsoleMethodWithDocs(TextSprite, setTextAlignment, ConsoleVoid, 3, 3, (alignment))
+{
+
+    object->setTextAlignment( TextSprite::getTextAlignmentEnum(argv[2]) );
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Gets the text alignment.
+    @return The text alignment of 'left', 'center' or 'right'.
+*/
+ConsoleMethodWithDocs(TextSprite, getTextAlignment, ConsoleString, 2, 2, ())
+{
+    return TextSprite::getTextAlignmentDescription(object->getTextAlignment());
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Set the size of the font characters.
+    @param width The width of a font character.
+    @param height The height of a font character.
+    @return No return value.
+*/
+ConsoleMethodWithDocs(TextSprite, setFontSize, ConsoleVoid, 3, 4, (width, height))
+{
+    F32 width, height;
+
+    U32 elementCount = Utility::mGetStringElementCount(argv[2]);
+
+    // ("width height")
+    if ((elementCount == 2) && (argc == 3))
+    {
+        width = dAtof(Utility::mGetStringElement(argv[2], 0));
+        height = dAtof(Utility::mGetStringElement(argv[2], 1));
+    }
+
+    // (width, [height])
+    else if (elementCount == 1)
+    {
+        width = dAtof(argv[2]);
+
+        if (argc > 3)
+            height = dAtof(argv[3]);
+        else
+            height = width;
+    }
+    // Invalid
+    else
+    {
+        Con::warnf("TextSprite::setFontSize() - Invalid number of parameters!");
+        return;
+    }
+
+    // Set character size.
+    object->setFontSize(width);
+
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Gets the size of the font characters.
+    @return The size of the font characters.
+*/
+ConsoleMethodWithDocs(TextSprite, getFontSize, ConsoleFloat, 2, 2, ())
+{
+    return object->getFontSize();
+}
+
+ConsoleMethodGroupEndWithDocs(TextSprite)

+ 1 - 23
engine/source/bitmapFont/BitmapFont.cc

@@ -114,8 +114,6 @@ namespace font
                   mPages = U16(dAtoi(Value));
                currentWordCount++;
             }
-            mAscent = mBaseline;
-            mDescent = mHeight - mBaseline;
          }
          else if (dStrcmp(Read, "page") == 0)
          {
@@ -188,6 +186,7 @@ namespace font
                   ci.mPage = S32(dAtoi(Value));
                currentWordCount++;
             }
+            ci.ProcessCharacter(mWidth, mHeight);
             mChar.emplace(CharID, ci);
          }
          else if (dStrcmp(Read, "kerning") == 0 && dStrcmp(Read, "kernings") != 0)
@@ -227,27 +226,6 @@ namespace font
          }
       }
 
-      /*for (U32 i = 0; i < mPages; i++)
-      {
-         char buf[1024];
-         dSprintf(buf, sizeof(buf), "%s/%s", Con::getVariable("$GUI::fontCacheDirectory"), fileName);
-         Con::printf("Platform::makeFullPathName %s", buf);
-
-         GBitmap *bmp = dynamic_cast<GBitmap*>(ResourceManager->loadInstance(buf));
-
-         if (bmp == NULL)
-         {
-            return false;
-         }
-
-         char buff[30];
-         dSprintf(buff, sizeof(buff), "font_%d", smSheetIdCount++);
-
-         mTextureSheets.increment();
-         constructInPlace(&mTextureSheets.last());
-         mTextureSheets.last() = TextureHandle(buf, bmp, TextureHandle::BitmapKeepTexture);
-         mTextureSheets.last().setFilter(GL_NEAREST);
-      }*/
       return (io_rStream.getStatus() == Stream::EOS);
    }
 

+ 5 - 4
engine/source/bitmapFont/BitmapFont.h

@@ -47,10 +47,6 @@ namespace font
    class BitmapFont
    {
    private:
-      U16 mLineHeight;
-      U16 mBaseline;
-      U16 mSize;
-      U16 mAscent, mDescent;
       U16 mWidth, mHeight;
       U16 mPages;
 
@@ -58,12 +54,17 @@ namespace font
       KerningMap mKerning;
 
    public:
+      U16 mLineHeight;
+      U16 mBaseline;
+      U16 mSize;
       std::vector<StringTableEntry> mPageName;
       std::vector<TextureHandle> mTexture;
 
       BitmapFont();
       bool parseFont(Stream& io_rStream);
       TextureHandle LoadTexture(StringTableEntry fileName);
+      const BitmapFontCharacter getCharacter(const U16 charID) { return mChar[charID]; }
+      inline const F32 getSizeRatio(const U16 size) { return (F32)size / mLineHeight; }
 
    private:
       inline void AddKerning(U16 first, U16 second, S16 amount) { mKerning[make_pair(first, second)] = amount; }

+ 44 - 0
engine/source/bitmapFont/BitmapFontCharacter.cc

@@ -0,0 +1,44 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2013 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+#ifndef _BITMAP_FONT_CHARACTER_H_
+#include "bitmapFont/BitmapFontCharacter.h"
+#endif
+
+namespace font
+{
+   void BitmapFontCharacter::ProcessCharacter(U16 width, U16 height)
+   {
+      F32 top, right, bottom, left;
+
+      bottom = (F32)mY / height;
+      top = (F32)(mY + mHeight) / height;
+
+      left = (F32)mX / width;
+      right = (F32)(mX + mWidth) / width;
+
+      mOOBB[0] = Vector2(left, top);
+      mOOBB[1] = Vector2(right, top);
+      mOOBB[2] = Vector2(right, bottom);
+      mOOBB[3] = Vector2(left, bottom);
+   }
+}

+ 9 - 1
engine/source/bitmapFont/BitmapFontCharacter.h

@@ -27,20 +27,28 @@
 #include "2d/core/utility.h"
 #endif
 
+#ifndef _VECTOR2_H_
+#include "2d/Core/Vector2.h"
+#endif
+
 namespace font
 {
-   struct BitmapFontCharacter
+   class BitmapFontCharacter
    {
+   public:
       U16 mX, mY;
       U16 mWidth, mHeight;
       F32 mXOffset, mYOffset;
       F32 mXAdvance;
       U16 mPage;
+      Vector2 mOOBB[4];
 
       BitmapFontCharacter() : mX(0), mY(0), mWidth(0), mHeight(0), mXOffset(0), mYOffset(0), mXAdvance(0), mPage(0)
       {
 
       }
+
+      void ProcessCharacter(U16 width, U16 height);
    };
 }
 

+ 15 - 34
modules/ImageFontToy/1/main.cs

@@ -22,7 +22,7 @@
 
 function ImageFontToy::create( %this )
 {
-    // Reset the toy.    
+    // Reset the toy.
     ImageFontToy.reset();
 }
 
@@ -38,40 +38,21 @@ function ImageFontToy::reset( %this )
 {
     // Clear the scene.
     SandboxScene.clear();
-            
-    // Create the image font.
-    %object = new ImageFont();
-    
-    // Always try to configure a scene-object prior to adding it to a scene for best performance.
-    
-    // Set the image font to use the font image asset.
-    %object.Image = "ToyAssets:Font";
-    
-    // We don't really need to do this as the position is set to zero by default.
-    %object.Position = "0 0";
-    
-    // We don't need to size this object as it sizes automatically according to the alignment, font-size and text.
-   
-    // Set the font size in both axis.  This is in world-units and not typicaly font "points".
-    %object.FontSize = "2 2";
-    
-    // We don't really need to do this as the padding is set to zero by default.
-    // Padding is specified in world-units and relates to the space added between each character.
-    %object.FontPadding = 0;
-
-    // Set the text alignment.
-    %object.TextAlignment = "Center";
 
-    // Set the text to display.
-    %object.Text = " !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`~abcdefghijklmnopqrstuvwxyz";
+    // Create the image font.
+    %object = new TextSprite()
+    {
+        font = "ToyAssets:OratorBoldFont";
+        fontSize = 6;
+        position = "0 0";
+        text = "Hello World!";
+        size = "30 30";
+        BlendColor = "1 1 1 1";
+        AngularVelocity = 30;
+    };
+
+    $f = %object;
 
-    // Make the text spin just to make it more interesting!
-    %object.AngularVelocity = 30;
-    
-    // The ImageFont is a type that defaults to a "static" body-type (typically so it's not affected by gravity)
-    // but we want this to spin so we need a "dynamic" body-type/
-    %object.BodyType = "dynamic";
-    
     // Add the sprite to the scene.
-    SandboxScene.add( %object );    
+    SandboxScene.add( %object );
 }

+ 3 - 0
modules/ToyAssets/1/assets/fonts/Orator Bold.asset.taml

@@ -0,0 +1,3 @@
+<FontAsset
+    AssetName="OratorBoldFont"
+    FontFile="Orator Bold.fnt" />

+ 3 - 0
modules/ToyAssets/1/assets/fonts/Trajan Pro.asset.taml

@@ -0,0 +1,3 @@
+<FontAsset
+    AssetName="TrajanProFont"
+    FontFile="Trajan Pro.fnt" />