# Porting your legacy HOOPS I.M. code

In Release 17, HOOPS I.M. underwent a redesign. The new interface is type safe with opaque data structures. These new features have given the HOOPS development team more flexibility to increase the stability and performance of the intermediate mode environment.

The I.M. functions and their names have remained the same. However, the I.M. data structures have changed. As a consequence, many function signatures have changed as well. For example, prior to Release 17, it was legal to pass an array with three floats in place of passing the I.M. data structure `HT_RGB` when calling `HIC_Set_Face_Color`. Now, if you call `HIC_Set_Face_Color`, it accepts neither an array of three floats or `HT_RGB`. Instead, it expects a new data structure, HIC_RGB. `HIC_RGB` and `HT_RGB` are primarily the same. They both encapsulate color information. So, you can still pass an array of three floats but you must first explicitly cast the array to `const HIC_RGB*`. When porting your code, the new parameters for the I.M functions are primarily the same as their original counterparts in functionality with the main difference being that the name now has a `HIC` prefix instead of an `HT` prefix. For instance, `HIC_RGB`’s counterpart in Release 16 is `HT_RGB`. In most cases, to port your code, you simply need to explicitly cast your data into the new data type and use the keyword const.

Another important difference between the new data structures and their original counterparts is that Release 17 data structures are opaque. In prior releases, it was legal to directly access any members in an I.M. data structure. As of Release 17, to retrieve member information from a given I.M. data structure, you should use the provided Show function. For instance, to find the value of the blue component for the current face color, you can call `HIC_Show_Face_Color_Blue` and pass in a pointer to an instance of `HIC_Rendition`.

Let’s look at an example as how one of our sample programs is ported to the new I.M. interface. In lines.c, we set up a callback point at “draw dc polylines” with the function user_defined_lines. Below, we see the original function signature for user_defined_lines:

    void user_defined_lines (
            HT_Rendition    *rendition,
            int                     count,
            HT_DC_Point             *points)
    {...

In the sample snippet below is the ported function signature for user_defined_lines. As you can see, `HT_Rendition` is replaced with `HIC_Rendition` while `HT_DC_Point` is now `HIC_DC_Point`:

    void user_defined_lines (
            HIC_Rendition   const *rendition,
            int                             count,
            HIC_DC_Point            const *points)
    {...

In the user_defined_lines function, we determine how to render a line by looking at the user option set on the segment. When the user option is set to `MEASURED_DASHES`, the function sets the line color to the variable purple which is defined as an array of three floats. In the original function below, we call `HIC_Set_Line_Color` passing purple as an array of three floats even when the function is asking for an `HT_RGB` structure:

    ...
    float purple[] = {1.0f, 0.0f, 1.0f};
    ...
    void user_defined_lines (
            HT_Rendition    *rendition,
            int                     count,
            HT_DC_Point             *points)
    {...
            case MEASURED_DASHES: {
                    long            length;
                    HT_Rendition    *new_rendition;

                    length = (long)HIC_Show_User_Option_By_Index (rendition,
                                                              MY_DASH_SIZE_IN_PTS);

                    new_rendition = HIC_New_Rendition (rendition);
                    HIC_Set_Line_Weight (new_rendition, 5);

                    /************************************
                    Setting the line color to purple by
                    passing an array of floats.
                    *************************************/
                    HIC_Set_Line_Color (new_rendition, purple);

                    HIC_Draw_DC_Polyline (new_rendition, count, points);
                    HIC_Free_Rendition (new_rendition);

    ....

In the ported code below, when `HIC_Set_Line_Color` is called, purple is still passed as the color parameter but it is cast explicitly to the `HIC_RGB` data structure and with the `const` keyword:

    ...
    float purple[] = {1.0f, 0.0f, 1.0f};
    ...

    void user_defined_lines (
            HIC_Rendition   const *rendition,
            int                             count,
            HIC_DC_Point            const *points)
    {...

            case MEASURED_DASHES: {
                    long            length;
                    HIC_Rendition   const *new_rendition;

                    length = (long)HIC_Show_User_Option_By_Index (rendition,
                                                              MY_DASH_SIZE_IN_PTS);

                    new_rendition = HIC_New_Rendition (rendition);
                    HIC_Set_Line_Weight (new_rendition, 5);

                    /************************************
                    Setting the line color to purple by
                    passing an array of floats that has
                    been cast to the correct data type.
                    *************************************/
                    HIC_Set_Line_Color (new_rendition, (const HIC_RGB*)purple);

                    HIC_Draw_DC_Polyline (new_rendition, count, points);
                    HIC_Free_Rendition (new_rendition);
            }   break;

    ...

Another important point to note is how user option information is obtained from an `HIC_Rendition` data structure. In prior releases, you could access data directly from the rendition structure or use the show function as seen in the code sample below:

    // obtaining user option information from a show function
    length = (long)HIC_Show_User_Option_By_Index (rendition, MY_LINE_PATTERN);

    // obtaining user option information by accessing the internal data directly
    length = (long)rendition->user_rendition->values[MY_LINE_PATTERN].value;

As of Release 17, data structures like `HIC_Rendition` are opaque. Thus, it is not possible to access any internal data directly. Instead, you must use a `Show` function like `HIC_Show_User_Option_By_Index`.