Previous section.

Portable Layout Services: Context-dependent and Directional Text

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

Layout APIs

This chapter defines the m_*_layout() functions in alphabetical order. Context-dependent and Directional Text - m_create_layout
Previous section.


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

NAME

m_create_layout - initialise a layout object

SYNOPSIS

#include <sys/layout.h>

LayoutObject m_create_layout(const AttrObject attrobj, const char* modifier);

DESCRIPTION

The m_create_layout() function creates a LayoutObject associated with the locale identified by attrobj.

The LayoutObject is an opaque object containing all the data and methods necessary to perform the layout operations on context-dependent or directional characters of the locale identified by the attrobj. The memory for the LayoutObject is allocated by m_create_layout.() The LayoutObject created has default layout values. (If the modifier argument is not NULL, the layout values specified by the modifier overwrite the default layout values associated with the locale). The defaults are given in Layout Values . Also, internal states maintained by the layout transformation function across transformations, are set to their initial values. The internal state values are implementation dependent and their specifications are not explicitly presented in this document.

The attrobj argument is or may be an amalgam of many opaque objects. A locale object is just one example of the type of object that can be attached to an attribute object. The attrobj argument specifies a name that is usually associated with a locale category. If attrobj is null, the created LayoutObject is associated with the current locale as set by the setlocale() function.

The modifier argument can be used to announce a set of layout values when the LayoutObject is created. The syntax for this argument is defined in Layout Modifiers .

RETURN VALUE

Upon successful completion, the m_create_layout() function returns a LayoutObject for use in subsequent calls to m_*_layout() functions. Otherwise the m_create_layout() function returns (LayoutObject)0 and sets errno to indicate the error.

ERRORS

The m_create_layout() function may fail if:

[EINVAL]

The modifier string has a syntax error or it contains unknown layout values.

[EBADF]

The attribute object is invalid or the locale associated with the attribute object is not available.

[EMFILE]

{OPEN_MAX} file descriptors are currently open in the calling process.

[ENOMEM]

Insufficient storage space is available.

Context-dependent and Directional Text - m_destroy_layout
Previous section.

NAME

m_destroy_layout - destroy a layout object

SYNOPSIS

#include <sys/layout.h>

int m_destroy_layout(const LayoutObject layoutobject);

DESCRIPTION

The m_destroy_layout() function destroys a LayoutObject by deallocating the layout object and all the associated resources previously allocated by the m_create_layout() function.

RETURN VALUE

Upon successful completion, a value of zero is returned. Otherwise a value of -1 is returned and errno is set to indicate the error.

ERRORS

The m_destroy_layout() function may fail if:

[EBADF]

The attribute object is erroneous.

[EFAULT]

Errors occurred while processing the request.

Context-dependent and Directional Text - m_getvalues_layout
Previous section.

NAME

m_getvalues_layout - query layout values of a LayoutObject

SYNOPSIS

#include <sys/layout.h>

int m_getvalues_layout(const LayoutObject layout_object, LayoutValues values, int *index_returned);

DESCRIPTION

The m_getvalues_layout() function is used to query the current setting of layout values within a LayoutObject.

The layout_object argument specifies a LayoutObject returned by the m_create_layout() function.

The values argument specifies the list of layout values that are to be queried. (see Type LayoutValues ). Each value element of a LayoutValueRec must point to a location where the layout value is stored. That is, if the layout value is of type T, the argument must be of type T*. The values are queried from the LayoutObject and represent its current state.

It is the user's responsibility to manage the space allocation for the layout values queried. If the layout value name has QueryValueSize ORed to it, instead of the value of the layout value, only its size is returned. This option can be used by the caller to determine the amount of memory needed to be allocated for the layout values queried (see QueryValueSize (G) ).

RETURN VALUE

When the m_getvalues_layout() function completes without errors a zero is returned. If any value cannot be queried, the index of the value causing the error is returned in index_returned, a -1 value is returned and errno is set to indicate the error.

ERRORS

