Resources | Resources |



Using the rich text model with a static widget

The rich text model allows the application to render text using embedded tags. This topic describes how to implement the rich text model on a static widget. It also describes how to set up the tags and fonts required for rendering rich text on the output device.

This example code in the sections below is from c_richtexteditsample. The examples show how to create a static widget, attach a Rich Text Model, and specify rich text tags to use with the model.

To display rich text, an application needs to do the following:

  1. Create a standard static widget and place it in a root container. ISHELL_CreateInstance is used to create the static widget and then the text model for that widget.
  2. Query Interface the text model for support of AEEIID_IRichTextModel and the rich text model version, by calling ITextModel_QueryInterface().
  3. Set the rich text model to the static widget, by calling IWidget_SetModel().
  4. Create an AEECLSID_CFontMapModel using ISHELL_CreateInstance.
  5. For each rich text tag, a font is loaded using an API such as ITypeface_NewFontFromFontFile, and the font and style are set into the model by calling IFontMapModel_Insert(). For other methods of creating fonts using ITypeface, see the

  6. Set a rich text string into the static widget's model, by calling IRichTextModel_SetMarkupText(), and the widget is displayed.

Include files

The following include files are needed to create the widget, model, and fonts:

#include "AEEIWidget.h"         
#include "AEEITextModel.h"         
#include "AEETextWidget.h"         
#include ""         
#include ""         
#include "AEEIRichTextModel.h"         
#include "AEEIPropContainer.h"         
#include "AEEIRootContainer.h"         
#include ""         
#include ""         
#include "AEEFontBidiUtil.h"         
#include "AEEFontMapModel.h"         
#include "AEEHFontOutline.h"         
#include ""         
#include ""         
#include "AEETypeface.h"         
#include ""         
#include "AEEImageStaticWidget.h"         
#include ""     
#include "AEEWidgetProperties.h"     
#include "AEEITextLayout.h"

Create the widget, text model, and get the rich text model

Note: ERR_TRY is a macro defined in the source code, used to test the return value of the function.

//create the Static widget which will display our text         
ERR_TRY( ISHELL_CreateInstance(pMe->piShell, AEECLSID_CStaticWidget,
            CAST(void**, &pMe->m_pRichTextElement)));         
//create a text model interface         
ERR_TRY( ISHELL_CreateInstance(pMe->piShell, AEECLSID_CTextModel,          
            CAST(void**, &pTempModel)) );         
//get the rich text model version         
ERR_TRY( ITextModel_QueryInterface(pTempModel, AEEIID_IRichTextModel,          
            (void **) &pMe->m_pRichTextModel));         
//release the temp model         

Add the text model to the created widget

            (IModel *)pMe->m_pRichTextModel));

Create a font map model

This code example creates a font map model and adds tags to the model.

