Previous section.

Portable Layout Services: Context-dependent and Directional Text

Portable Layout Services:
Context-dependent and Directional Text
Copyright © 1997 The Open Group

Dynamic Pluggable Interface

This appendix defines the interface between the locale-independent and locale-dependent layer of Layout Services.

The locale-independent module is a library containing the interfaces defined in this document. These interfaces are implemented as wrapper functions which access the actual locale-specific implementation through function pointers. In addition, this locale-independent layout services library also contains the platform-specific implementation for dynamic loading of the locale-dependent module.

Each locale will have a locale-dependent module containing the implementation of the locale-sensitive functions. The locale-dependent module could be implemented as part of the locale-independent layout services library, or it could be implemented as a separate dynamic loadable object to be loaded in during runtime. This proposal will only concentrate on defining the dynamic loadable object approach.

The advantages to separate the implementation into locale-dependent and locale-independent modules are:

  1. Each locale-dependent module could be highly tuned for a specific language to yield maixmum performance.

  2. A client can switch to a different Layout Services support dynamically during runtime.

  3. A single application can have a different Layout Services support for each window.

Operating System Requirement

In order to implement the dynamic loadable object approach, the underlying operating system must support the dynamic linking feature. This feature could be provided via the following two interfaces:

Design

Every locale-dependent module must implement a function called _LayoutObjectInit(). This is the entry point from locale-independent module to locale-dependent module to create and initialize LayoutObject.

Following is an example of how a locale-dependent module implements only the default Layout Services Support:

#include <sys/layout.h>

LayoutObject
_LayoutObjectInit(locale_name)
    char  *locale_name;
{
    return(_LayoutObjectDefaultInit(locale_name));
}

The locale-independent module has a built-in default implementation of the locale-dependent methods which can provide at least "C" locale support.

The naming of the libraries for locale-independent and locale-dependent modules are implementation-dependent. Following is an example for the location and naming of the libraries. The locale-independent module is /usr/lib/liblayout.so. The locale-dependent module is $LOCPATH/<locale>.layout.so.<version number>.

Data Structure

typedef struct _LayoutObject *LayoutObj;
                         /* Private name of Layout Object */
typedef struct _LayoutObject *LayoutObject;
                         /* Public name of Layout Object */

typedef struct {
    LayoutObject (*create)(
#if NeedFunctionPrototypes
        LayoutObj, AttrObj, LayoutValues
#endif
    );

    int (*destroy)(
#if NeedFunctionPrototypes
        LayoutObj
#endif
        );

    int (*getvalues)(
#if NeedFunctionPrototypes
        LayoutObj, LayoutValues, int *
#endif
        );

    int (*setvalues)(
#if NeedFunctionPrototypes
        LayoutObj, LayoutValues, int *
#endif
        );

    int (*transform)(
#if NeedFunctionPrototypes
        LayoutObj, const char *, size_t *, void *,
        size_t *, size_t *, size_t *, unsigned char *, size_t *
#endif
        );

    int (*wcstransform)(
#if NeedFunctionPrototypes
        LayoutObj, const wchar_t *, size_t *, void *,
        size_t *, size_t *, size_t *, unsigned char *, size_t *
#endif
        );

} LayoutMethodsRec, *LayoutMethods;

typedef struct {
    char   *locale_name;

    LayoutTextDescriptor orientation;
    LayoutTextDescriptor context;
    LayoutTextDescriptor type_of_text;
    LayoutTextDescriptor implicit_alg;
    LayoutTextDescriptor swapping;
    LayoutTextDescriptor numerals;
    LayoutTextDescriptor text_shaping;
    BooleanValue  active_dir;
    BooleanValue  active_shape_editing;
    char   *shape_charset;
    int    shape_charset_size;
    unsigned long  in_out_text_descr_mask;
    unsigned long  in_only_text_descr;
    unsigned long  out_only_text_descr;
    LayouDesc   check_mode;
    LayoutEditSize  shape_context_size;
} LayoutCoreRec, *LayoutCore;

typedef struct _LayoutObject {
    LayoutMethods methods; /* methods of this CTL Object */
    LayoutCoreReccore; /* data of this CTL Object */
    void  *private_data; /* Private data of locale-dependent object */
} LayoutObjectRec;

Calling Sequence

  1. Within m_create_layout(), _LayoutObjectGetHandle() is called to retrieve a LayoutObject for the specified locale by loading in the locale-dependent module.

  2. In order to avoid the same locale-dependent module to be reloaded, a list of loaded locales is searched.

  3. If the specified locale is found in the list, _LayoutObjectInit() will be called to create a new LayoutObject via the pointer within the locale-specific object.

  4. Otherwise, _GetLayoutInitFunc() will be called to load in the locale-dependent module and return a function pointer to _LayoutObjectInit() for the specified locale. This function pointer will be added to a list to be reused for the same locale in the future as in step 2.

  5. If the locale-dependent module cannot be loaded for the specified locale, _LayoutObjectGetHandle() will return NULL.

  6. The actual creation and initialization of the LayoutObject is done within each locale-dependent implementation of _LayoutObjectInit().

Sample Code

/* Following is part of the locale-independent module */

#define CTLObjectRelease          1

static LayoutMethodsRec _DefaultLayoutMethods = {
 _LSDefaultCreate,
 _LSDefaultDestroy,
 _LSDefaultGetValues,
 _LSDefaultSetValues,
 _LSDefaultTransform,
 _LSDefaultWCSTransform,
    };

    };