The m_getvalues_layout() function may fail if:

[EINVAL]

The layout value specified by index_returned is unknown or its value is invalid or the argument layout_object is invalid. In the case of an invalid layout_object argument, the value returned for index_returned is -1.

Context-dependent and Directional Text - m_setvalues_layout
Previous section.

NAME

m_setvalues_layout - set layout values of a LayoutObject

SYNOPSIS

#include <sys/layout.h>

int m_setvalues_layout(LayoutObject layout_object, const LayoutValues values, int *index_returned);

DESCRIPTION

The m_setvalues_layout() function is used to change the layout values of a LayoutObject.

The layout_object argument specifies a LayoutObject returned by the m_create_layout() function.

The values argument specifies the list of layout values (see Type LayoutValues ). that are to be changed. The values are written into the LayoutObject and may affect the behaviour of subsequent layout functions.

Note:
Some layout values do alter internal states maintained by a LayoutObject.

The m_setvalues_layout() function can be implemented as a macro that evaluates the first argument twice.

RETURN VALUE

Upon successful completion the requested layout values are set and a value of zero is returned. Otherwise a value of -1 is returned and errno is set to indicate the error. If any value cannot be set, none of the layout values is changed and the (zero-based) index of the first value causing the error is returned in index_returned.

ERRORS

The m_setvalues_layout() function may fail if:

[EINVAL]

The layout value specified by index_returned is unknown or its value is invalid or the argument layout_object is invalid.

[EMFILE]

{OPEN_MAX} file descriptors are currently open in the calling process.

APPLICATION USAGE

Do not use expressions with side effects such as auto-increment or auto-decrement within the first argument to the m_setvalues_layout() function.
Context-dependent and Directional Text - m_transform_layout
Previous section.

NAME

m_transform_layout - layout transformation

SYNOPSIS

#include <sys/layout.h>

int m_transform_layout( LayoutObject layout_object, const char *InpBuf, const size_t InpSize, void *OutBuf, size_t *Outsize, size_t *InpToOut, size_t *OutToInp, unsigned char *Property, size_t *InpBufIndex );

DESCRIPTION

This function performs layout transformations (reordering, shaping, cell determination) or it may provide additional information needed for layout transformation (such as the expected size of the transformed layout, the nesting level of different segments in the text and cross references between the locations of the corresponding elements before and after the layout transformation). Both the input text and output text are character strings.

The m_transform_layout() function transforms the input text in InpBuf according to the current layout values in layout_object. Any layout value whose value type is LayoutTextDescriptor describes the attributes of the InpBuf and OutBuf arguments. If the attributes are the same for both InpBuf and OutBuf, a null transformation is performed with respect to that specific layout value.

The InpBuf argument specifies the source text to be processed. The InpBuf may not be NULL, unless there is a need to reset the internal state.

The InpSize argument is the number of bytes within InpBuf to be processed by the transformation. Its value will not change after return from the transformation. InpSize set to -1 indicates that the text in InpBuf is delimited by a NULL code element. If InpSize is not set to -1, it is possible to have some NULL elements in the input buffer. This might be used, for example, for a "one shot" transformation of several strings, separated by NULLs.

Outputs of this function may be one or more of the following depending on the setting of the arguments:

OutBuf

Any transformed data is stored in OutBuf, converted to ShapeCharset.

Outsize

The number of bytes in OutBuf.

InpToOut

A cross reference from each InpBuf code element to the transformed data. The cross reference relates to the data in InpBuf starting with the first element that InpBufIndex points to (and not necessarily starting from the beginning of the InpBuf).

OutToInp

A cross reference to each InpBuf code element from the transformed data. The cross reference relates to the data in InpBuf starting with the first element that InpBufIndex points to (and not necessarily starting from the beginning of the InpBuf).

Property

A weighted value that represents peculiar input string transformation properties with different connotations as explained below.