int nErr = AEE_SUCCESS;         
WidgetPos wp  = {0};         
pMe->wSize = 12; //12 point for default         
// create a FontMapModel that describes how markup is to be interpreted         
ERR_TRY(ISHELL_CreateInstance(pMe->piShell, AEECLSID_CFontMapModel,
ERR_TRY(ISHELL_CreateInstance(pMe->piShell, AEECLSID_CBTFETypeface,
// default font     
ERR_TRY(ITypeface_NewFontFromFontFile(pMe->m_pitf, "qcsans.ttf", pMe->wSize,
//allow inline images/emoticons in the default font     
ERR_TRY(c_RichTextEditSample_SetInlineImages(pMe, pMe->m_pihf));     
ERR_TRY(IFontMapModel_Insert(pMe->m_piFontMapModel, NULL,
            CAST(IFont*, pMe->m_pihf)));     
// [b] == bold font         
pMe->wSize = 20;         
ERR_TRY(ITypeface_NewFontFromFontFile(pMe->m_pitf, "qcsans.ttf", pMe->wSize,
ERR_TRY(c_RichTextEditSample_SetStyle(pMe, CAST(IFont*, pMe->m_pihf)));         
ERR_TRY(IHFont_SetEmphasisStyle(pMe->m_pihf, HFONT_EMPHASIS_BOLD));         
ERR_TRY(IFontMapModel_Insert(pMe->m_piFontMapModel, pawMarkupBold,
            CAST(IFont*, pMe->m_pihf)));         
pMe->wSize = 12;         
// [I] = italic font         
ERR_TRY(ITypeface_NewFontFromFontFile(pMe->m_pitf, "qcsans.ttf", pMe->wSize,
ERR_TRY(c_RichTextEditSample_SetStyle(pMe, CAST(IFont*, pMe->m_pihf)));         
ERR_TRY(IHFont_SetEmphasisStyle(pMe->m_pihf, HFONT_EMPHASIS_ITALIC));         
ERR_TRY(IFontMapModel_Insert(pMe->m_piFontMapModel, pawMarkupItalic,
            CAST(IFont*, pMe->m_pihf)));         
// [blue] == blue font         
pMe->wSize = 28;         
ERR_TRY(ITypeface_NewFontFromFontFile(pMe->m_pitf, "qcsans.ttf", pMe->wSize,
ERR_TRY(c_RichTextEditSample_SetStyle(pMe, CAST(IFont*, pMe->m_pihf)));         
ERR_TRY(IHFont_SetTextColor(pMe->m_pihf, RGBA_BLUE));         
ERR_TRY(IFontMapModel_Insert(pMe->m_piFontMapModel, pawMarkupBlue, CAST(IFont*,
// [u] == underlined         
pMe->wSize = 18;         
ERR_TRY(ITypeface_NewFontFromFontFile(pMe->m_pitf, "qcsans.ttf", pMe->wSize,
ERR_TRY(c_RichTextEditSample_SetStyle(pMe, CAST(IFont*, pMe->m_pihf)));         
ERR_TRY(IHFont_SetUnderlineStyle(pMe->m_pihf, HFONT_LINEEFFECT_SINGLE));         
ERR_TRY(IHFont_SetTextColor(pMe->m_pihf, RGBA_RED));         
ERR_TRY(IFontMapModel_Insert(pMe->m_piFontMapModel, pawMarkupUnderlined,
            CAST(IFont*, pMe->m_pihf)));         

Attach the font map model to the static widget

In the following example, the application adds the font map model to the static widget and instantiates the Brew MP True Type Font Extension, as follows:

ERR_TRY(ITextLayout_SetFontMapModel((ITextLayout *)pMe->m_pRichTextElement,
            AEECLSID_CBTFETextLayout )); 

Loading images and mapping images to characters

To support inline images, such as emoticons in text, the application must first load the images to be used, then call IHFont_SetInlineImageParam() to map the image to a particular character in the font. In this example the "#" character is mapped to a smiley face image.

Note: For best results, the size of the image should correspond to the font size being used.

static int c_RichTextEditSample_SetInlineImages(c_RichTextEditSample* pMe,
            IHFont* pihf)         
   int nErr = AEE_SUCCESS;         
   int nNumInlineImages = 0;         
   AEEImageInfo ii;         
   InlineImageParam* piip = &pMe->m_piip;         
   pMe->m_pInlineImage = ISHELL_LoadImage(pMe->piShell, "smiley.png");         
   IImage_GetInfo(pMe->m_pInlineImage, &ii);         
   // place emoticons 3 pixels below the baseline         
   SETAEERECT(&piip->rcImage, 0, 0, ii.cxFrame,;         
   piip->dcb = c_RichTextEditSample_InlineImageDrawCB;         
   piip->pUser = (void*)pMe;         
   piip->dwImageId = 0;         
   piip->dwCharCode = (int)(AECHAR)'#';         
   nErr = IHFont_SetInlineImageParam(pihf, &pMe->m_piip);         
   return nErr;         

Callback function

While the widget is drawing, it calls the user callback function to render the inline images. In this example callback, the user renders the image at the coordinates that the text layout engine is providing.

static void c_RichTextEditSample_InlineImageDrawCB(InlineImageInfo* piii)         
   c_RichTextEditSample* pMe = piii->pUserData;         
   IImage_Draw(pMe->m_pInlineImage, piii->rcDst.x, piii->rcDst.y);         

Error handling

The sample code uses the following macros for error handling.

#define ERR_CATCH        __errcatch         
#define ERR_TRY(x) do { nErr = (x); if (AEE_SUCCESS != nErr) goto ERR_CATCH; } while(0)         
#define ERR_THROW(e)do { nErr = (e); goto ERR_CATCH; } while(0)         
#define ERR_CHECK_PTR(p) if (NULL == p) ERR_THROW(AEE_EFAILED);         
#ifndef CAST         
#define CAST(t, exp)   ((t)(void*)(exp))