Game Development Community

LineSpacing in GuiMLTextCtrl

by Teddy Setiawan Wijaya · in Torque Game Builder · 08/01/2008 (10:46 pm) · 2 replies

How do we set line spacing for a multiline text in a GuiMLTextCtrl?

I have tried changing the number for lineSpacing properties with no result.

I have also tried changing the value of HorizSizing, VertSizing, autoSizeHeight, autoSizeWidth in conjunction with setting the lineSpacing but also getting no result.

Surprisingly, when I tried changing the font type the line spacing changed.

Here's the code snippet that I use:
%textContent = new GuiMLTextCtrl(dialogueText) {
						 canSaveDynamicFields = "0";
						 isContainer = "0";
						 Profile = "GuiMLTextProfile";
						 HorizSizing = "right";
						 VertSizing = "bottom";
						 Position = %textPosition;
						 Extent = "280 125";
						 MinExtent = "8 8";
						 canSave = "1";
						 Visible = "1";
						 hovertime = "1000";
						 allowColorChars = "1";
						 maxChars = "-1";
						 lineSpacing = 2;
						 text = "";
						 layer = 1;						 
					};
	dialogueBackground.addGuiControl(%textContent);				
	dialogueText.setText(%this.text);


Did I miss something?

Note: I am using TGB 1.7.4

#1
08/02/2008 (10:37 am)
The line spacing property is defined but never actually used--which is why you are not seeing any effect.

To make the whole thing live, add the following to the public interface of GuiMLTextCtrl in gui/controls/guiMLTextCtrl.h:

U32 getLineSpacing() { return mLineSpacingPixels; }
   void setLineSpacing( U32 value ) { mLineSpacingPixels = value; mDirty = true; }

Then add the following function somewhere towards the top of gui/control/guiMLTextCtrl.cc

static bool setLineSpacingFunc( void* obj, const char* data )
{
   GuiMLTextCtrl* ctrl = static_cast< GuiMLTextCtrl* >( obj );
   S32 value = dAtoi( data );
   if( value >= 0 )
   {
      ctrl->setLineSpacing( value );
      return true;
   }
   else
      return false;
}

and in the same file, change the line:

addField("lineSpacing",       TypeS32,    Offset(mLineSpacingPixels, GuiMLTextCtrl));

to

addProtectedField("lineSpacing",       TypeS32,    Offset(mLineSpacingPixels, GuiMLTextCtrl),   setLineSpacingFunc, defaultProtectedGetFn, 1 );

Finally, still in the same file, replace the GuiMLTextCtrl::emitNewLine method with

void GuiMLTextCtrl::emitNewLine(U32 textStart)
{
   //clear any clipping
   mCurClipX = 0;

   Line *l = (Line *) mViewChunker.alloc(sizeof(Line));
   l->height = mCurStyle->font->fontRes->getHeight() + mLineSpacingPixels;
   l->y = mCurY;
   l->textStart = mLineStart;
   l->len = textStart - l->textStart;
   mLineStart = textStart;
   l->atomList = mLineAtoms;
   l->next = 0;
   l->divStyle = mCurDiv;
   *mLineInsert = l;
   mLineInsert = &(l->next);
   mCurX = mCurLMargin;
   mCurTabStop = 0;

   if(mLineAtoms)
   {
      // scan through the atoms in the line, get the largest height
      U32 maxBaseLine = 0;
      U32 maxDescent = 0;
      Atom* walk;

      for(walk = mLineAtoms; walk; walk = walk->next)
      {
         if(walk->baseLine > maxBaseLine)
            maxBaseLine = walk->baseLine;
         if(walk->descent > maxDescent)
            maxDescent = walk->descent;
         if(!walk->next)
         {
            l->len = walk->textStart + walk->len - l->textStart;
            mLineStart = walk->textStart + walk->len;
         }
      }
      l->height = maxBaseLine + maxDescent + mLineSpacingPixels;

      for(walk = mLineAtoms; walk; walk = walk->next)
         walk->yStart = mCurY + maxBaseLine - walk->baseLine;
   }
   mCurY += l->height;
   mLineAtoms = NULL;
   mLineAtomPtr = &mLineAtoms;

   // clear out the blocker list
   BitmapRef **blockList = &mBlockList;
   while(*blockList)
   {
      BitmapRef *blk = *blockList;
      if(blk->point.y + blk->extent.y <= mCurY)
         *blockList = blk->nextBlocker;
      else
         blockList = &(blk->nextBlocker);
   }
   if(mCurY > mMaxY)
      mMaxY = mCurY;
}

This is a quick job. Haven't checked extensively but it seems to do the thing just fine.
#2
08/02/2008 (8:59 pm)
Hi Rene, many thanks for the reply.

Sadly I have don't have TGB source code.
I guess for the time being I have to use the font type that give the desirable 'line spacing' (for example: Arial seems to do just fine while Lucida Console is not) ;-)