If this argument is not a NULL pointer, it represents an array of values with the same number of elements as the source substring text before the transformation. Each byte will contain relevant "property" information of the corresponding element in InpBuf starting from the element pointed by InpBufIndex. The four rightmost bits of each "property" byte will contain information for bidirectional environments (when ActiveDirectional is True) and they will mean "NestingLevels". The possible value from 0 to 15 represents the nesting level of the corresponding element in the InpBuf starting from the element pointed by InpBufIndex. If ActiveDirectional is false the content of NestingLevel bits will be ignored. The leftmost bit of each "property" byte will contain a "new cell indicator" for composed character environments, and will have a value of either 1 (for an element in InpBuf that is transformed to the beginning of a new cell) or zero (for the "zero-length" composing character elements, when these are grouped into the same presentation cell with a non-composing character). Here again, each element of "property" pertains to the elements in the InpBuf starting from the element pointed by InpBufIndex. (Remember that this is not necessarily the beginning of InpBuf). If none of the transformation properties is required, the argument Property can be NULL.

The use of "property" can be enhanced in the future to pertain to other possible usage in other environments.

The InpBufIndex argument is an offset value to the location of the transformed text. When m_transform_layout() is called, InpBufIndex contains the offset to the element in InpBuf that will be transformed first. (Note that this is not necessarily the first element in InpBuf). At the return from the transformation, InpBufIndex contains the offset to the first element in the InpBuf that has not been transformed. If the entire substring has been transformed successfully, InpBufIndex will be incremented by the amount defined by InpSize.

Each of these output arguments may be NULL to specify that no output is desired for the specific argument, but at least one of them should be set to non-NULL to perform any significant work.

The layout object maintains a directional state that keeps track of directional changes, based on the last segment transformed. The directional state is maintained across calls to the layout transformation functions and allows stream data to be processed with the layout functions. The directional state is reset to its initial state whenever any of the layout values TypeOfText, Orientation or ImplicitAlg is modified by means of a call to m_setvalues_layout.()

The layout_object argument specifies a LayoutObject returned by the m_create_layout() function.

The OutBuf argument contains the transformed data. This argument can be specified as a NULL pointer to indicate that no transformed data is required.

The encoding of the OutBuf argument depends on the ShapeCharset layout value defined in layout_object. If the ActiveShapeEditing layout value is not set (False), the encoding of OutBuf is guaranteed to be the same as the codeset of the locale associated with the LayoutObject defined by layout_object.

On input, the OutSize argument specifies the size of the output buffer in number of bytes. The output buffer should be large enough to contain the transformed result; otherwise, only a partial transformation is performed. If the ActiveShapeEditing layout value is set (True) the OutBuf should be allocated to contain at least the InpSize multiplied by ShapeCharsetSize.

On return, the OutSize argument is modified to the actual number of bytes placed in OutBuf.

When the OutSize argument is specified as zero, the function calculates the size of an output buffer large enough to contain the transformed text, and the result is returned in this field. The content of the buffers specified by InpBuf and OutBuf, and the value of InpBufIndex, remain unchanged. If OutSize = NULL, the [EINVAL] error condition should be returned.

If the InpToOut argument is not a NULL pointer, it points to an array of values with the same number of bytes in InpBuf starting with the one pointed by InpBufIndex and up to the end of the substring in the buffer. On output, the nth value in InpToOut corresponds to the nth byte in InpBuf. This value is the index (in units of bytes) in OutBuf that identifies the transformed ShapeCharset element of the nth byte in InpBuf. In the case of multibyte encoding, the index points (for each of the bytes of a code element in the InpBuf) to the first byte of the transformed code element in the OutBuf.

InpToOut may be specified as NULL if no index array from InpBuf to OutBuf is desired.

If the OutToInp argument is not a NULL pointer, it points to an array of values with the same number of bytes as contained in OutBuf. On output, the nth value in OutToInp corresponds to the nth byte in OutBuf. This value is the index in InpBuf, starting with the byte pointed to by InpBufIndex, that identifies the logical code element of the nth byte in OutBuf. In the case of multibyte encoding, the index will point for each of the bytes of a transformed code element in the OutBuf to the first byte of the code element in the InpBuf.