typedef struct _InitFuncListRec  *InitFuncList;

typedef struct  _InitFuncListRec {
    void  *func   /* function pointer to _LayoutObjectInit() */
    char  *locale_name; /* locale of _LayoutObjectInit() */
    InitFuncList   next;  /* Pointer to next element of the list */
} InitFuncListRec;

/*
 *  Entry point of to create and initialize the default layout object.
 *
 */
LayoutObject
_LayoutObjectDefaultInit(locale_name)
    char  *locale_name;
{
    LayoutObj            layout_obj;

    /* Allocate layout_obj. */
    /* Initialize layout_obj->methods and layout_obj->core  */
    /* Return layout_obj. */
}

/*
 *  Search if a layout object of the requested locale is created.
 *  If not, create one and add it to the list.
 */
static LayoutObject
_DoGetObjHandle (locale_name)
    char   *locale_name;
{
    LayoutObj   layout_obj;

   /*
    * Look up a list of existing loaded locale specific objects.
    * If the locale specific object is already loaded for the specified
    * locale, call _LayoutObjectInit() to create the layout object
    * via the pointer within the locale object.
    */

   /*
    *  If the locale specific object is not loaded for the specified
    *  locale, then call _GetLayoutInitFunc() to load the
    *  locale-specific object.
    */

   /*
    * If _GetLayoutInitFunc() returns is not NULL, then add
    * the new object to the list and call _LayoutObjectInit() to
    * create layout_obj.  Then return layout_obj when its done.
    * Otherwise, return NULL.
    */
}

/*
 * Get LayoutObj of current locale.
 * If that failed, try it with C locale.
 */
LayoutObj
_LayoutObjectGetHandle (locale_name)
    char *locale_name;
{
    LayoutObj            layout_obj;

    /* Default locale_name to C if it is not set. */
    /*
     *  Use _DoGetObjHandle() to retrieve layout_obj
     *  base on locale_name and return layout_obj.
     */
}

/*
 *  Do actual loading of the load-dependent object.
 *  Then return the function pointer to _LayoutObjectInit.
 */
static void *
_GetLayoutInitFunc(locale_name)
    char  *locale_name;
{
    /* If locale_name is NULL, then return NULL. */
    /*
     * Otherwise, dynamically load in the locale specific
     * module.  Then return the function pointer to _LayoutObjectInit.
     */
}

Common Naming for Layout Values

#define AllTextDescriptors     0x0000007f

#define Orientation            1L
#define Context               (1L<<1)
#define TypeOfText            (1L<<2)
#define ImplicitAlg           (1L<<3)
#define Swapping              (1L<<4)
#define Numerals              (1L<<5)
#define TextShaping           (1L<<6)

#define ActiveDirectional     (1L<<16)
#define ActiveShapeEditing    (1L<<17)
#define ShapeCharset          (1L<<18)
#define ShapeCharsetSize      (1L<<19)
#define ShapeContextSize      (1L<<20)
#define InOutTextDescrMask    (1L<<21)
#define InOnlyTextDescr       (1L<<22)
#define OutOnlyTextDescr      (1L<<23)
#define CheckMode             (1L<<24)
#define QueryValueSize        (1L<<25)

/* Possible values for Orientation */
#define ORIENTATION_LTR        0x00000001
#define ORIENTATION_RTL        0x00000002
#define ORIENTATION_TTBRL      0x00000003
#define ORIENTATION_TTBLR      0x00000004
#define ORIENTATION_CONTEXTUAL 0x00000005
  
/* Possible values for Context */
#define CONTEXT_LTR            0x00000010
#define CONTEXT_RTL            0x00000020

/* Possible values for TypeOfText */
#define TEXT_IMPLICIT          0x00000100
#define TEXT_EXPLICIT          0x00000200
#define TEXT_VISUAL            0x00000300

/* Possible values for ImplicitAlg */
#define ALGOR_BASIC            0x00001000
#define ALGOR_IMPLICIT         0x00002000

/* Possible values for Swapping */
#define SWAPPING_NO            0x00010000
#define SWAPPING_YES           0x00020000

/* Possible values for Numerals */
#define NUMERALS_NOMINAL       0x00100000
#define NUMERALS_NATIONAL      0x00200000
#define NUMERALS_CONTEXTUAL    0x00300000

/* Possible values for TextShaping */
#define TEXT_SHAPED            0x01000000
#define TEXT_NOMINAL           0x02000000
#define TEXT_SHFORM1           0x03000000
#define TEXT_SHFORM2           0x04000000
#define TEXT_SHFORM3           0x05000000
#define TEXT_SHFORM4           0x06000000

/* Possible values for CheckMode */
#define MODE_STREAM            0x00000001
#define MODE_EDIT              0x00000002

#define MaskAllTextDescriptors 0x0fffffff
#define MaskOrientation        0x0000000f
#define MaskContext            0x000000f0
#define MaskTypeOfText         0x00000f00
#define MaskImplicitAlg        0x0000f000
#define MaskSwapping           0x000f0000
#define MaskNumerals           0x00f00000
#define MaskTextShaping        0x0f000000

/* Mask for the Property parament of m_*transform() */
#define NESTLEVEL_MASK         0x0f
#define DISPLAYCELL_MASK       0x10


Why not acquire a nicely bound hard copy?
Click here to return to the publication details or order a copy of this publication.

Contents Next section Index