OutToInp may be specified as NULL if no index array from OutBuf to InpBuf is desired.

To perform shaping of a text string without reordering of code elements, the layout_object should be set with input and output layout value TypeOfText set to TEXT_VISUAL and both in and out of Orientation set to the same value.

RETURN VALUE

If successful, the m_transform_layout() function returns zero. If unsuccessful, the returned value is -1 and the errno is set to indicate the source of error. When the size of OutBuf is not large enough to contain the entire transformed text, the input text state at the end of the uncompleted transformation is saved internally and the error condition [E2BIG] is returned in errno.

ERRORS

The m_transform_layout() function may fail if:

[EILSEQ]

Transformation stopped due to an input code element that cannot be shaped or is invalid. The InpBufIndex argument is set to indicate the code element causing the error. The suspect code element is either a valid code element but cannot be shaped into the ShapeCharset layout value, or is an invalid code element not defined by the codeset of the locale of layout_object. The mbtowc() and wctomb() functions, when used in the same locale as the LayoutObject, can be used to determine if the code element is valid.

[E2BIG]

The output buffer is full and the source text is not entirely processed.

[EINVAL]

Transformation stopped due to an incomplete composite sequence at the end of the input buffer, or OutSize contains NULL.

[ERANGE]

More than 15 embedding levels are in source text or InpBuf contain unbalanced directional layout information (push/pop) or an incomplete composite sequence has been detected in the input buffer at the beginning of the string pointed to by InpBufIndex.
Note:
An incomplete composite sequence at the end of the input buffer is not always detectable. Sometimes, the fact that the sequence is incomplete will only be detected when additional character elements belonging to the composite sequence are found at the beginning of the next input buffer.

[EBADF]

The layout values are set to a meaningless combination or the layout object is not valid.

APPLICATION USAGE

A LayoutObject will have a meaningful combination of default layout values. Whoever chooses to change the default layout values is responsible for making sure that the combination of layout values is meaningful. Otherwise, the result of m_transform_layout() might be unpredictable or implementation-specific with errno set to [EBADF].
Context-dependent and Directional Text - m_wtransform_layout
Previous section.

NAME

m_wtransform_layout - layout transformation for wide character strings

SYNOPSIS

#include <sys/layout.h>

int m_wtransform_layout ( LayoutObject layout_object, const wchar_t *InpBuf, const size_t InpSize, void *OutBuf, size_t *Outsize, size_t *InpToOut, size_t *OutToInp, unsigned char *Property, size_t *InpBufIndex );

DESCRIPTION

This function performs layout transformations (reordering and shaping, cell determination) or it may provide additional information needed for layout transformation (such as the expected size of the transformed layout, the nesting level of different segments in the text and cross references between the locations of the corresponding elements before and after the layout transformation). Both the input text and output text are wide character strings.

The m_wtransform_layout() function transforms the input text in InpBuf according to the current layout values in layout_object. Any layout value whose value type is LayoutTextDescriptor describes the attributes of the InpBuf and OutBuf. If the attributes are the same for both InpBuf and OutBuf, a null transformation is performed with respect to that specific layout value.

The InpBuf argument specifies the source text to be processed. The InpBuf may not be NULL, unless there is a need to reset the internal state.

The InpSize is the number of characters within InpBuf to be processed by the transformation. Its value will not change after return from the transformation. InpSize set to -1 indicates that the text in InpBuf is delimited by a NULL code element. If InpSize is not set to -1, it is possible to have some NULL elements in the input buffer. This might be used, for example, for a "one shot" transformation of several strings, separated by NULLs.

Outputs of this function may be one or more of the following depending on the setting of the arguments:

OutBuf

Any transformed data is stored in OutBuf, converted to ShapeCharset.

Outsize

The number of wide characters in OutBuf.

InpToOut

A cross reference from each InpBuf code element to the transformed data. The cross reference relates to the data in InpBuf starting with the first element that InpBufIndex points to (and not necessarily starting from the beginning of the InpBuf).

OutToInp

A cross reference to each InpBuf code element from the transformed data. The cross reference relates to the data in InpBuf starting with the first element that InpBufIndex points to (and not necessarily starting from the beginning of the InpBuf).

Property

A weighted value that represents peculiar input string transformation properties with different connotations as explained below.

If this argument is not a NULL pointer, it represents an array of values with the same number of elements as the source substring text before the transformation. Each byte will contain relevant "property" information of the corresponding element in InpBuf starting from the element pointed by InpBufIndex. The four rightmost bits of each "property" byte will contain information for bidirectional environments (when ActiveDirectional is True) and they will mean "NestingLevels". The possible value from 0 to 15 represents the nesting level of the corresponding element in the InpBuf starting from the element pointed by InpBufIndex. If ActiveDirectional is false the content of NestingLevel bits will be ignored. The leftmost bit of each "property" byte will contain a "new cell indicator" for composed character environments, and will have a value of either 1 (for an element in InpBuf that is transformed to the beginning of a new cell) or zero (for the "zero-length" composing character elements, when these are grouped into the same presentation cell with a non-composing character). Here again, each element of "property" pertains to the elements in the InpBuf starting from the element pointed by InpBufIndex. (Remember that this is not necessarily the beginning of InpBuf). If none of the transformation properties is required, the argument Property can be NULL.

The use of "property" can be enhanced in the future to pertain to other possible usage in other environments.

The InpBufIndex argument is an offset value to the location of the transformed text. When m_wtransform_layout() is called, InpBufIndex contains the offset to the element in InpBuf that will be transformed first. (Note that this is not necessarily the first element in InpBuf.) At the return from the transformation, InpBufIndex contains the offset to the first element in the InpBuf that has not been transformed. If the entire substring has been transformed successfully, InpBufIndex will be incremented by the amount defined by InpSize.

Each of these output arguments may be NULL to specify that no output is desired for the specific argument, but at least one of them should be set to non-NULL to perform any significant work.

In addition to the possible outputs above the layout_object maintains a directional state across calls to the transform functions. The directional state is reset to its initial state whenever any of the layout values TypeOfText, Orientation or ImplicitAlg is modified by means of a call to m_setvalues_layout().

The layout_object argument specifies a layout_object returned by the m_create_layout() function.

The OutBuf argument contains the transformed data. This argument can be specified as a NULL pointer to indicate that no transformed data is required.

The encoding of the OutBuf argument depends on the ShapeCharset layout value defined in layout_object. If the ActiveShapeEditing layout value is not set (False), the encoding of OutBuf is guaranteed to be the same as the codeset of the locale associated with the attribute object indicated during the creation of the Layout Object.

On input, the OutSize argument specifies the size of the output buffer in number of wide characters. The output buffer should be large enough to contain the transformed result; otherwise, only a partial transformation is performed. If the ActiveShapeEditing layout value is set (True) the OutBuf should be allocated to contain at least the InpSize multiplied by ShapeCharsetSize.

On return, the OutSize argument is modified to the actual number of code elements in OutBuf.

When the OutSize argument is specified as zero, the function calculates the size of an output buffer large enough to contain the transformed text, and the result is returned in this field. The content of the buffers specified by InpBuf and OutBuf, and the value of InpBufIndex, remain unchanged. If OutSize = NULL, the [EINVAL] error condition should be returned.

If the InpToOut argument is not a NULL pointer, it points to an array of values with the same number of wide characters in InpBuf starting with the one pointed by InpBufIndex and up to the end of the substring in the buffer. On output, the nth value in InpToOut corresponds to the nth wide character in InpBuf. This value is the index (in units of wide characters) in OutBuf that identifies the transformed ShapeCharset element of the nth wide character in InpBuf.

InpToOut may be specified as NULL if no index array from InpBuf to OutBuf is desired.

If the OutToInp argument is not a NULL pointer, it points to an array of values with the same number of wide characters as contained in OutBuf. On output the nth value in OutToInp corresponds to the nth wide character in OutBuf. This value is the index in InpBuf, starting with the wide character pointed to by InpBufIndex, that identifies the logical code element of the nth wide character in OutBuf.

OutToInp may be specified as NULL if no index array from OutBuf to InpBuf is desired.

To perform shaping of a text string without reordering of code elements, the layout_object should be set with input and output layout value TypeOfText set to TEXT_VISUAL and both in and out of Orientation set to the same value.

RETURN VALUE

If successful, the m_wtransform_layout() function returns a zero. If unsuccessful, the returned value is -1 and the errno is set to indicate the source of error. When the size of OutBuf is not large enough to contain the entire transformed text, the input text state at the end of the uncompleted transformation is saved internally and the error condition [E2BIG] is returned in errno.

ERRORS

The m_wtransform_layout() function may fail if:

[EILSEQ]

Transformation stopped due to an input code element that cannot be shaped or is invalid. The InfBufIndex argument is set to indicate the code element causing the error. The suspect code element is either a valid code element but cannot be shaped into the ShapeCharset layout value or is an invalid code element not defined by codeset of the locale of layout_object. The mbtowc() and wctomb() functions, when used in the same locale as the layoutobject, can be used to determine if the code element is valid.

[E2BIG]

The output buffer is full and the source text is not entirely processed.

[EINVAL]

Transformation stopped due to an incomplete composite sequence at the end of the input buffer, or OutSize contains NULL.

[ERANGE]

More than 15 embedding levels are in source text or InpBuf contain unbalanced directional layout information (push/pop) or an incomplete composite sequence has been detected in the input buffer at the beginning of the string pointed to by InpBufIndex.
Note:
An incomplete composite sequence at the end of the input buffer is not always detectable. Sometimes, the fact that the sequence is incomplete will only be detected when additional character elements belonging to the composite sequence are found at the beginning of the next input buffer.

[EBADF]

The layout values are set to a meaningless combination or the layout object is not valid.

APPLICATION USAGE

A LayoutObject will have a meaningful combination of default layout values. Whoever chooses to change the default layout values is responsible for making sure that the combination of layout values is meaningful. Otherwise, the result of m_transform_layout() might be unpredictable or implementation-specific with errno set to [EBADF].

EXAMPLES

The following example illustrates what the different arguments of m_wtransform_layout() look like when a string in InpBuf is shaped and reordered into OutBuf. Upper-case letters in the example represent left-to-right letters while lower-case letters represent right-to-left letters.
xyz represents the shapes of cde.
Position:           0123456789
InpBuf:             AB cde 12Z

Position: 0123456789 OutBuf: AB 12 zyxZ

Position: 0123456789 InpToOut: 0128765349

Position: 0123456789 OutToInp: 0127865439

Position: 0123456789 Property.NestLevel: 0001111220 Property.CelBdry: 1111111111

The values (encoded in binary) returned in the Property argument define the directionality of each code element in the source text as defined by the type of algorithm used within the layout_object. While the algorithm may be implementation dependent the resulting values and levels are defined such as to allow a single method to be used in determining the directionality of the source text. The base rules are:

Within a Property array each increment in the level indicates the corresponding code elements should be presented in the opposite direction. Callers of this function should realise that the Property values for certain code elements is dependent on the context of the given character and the layout values: Orientation and ImplicitAlg. Callers should not assume that a given code element always have the same Property value in all cases.

Example of Possible Presentation Algorithm
The following is an example of a standard presentation algorithm that handles nesting correctly. The goal of the algorithm is ultimately to return to a zero nest level.
Note:
More efficient algorithms do exist; the following is provided for clarity rather than for efficiency.

  1. Search for the highest nest level in the string.

  2. Reverse all surrounding code elements of the same level. Reduce the nest level of these code elements by 1.

  3. Repeat 1 and 2 until all code elements are of level 0.

The following shows the progression of the example from above:

Position:           0123456789    0123456789  0123456789
InpBuf:             AB cde 12Z    AB cde 21Z  AB 12 edcZ
Property.NestLevel: 0001111220    0001111110  0000000000
Property.CellBdry:  1111111111    1111111111  1111111111

Notes

  1. Using the InpBufIndex content and analysing the content of errno, in the case that an exceptional transformation event has occurred, the application can take steps to correct the reason for the exceptional events, such as enlarging the size of the OutBuf if [E2BIG] was returned, and it has the latitude to choose between different possible ulterior actions:

    Naturally the content of OutBuf will vary according to the option chosen and the caller to the m_transform_layout() function will be aware of it and use it as suitable.

  2. The "front" component of the layout value ShapeContextSize will be used for Thai in order to determine the maximum number of character elements needed before the first character element pointed to by InpBufIndex in order to correctly determine the cell group for the character elements at the beginning of the transformed substring.

  3. In Thai there is a possibility that though a sequence of character elements is correctly composing a Thai composite element, there is an additional composing character immediately following them that belongs to the same cell. Because this condition can be detected when processing the transformation of the subsequent substring where the "additional" composing element will be the first one, the [EINVAL] error value will not be set at the end of processing Thai substrings that end with a valid combination (that can potentially be incomplete after all).

  4. An example of possible use of MODE_EDIT for shaping based on locale specific assumptions is for scripts that have various shapes - initial, middle, isolated, final, and so on - and the shape of a character depends on its connecting ability to its neighbouring characters, if present. Assume that InpBuf contains newly keyed in data and the m_*transform_layout() function is used to shape this data in order to present it on the screen. If the value of CheckMode is MODE_EDIT, the last character entered (to which InpBufIndex points) will be shaped as if it is followed by another connect-to-the-right letter (as it happens in most of the cases) causing the transformation to use initial or middle shapes. If CheckMode were not set to MODE_EDIT such text would be transformed into isolated or final shapes (which may need to be reshaped to initial or middle shape once the next connect-to-the right letter belonging to the same word will be keyed in).

    The MODE_EDIT checking is also useful for scripts where determination of display cells is needed. Specifically where composite sequences may span display cell boundary.

  5. The SaraAm character from Thai can be shaped such that it affects the preceding character (that is, in some cases, the SaraAm is split at output; part of it is composed with the preceding consonant, and part of it is composed as a separate cell). Below is an example that shows how the transform function would behave in the case of this character.

    Let assume 'a' is a consonant and 'b' is a SaraAm character in the input buffer:

    Inp Buf:  | a | b | c |  | d |
    
    

    And, actual screen will look as follows:

    | b1|   | c2|   | d2|
    | a | b2| c1|   | d1|  <-- baseline symbol/consonant
    |   |   |   |   | d3|
    
    

    The results of a transform would be expected to behave as follows:

    Position:             | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 
    Inp Buf:              | a | b | c |   | d | 
    Inp BufIndex:           0
    Out Buf:              | a | b1| b2| c1| c2|   | d1| d2| d3| 
    InpToOut:             | 1 | 3 | 4 | 6 | 7 | 
    OutToInp:             | 1 | 2 | 2 | 3 | 3 | 4 | 5 | 5 | 5 | 
    Property.CellBdry:    | 1 | 1 | 1 | 1 | 1 | 
    Property.NestLevel:   | 0 | 0 | 0 | 0 | 0 | 
    InputBufIndex return:  10
    
    

    Note that the Property display cell boundary (Property.CelBdry) information says that the SaraAm character is in its own display cell. Yet it's shape actually affects the preceding display cell. But also note that the InpToOut index for the SaraAm ('b') character points to the 3rd position in the output buffer, while the indication that "part" of "b" in the form of "b1" appears in the same cell as "a" is reflected in the second position of OutToInp. Thus determination of the display cell boundary within the output buffer requires analysis of both the Property display cell information (that relates to the input buffer), as well as the OutToInp and the InpToOut buffer.

Contents Next section Index