/*DDK*************************************************************************/
/*                                                                           */
/* COPYRIGHT (C) Lexmark Corporation, 1989                                   */
/* COPYRIGHT    Copyright (C) 1995 IBM Corporation                           */
/*                                                                           */
/*    The following IBM OS/2 WARP source code is provided to you solely for  */
/*    the purpose of assisting you in your development of OS/2 WARP device   */
/*    drivers. You may use this code in accordance with the IBM License      */
/*    Agreement provided in the IBM Device Driver Source Kit for OS/2. This  */
/*    Copyright statement may not be removed.                                */
/*                                                                           */
/*****************************************************************************/
/**************************************************************************
 *
 * SOURCE FILE NAME = PRDASETB
 *
 * DESCRIPTIVE NAME =
 *
 *
 * VERSION
 *
 * DATE
 *
 * DESCRIPTION
 *
 * FUNCTIONS   prda_DeviceSetAttributes
 *             prda_DeviceGetAttributes
 *             prda_SetTextAttrs
 *             prda_SetLineAttrs
 *             prda_SetMarkAttrs
 *             prda_SetPtrnAttrs
 *             prda_SetImagAttrs
 *             prda_CheckDevFontValid
 *             prda_SetTextSimlFlag
 *             prda_GetDfltCharBox
 *
 * ENTRY POINTS:
 *
 * DEPENDENCIES:
 *
 * NOTES
 *
 *
 * STRUCTURES
 *
 * EXTERNAL REFERENCES
 *
 * EXTERNAL FUNCTIONS
 *
*/

#define INCL_32                         /* Convert to C/SET2    CON3201       */
#define INCL_DOSPROCESS                 /* Convert to C/SET2    CON3201       */
#define INCL_DOSSEMAPHORES
#define INCL_GPIPRIMITIVES
#define INCL_WINHEAP
#define INCL_GPIBITMAPS
#define INCL_GPIERRORS
#include <os2.h>
#undef INCL_DOSPROCESS                  /* Convert to C/SET2    CON3201       */
#undef INCL_DOSSEMAPHORES
#undef INCL_GPIPRIMITIVES
#undef INCL_WINHEAP
#undef INCL_GPIBITMAPS
#undef INCL_GPIERRORS

#define INCL_DDIBUNDLES
#define INCL_DDIFONTSTRUCS
#define INCL_DDIDEFS
#define INCL_DDICOMFLAGS
#define INCL_DDIMISC
#define INCL_GRE_XFORMS
#include <pmddi.h>
#undef INCL_DDIBUNDLES
#undef INCL_DDIFONTSTRUCS
#undef INCL_DDIDEFS
#undef INCL_DDICOMFLAGS
#undef INCL_DDIMISC
#undef INCL_GRE_XFORMS

#define INCL_WINP_SELECTIVE
#define INCL_WINP_SEI
#include <pmwinx.h>
#undef INCL_WINP_SELECTIVE
#undef INCL_WINP_SEI

#include <prdacone.h>
#include <prdconse.h>
#include <prddcone.h>
#include <prdtcone.h>

#define NO_CONSTANT_INCL
#include <prdinclt.h>
#undef NO_CONSTANT_INCL

#include <prdaextf.h>
#include <prdcextf.h>
#include <prdgextf.h>
#include <prdtextf.h>


extern DCHARBUNDLE      prda_DefTxtAts;    /* Set up access to the    */
extern DLINEBUNDLE      prda_DefLinAts;    /* various default         */
extern DMARKERBUNDLE    prda_DefMrkAts;    /* attribute bundles       */
extern DAREABUNDLE      prda_DefPtnAts;    /*                         */
extern DIMAGEBUNDLE     prda_DefImgAts;    /*                         */

extern BYTE             LineTypeTable [];  /* Set up access to the    */
                                           /* line type table         */

/**********************************************************************/
/* Set up access to engine convert function                           */
/**********************************************************************/
extern PFNL  da_ConvertWithMatrix;






/**********************************************************************/
/*                                                                    */
/*   FUNCTION: prda_DeviceSetAttributes                               */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*                                                                    */
/*   See "OS/2 Technical Reference: I/O Subsytems and Device Drivers" */
/*                                                                    */
/*   HDC            DcH;                                              */
/*   ULONG          ArgBundleType;                                    */
/*   ULONG          ArgDefsMask;                                      */
/*   ULONG          ArgAttrsMask;                                     */
/*   PBUNDLE        ArgAttributes;                                    */
/*   lpDCI          DCIData;                                          */
/*   ULONG          FunN;                                             */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/*   This function acts as a single entry point to set the various    */
/*   attributes.  ArgBundleType determines which (of line, character  */
/*   marker, pattern, image) attributes are to be set.  Then the      */
/*   function calls one of the prda_Set*Attrs functions to            */
/*   make the changes.                                                */
/*                                                                    */
/**********************************************************************/
/*   CON3201  Convert to C/SET2                                       */
ULONG EXPENTRY prda_DeviceSetAttributes (HDC      DcH,
                                         ULONG    ArgBundleType,
                                         ULONG    ArgDefsMask,
                                         ULONG    ArgAttrsMask,
                                         PBUNDLE  ArgAttributes,
                                         lpDCI    DCIData,
                                         ULONG    FunN )

{
#define TFUNC "prda_DevSetAttr"

    /******************************************************************/
    /* Local variables                                                */
    /******************************************************************/
    USHORT             DefMask;    /* The default and ...             */
    USHORT             AttrMask;   /*  ... attr masks to be passed to */
                                   /* the prda_Set*Attrs functions    */


    /******************************************************************/
    /* If the Attrs Mask is 0 then there is no need to set anything   */
    /* so return.                                                     */
    /******************************************************************/
    if ( !ArgAttrsMask )
        return (OK);

    /******************************************************************/
    /* Do entry processing                                            */
    /******************************************************************/
#ifdef PRD_TIMING
    DEKHOOK0(A,7,22)
#endif
    prdm_EnterDriver(DCIData);

    /******************************************************************/
    /* Set DefMask and AttrMask so that there is no overlap between   */
    /* them.  This means if a field is selected in both ArgDefsMask   */
    /* and ArgAttrsMask then the default values will be used by the   */
    /* prda_Set*Attrs function called and if a field is selected      */
    /* in only ArgDefsMask then it will be left unchanged. This is    */
    /* how prda_DeviceSetAttributes is supposed to work               */
    /******************************************************************/
    DefMask  = (USHORT)ArgAttrsMask & (USHORT)ArgDefsMask;
    AttrMask = (USHORT)ArgAttrsMask & (~DefMask);

    /******************************************************************/
    /* Switch to appropriate subroutine according to bundle type      */
    /* casting ArgAttributes to the appropriate type of pointer in    */
    /* the call.  The subroutines always return OK.                   */
    /******************************************************************/
    switch ( (USHORT)ArgBundleType )
    {
    case PRIM_LINE:
        prda_SetLineAttrs( DefMask,
                           AttrMask,
                           (PDLINEBUNDLE)ArgAttributes,
                           DCIData->DCICurLinAts,
                           DCIData );
        break;

    case PRIM_CHAR:
        if ( prda_SetTextAttrs( DcH,
                                DefMask,
                                AttrMask,
                                (PDCHARBUNDLE)ArgAttributes,
                                DCIData->DCICurTxtAts,
                                DCIData ) != OK )
        {
            LOGERR(TFUNC, "Invalid font attrs", FNULL, 0,
                                               PMERR_INV_FONT_ATTRS );
            prdm_LeaveDriver(DCIData);
#ifdef PRD_TIMING
    DEKHOOK0(A,7,A2)
#endif
            return (ERROR_ZERO);
        }
        break;

    case PRIM_MARKER:
        prda_SetMarkAttrs( DefMask,
                           AttrMask,
                           (PDMARKERBUNDLE)ArgAttributes,
                           DCIData->DCICurMrkAts );
        break;

    case PRIM_AREA:
        /**************************************************************/
        /* Update or reset the pattern attributes                     */
        /**************************************************************/
        prda_SetPtrnAttrs( DefMask,
                           AttrMask,
                           (PDAREABUNDLE)ArgAttributes,
                           DCIData->DCICurPtnAts );

        /**************************************************************/
        /* PD00474 : Pattern attributes have changed so the cached    */
        /* value is not valid any more. This field is looked at by    */
        /* PolyScanLine.                                              */
        /**************************************************************/
        DCIData->usPatValid = FALSE;

        /**************************************************************/
        /* For the area (pattern) attribute extra processing is       */
        /* necessary.  This requires us to transform the pattern      */
        /* origin from world coordinates in the attributes bundle to  */
        /* device coordinates in DC Instance data.                    */
        /**************************************************************/
        if ( prdg_Convert (
                      (PULONG)&DCIData->DCICurPtnAts->abnd.ptlRefPoint,
                      (PULONG)&DCIData->DCIPattOriDev,
                      COORD_WORLD, COORD_DEVICE_WORD, 1L,
                      (hanDC)DcH, COM_TRANSFORM ) != OK )
        {
            prdm_LeaveDriver(DCIData);
#ifdef PRD_TIMING
    DEKHOOK0(A,7,A2)
#endif
            return (ERROR_ZERO);
        }
        break;

    case PRIM_IMAGE:
        prda_SetImagAttrs( DefMask,
                           AttrMask,
                           (PDIMAGEBUNDLE)ArgAttributes,
                           DCIData->DCICurImgAts );
        break;

    default:
        prdm_LeaveDriver(DCIData);
#ifdef PRD_TIMING
    DEKHOOK0(A,7,A2)
#endif
        return (ERROR_ZERO);
        break;

    }
    /*.. switch ((USHORT)ArgBundleType) ................................*/

    prdm_LeaveDriver(DCIData);
#ifdef PRD_TIMING
    DEKHOOK0(A,7,A2)
#endif
    return (OK);

}
#undef TFUNC





/**********************************************************************/
/*                                                                    */
/*   FUNCTION: prda_DeviceGetAttributes                               */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*                                                                    */
/*   See "OS/2 Technical Reference: I/O Subsytems and Device Drivers" */
/*                                                                    */
/*   HDC            DcH;                                              */
/*   ULONG          ArgBundleType;                                    */
/*   ULONG          ArgAttrsMask;                                     */
/*   PBUNDLE        ArgAttributes;                                    */
/*   lpDCI          DCIData;                                          */
/*   ULONG          FunN;                                             */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/*   This function returns the current line, character, marker,       */
/*   pattern or image attributes depending on which one is specified  */
/*   in ArgBundleType).  Only foreground and background colours are   */
/*   returned.                                                        */
/*                                                                    */
/**********************************************************************/
/*   CON3201  Convert to C/SET2                                       */
ULONG EXPENTRY prda_DeviceGetAttributes ( HDC     DcH,
                                          ULONG   ArgBundleType,
                                          ULONG   ArgAttrsMask,
                                          PBUNDLE ArgAttributes,
                                          lpDCI   DCIData,
                                          ULONG   FunN )

{
#define TFUNC "prda_DevGetAtts"

#ifdef PRD_TIMING
    DEKHOOK0(A,7,23)
#endif
    prdm_EnterDriver(DCIData);

    /******************************************************************/
    /* Switch according to bundle type.  We only need to return       */
    /* information on foreground and background colours.  These could */
    /* the driver's special default values which are not known to the */
    /* system - allow for this before returning the colours.          */
    /******************************************************************/
    switch ( (USHORT)ArgBundleType )
    {
    case PRIM_LINE:
        if ( ArgAttrsMask & 0x0001L )
         /* ((LINEBUNDLE FAR *)ArgAttributes)->lColor = */
            ((LINEBUNDLE *)ArgAttributes)->lColor =        /* CON3201 */
              prdc_GetSystemColor( DCIData->DCICurLinAts->lbnd.lColor,
                                   DCIData );
        break;

    case PRIM_CHAR:
        if ( ArgAttrsMask & 0x0001L )
         /* ((CHARBUNDLE FAR *)ArgAttributes)->lColor = */
            ((CHARBUNDLE *)ArgAttributes)->lColor =        /* CON3201 */
              prdc_GetSystemColor( DCIData->DCICurTxtAts->cbnd.lColor,
                                   DCIData );

        if ( ArgAttrsMask & 0x0002L )
         /* ((CHARBUNDLE FAR *)ArgAttributes)->lBackColor = */
            ((CHARBUNDLE *)ArgAttributes)->lBackColor =    /* CON3201 */
              prdc_GetSystemColor( DCIData->DCICurTxtAts->cbnd.lBackColor,
                                   DCIData );
        break;

    case PRIM_MARKER:
        if ( ArgAttrsMask & 0x0001L )
         /* ((MARKERBUNDLE FAR *)ArgAttributes)->lColor = */
            ((MARKERBUNDLE *)ArgAttributes)->lColor =      /* CON3201 */
              prdc_GetSystemColor( DCIData->DCICurMrkAts->mbnd.lColor,
                                   DCIData );

        if ( ArgAttrsMask & 0x0002L )
         /* ((MARKERBUNDLE FAR *)ArgAttributes)->lBackColor = */
            ((MARKERBUNDLE *)ArgAttributes)->lBackColor =  /* CON3201 */
              prdc_GetSystemColor( DCIData->DCICurMrkAts->mbnd.lBackColor,
                                   DCIData );
        break;

    case PRIM_AREA:
        if ( ArgAttrsMask & 0x0001L )
         /* ((AREABUNDLE FAR *)ArgAttributes)->lColor = /*
            ((AREABUNDLE *)ArgAttributes)->lColor =        /* CON3201 */
              prdc_GetSystemColor( DCIData->DCICurPtnAts->abnd.lColor,
                                   DCIData );

        if ( ArgAttrsMask & 0x0002L )
         /* ((AREABUNDLE FAR *)ArgAttributes)->lBackColor = */
            ((AREABUNDLE *)ArgAttributes)->lBackColor =    /* CON3201 */
              prdc_GetSystemColor( DCIData->DCICurPtnAts->abnd.lBackColor,
                                   DCIData );
        break;

    case PRIM_IMAGE:
        if ( ArgAttrsMask & 0x0001L )
         /* ((IMAGEBUNDLE FAR *)ArgAttributes)->lColor = */
            ((IMAGEBUNDLE *)ArgAttributes)->lColor =       /* CON3201 */
              prdc_GetSystemColor( DCIData->DCICurImgAts->ibnd.lColor,
                                   DCIData );

        if ( ArgAttrsMask & 0x0002L )
         /* ((IMAGEBUNDLE FAR *)ArgAttributes)->lBackColor = */
            ((IMAGEBUNDLE *)ArgAttributes)->lBackColor =   /* CON3201 */
              prdc_GetSystemColor( DCIData->DCICurImgAts->ibnd.lBackColor,
                                   DCIData );
        break;

    default:
        prdm_LeaveDriver(DCIData);
#ifdef PRD_TIMING
    DEKHOOK0(A,7,A3)
#endif
        return (ERROR_ZERO);
        break;

    }
    /*.. switch ( (USHORT)ArgBundleType ) ........................... */

    prdm_LeaveDriver(DCIData);
#ifdef PRD_TIMING
    DEKHOOK0(A,7,A3)
#endif
    return (OK);

}
#undef TFUNC






/**********************************************************************/
/*                                                                    */
/*   FUNCTION: prda_SetTextAttrs                                      */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*                                                                    */
/*   USHORT         DefMask;           Mask determines which values   */
/*                                     are to be set to default       */
/*   USHORT         AttrMask;          Mask determines which values   */
/*                                     are to be set from Attributes  */
/*   PDCHARBUNDLE   Attributes;        New attributes passed in       */
/*   PDCHARBUNDLE   CurrAttrs;         Current attributes to be set   */
/*                                     according to DefMask, AttrMask */
/*                                     and Attributes                 */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/*   This function is called from prda_DeviceSetAttributes to set the */
/*   text attributes.  The attributes are set in two passes:  first   */
/*   the default attributes requested in DefMask are copied into the  */
/*   CurrAttrs and then the values from Attributes requested          */
/*   in AttrMask are copied into CurrAttrs.  Note that this           */
/*   means that attributes selected in DefMask AND AttrMask will be   */
/*   set from Attributes and NOT from the default attributes.         */
/*                                                                    */
/* PD00022 : Do not check the validity of the font. This is done in   */
/*           prdt_LocateFont. Also tidy up so that if an error        */
/*           occurs in locate font, then the font attributes are not  */
/*           affected.                                                */
/*                                                                    */
/**********************************************************************/
/*   CON3201  Convert to C/SET2                                       */
USHORT prda_SetTextAttrs ( HDC          DcH,
                           USHORT       DefMask,
                           USHORT       AttrMask,
                           PDCHARBUNDLE Attributes,
                           PDCHARBUNDLE CurrAttrs,
                           lpDCI        DCIData )

{
#define TFUNC "prda_SetTextAts"

    /******************************************************************/
    /* Local variables                                                */
    /******************************************************************/
    USHORT             Mask;           /* Mask determines which       */
                                       /* attributes to set           */
    PDCHARBUNDLE       Attrs;          /* Pointer to supplied         */
                                       /* attributes                  */
    PDCHARBUNDLE       DefAttrs;       /* Pointer to attrs bundle     */
                                       /* used for the default.       */
    CHARDEFS           Oldcdef;        /* Saved cDef in case the      */
                                       /* locate font fails           */
    USHORT             i;              /* Loop control variable       */


    /******************************************************************/
    /* The new set of current attributes are set up in two passes.    */
    /* The first pass sets any default values requested, the second   */
    /* sets any values supplied - this has the effect of setting the  */
    /* attributes to the supplied value when BOTH are requested.      */
    /******************************************************************/

    /******************************************************************/
    /* If DCIDefTxtAts has been set up use these as the default attrs */
    /* otherwise use the bundle in the data segment.                  */
    /******************************************************************/
    if ( (DefAttrs = DCIData->DCIDefTxtAts) == FNULL )
        DefAttrs = &prda_DefTxtAts;

    /******************************************************************/
    /* If a pointer to an attributes bundle has been passed then copy */
    /* the device bundle definition fields from this attributes       */
    /* bundle otherwise copy them from the default bundle and ensure  */
    /* that Attributes is a valid pointer by setting it up to point   */
    /* to the default attributes.                                     */
    /******************************************************************/
    if ( Attributes == FNULL )
        Attributes = DefAttrs;

    /******************************************************************/
    /* PD00022 : Safety work for the text attributes.                 */
    /* Save the cdef fields just in case something goes       with    */
    /* the locatefont call which occurs at the end of this function.  */
    /******************************************************************/
    Oldcdef.defSet   = CurrAttrs->cdef.defSet;
    Oldcdef.fFlags   = CurrAttrs->cdef.fFlags;
    Oldcdef.CodePage = CurrAttrs->cdef.CodePage;

    /******************************************************************/
    /* If any of the cdef fields change then we need to make sure     */
    /* the font data in the DCIData is updated (the bit flag used is  */
    /* also set on in prde_EnableDC).                                 */
    /******************************************************************/
    if ( (CurrAttrs->cdef.defSet   != Attributes->cdef.defSet) ||
         (CurrAttrs->cdef.fFlags   != Attributes->cdef.fFlags) ||
         (CurrAttrs->cdef.CodePage != Attributes->cdef.CodePage) )
    {
        /**************************************************************/
        /* The default char cdef structure is all zeroes which gives  */
        /* the default font.  EnableDC calls prda_SetTextAttrs to set */
        /* up the default text bundle - hence after that initial      */
        /* call the values contained in the cdef structure (and       */
        /* DCIFontData) will always be valid.                         */
        /*                                                            */
        /* [ See comments in prde_SetDCIDefaults on initialisation    */
        /*   of the font data. ]                                      */
        /**************************************************************/
        DCIData->DCIStateFlags |= LOCATE_FONT_REQD;

        CurrAttrs->cdef.defSet   = Attributes->cdef.defSet;
        CurrAttrs->cdef.fFlags   = Attributes->cdef.fFlags;
        CurrAttrs->cdef.CodePage = Attributes->cdef.CodePage;
    }

    /******************************************************************/
    /* Check that font is valid - if not, then quit.                  */
    /*                                                                */
    /* PD00022 : Remove this call. It does no useful processing. All  */
    /* the validation now occurs in prdt_LocateFont.                  */
    /******************************************************************/
/*  if ( !prda_CheckFontValid(&Attributes->cdef, DCIData) )  */
/*      return (ERROR_ZERO);                                 */

    /******************************************************************/
    /* The loop is processed exactly twice.  Mask and Attrs are set   */
    /* to do the defaults in the first loop and then they are         */
    /* changed to do the supplied values in the second loop.          */
    /******************************************************************/
    for ( Mask = DefMask , Attrs = DefAttrs, i = 2;
          i--;
          Mask = AttrMask, Attrs = Attributes )
    {
        /**************************************************************/
        /* For each of the attributes which is selected in Mask set   */
        /* the appropriate field in CurrAttrs to either the           */
        /* default or supplied value (depending on which pass this is)*/
        /**************************************************************/
        if ( Mask & CBB_COLOR )
            CurrAttrs->cbnd.lColor = Attrs->cbnd.lColor;

        if ( Mask & CBB_BACK_COLOR )
            CurrAttrs->cbnd.lBackColor = Attrs->cbnd.lBackColor;

        if ( Mask & CBB_MIX_MODE )
            CurrAttrs->cbnd.usMixMode = Attrs->cbnd.usMixMode;

        if ( Mask & CBB_BACK_MIX_MODE )
            CurrAttrs->cbnd.usBackMixMode = Attrs->cbnd.usBackMixMode;

        if ( Mask & CBB_SET )
            CurrAttrs->cbnd.usSet = Attrs->cbnd.usSet;

        if ( Mask & CBB_MODE )
        {
            DCIData->DCIStateFlags |= ESTABLISH_FONT_REQD;
            CurrAttrs->cbnd.usPrecision = Attrs->cbnd.usPrecision;
        }

        if ( Mask & CBB_BOX )
        {
            DCIData->DCIStateFlags |= ESTABLISH_FONT_REQD;
            if ( Attrs == DefAttrs )
            {
                /******************************************************/
                /* The default box dimensions depend on the current   */
                /* font data.                                         */
                /******************************************************/
                CurrAttrs->cbnd.sizfxCell.cx = prda_GetDfltCharBox(
                                                          DcH,
                                                          WIDTH,
                                                          WORLD_COORDS,
                                                          DCIData);
                CurrAttrs->cbnd.sizfxCell.cy = prda_GetDfltCharBox(
                                                          DcH,
                                                          HEIGHT,
                                                          WORLD_COORDS,
                                                          DCIData);
            }
            else
            {
                /**************************************************************/
                /* PD00073 : Removed absolute value abs() from right side for */
                /* both cx and cy below.                                      */
                /**************************************************************/
                CurrAttrs->cbnd.sizfxCell.cx = Attrs->cbnd.sizfxCell.cx;
/*                           (FIXED)abs((LONG)Attrs->cbnd.sizfxCell.cx);  */
                CurrAttrs->cbnd.sizfxCell.cy = Attrs->cbnd.sizfxCell.cy;
/*                           (FIXED)abs((LONG)Attrs->cbnd.sizfxCell.cy);  */
            }
        }

        if ( Mask & CBB_ANGLE )
        {
            DCIData->DCIStateFlags |= ESTABLISH_FONT_REQD;
            CurrAttrs->cbnd.ptlAngle.x = Attrs->cbnd.ptlAngle.x;
            CurrAttrs->cbnd.ptlAngle.y = Attrs->cbnd.ptlAngle.y;
        }

        if ( Mask & CBB_SHEAR  )
        {
            DCIData->DCIStateFlags |= ESTABLISH_FONT_REQD;
            CurrAttrs->cbnd.ptlShear.x = Attrs->cbnd.ptlShear.x;
            CurrAttrs->cbnd.ptlShear.y = Attrs->cbnd.ptlShear.y;
        }

        if ( Mask & CBB_DIRECTION )
        {
            CurrAttrs->cbnd.usDirection = Attrs->cbnd.usDirection;
        }
 /**************************************************************************/
 /* CON3201 - Added three more if statements to set up the new             */
 /* charbundle structure members                                           */
 /**************************************************************************/
        if ( Mask & CBB_TEXT_ALIGN )
        {
            CurrAttrs->cbnd.usTextAlign = Attrs->cbnd.usTextAlign;
        }
        if ( Mask & CBB_EXTRA )
        {
            CurrAttrs->cbnd.fxExtra = Attrs->cbnd.fxExtra;
        }
        if ( Mask & CBB_BREAK_EXTRA )
        {
            CurrAttrs->cbnd.fxBreakExtra = Attrs->cbnd.fxBreakExtra;
        }

    }

    /******************************************************************/
    /*                                                                */
    /* Call LocateFont if the font, codepage or engine attributes     */
    /* have changed. LocateFont calls EstablishFont.                  */
    /*                                                                */
    /* Call prdt_EstablishFont if the CharMode or CharBox was changed */
    /* above (i.e. if one of the masks contained a CBB_BOX or a       */
    /* CBB_MODE flag).                                                */
    /*                                                                */
    /* If the char mode or char box changes, then CPtInfo might       */
    /* have become invalid, so call EstablishFont to reset.           */
    /*                                                                */
    /* Also call prdt_EstablishFont if the angle or shear changes, as */
    /* these will change the world/device transform matrices.         */
    /******************************************************************/
    if ( DCIData->DCIStateFlags & LOCATE_FONT_REQD )
    {
        if ( prdt_LocateFont(&DCIData->DCIFontData, DCIData) != OK )
        {
            /**********************************************************/
            /* PD00022 : LocateFont does not like the cdefs field, so */
            /* restore the old version.                               */
            /**********************************************************/
            CurrAttrs->cdef.defSet   = Oldcdef.defSet;
            CurrAttrs->cdef.fFlags   = Oldcdef.fFlags;
            CurrAttrs->cdef.CodePage = Oldcdef.CodePage;

            /**********************************************************/
            /* Now return zero to indicate that the set attributes    */
            /* failed.                                                */
            /**********************************************************/
            return (ERROR_ZERO);
        }

        /**************************************************************/
        /* Locate font and establish font are done.                   */
        /**************************************************************/
        DCIData->DCIStateFlags &= ~LOCATE_FONT_REQD;
        DCIData->DCIStateFlags &= ~ESTABLISH_FONT_REQD;

    }
    else if ( DCIData->DCIStateFlags & ESTABLISH_FONT_REQD )
    {
        /**************************************************************/
        /* Same font, but char box or mode has changed.               */
        /**************************************************************/
        (VOID) prdt_EstablishFont(&DCIData->DCIFontData, DCIData);
        DCIData->DCIStateFlags &= ~ESTABLISH_FONT_REQD;
    }

    /******************************************************************/
    /* Now all the bundle attributes have been set we can set up the  */
    /* "simulation required" flags which are stored in DCIData.       */
    /******************************************************************/
    prda_SetTextSimlFlag(DCIData);

    return (OK);
}
#undef TFUNC







/**********************************************************************/
/*                                                                    */
/*   FUNCTION: prda_SetLineAttrs                                      */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*                                                                    */
/*   USHORT         DefMask;           Mask determines which values   */
/*                                     are to be set to default       */
/*   USHORT         AttrMask;          Mask determines which values   */
/*                                     are to be set from Attributes  */
/*   PDLINEBUNDLE   Attributes;        New attributes passed in       */
/*   PDLINEBUNDLE   CurrAttrs;         Current attributes to be set   */
/*                                     according to DefMask, AttrMask */
/*                                     and Attributes                 */
/*   lpDCI          DCIData;           Pointer to Instance data       */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/*   This function is called from prda_DeviceSetAttributes to set the */
/*   line attributes.  The attributes are set in two passes:  first   */
/*   the default attributes requested in DefMask are copied into the  */
/*   CurrAttrs and then the values from Attributes requested          */
/*   in AttrMask are copied into CurrAttrs.  Note that this           */
/*   means that attributes selected in DefMask AND AttrMask will be   */
/*   set from Attributes and NOT from the default attributes.         */
/*                                                                    */
/**********************************************************************/
/*   CON3201  Convert to C/SET2                                       */
VOID prda_SetLineAttrs ( USHORT       DefMask,
                         USHORT       AttrMask,
                         PDLINEBUNDLE Attributes,
                         PDLINEBUNDLE CurrAttrs,
                         lpDCI        DCIData )

{
#define TFUNC "prda_SetLineAttrs"

    /******************************************************************/
    /* Local variables                                                */
    /******************************************************************/
    USHORT             Mask;           /* Mask determines which       */
                                       /* attributes to set           */
    PDLINEBUNDLE       Attrs;          /* Pointer to supplied         */
                                       /* attributes                  */
    USHORT             i;              /* loop control variable       */


    /******************************************************************/
    /* The new set of current attributes are set up in two passes.    */
    /* The first pass sets any default values requested, the second   */
    /* sets any values supplied - this has the effect of setting the  */
    /* attributes to the supplied value when BOTH are requested.      */
    /******************************************************************/

    /******************************************************************/
    /* If a pointer to an attributes bundle has been passed then copy */
    /* the device bundle definition fields from this attributes       */
    /* bundle otherwise copy them from the default bundle and ensure  */
    /* that Attributes is a valid pointer by setting it up to point   */
    /* to the default attributes.                                     */
    /******************************************************************/
    if ( Attributes == FNULL )
        Attributes = &prda_DefLinAts;

    Attrs = Attributes;

    CurrAttrs->ldef.defType = Attrs->ldef.defType;

    /******************************************************************/
    /* The loop is processed exactly twice.  Mask and Attrs are set   */
    /* to do the defaults in the first loop and then they are         */
    /* changed to do the supplied values in the second loop.          */
    /******************************************************************/
    for ( Mask = DefMask, Attrs = &prda_DefLinAts, i = 2;
          i--;
          Mask = AttrMask, Attrs = Attributes )
    {
        TRACE4(TFUNC, "Mask", &Mask , 1);

        if ( Mask & LBB_COLOR )
            CurrAttrs->lbnd.lColor = Attrs->lbnd.lColor;

        if ( Mask & LBB_MIX_MODE )
            CurrAttrs->lbnd.usMixMode = Attrs->lbnd.usMixMode;

        if ( Mask & LBB_WIDTH )
            CurrAttrs->lbnd.fxWidth = Attrs->lbnd.fxWidth;

        if ( Mask & LBB_GEOM_WIDTH )
            CurrAttrs->lbnd.lGeomWidth = Attrs->lbnd.lGeomWidth;

        if ( Mask & LBB_TYPE )
        {
            CurrAttrs->lbnd.usType = Attrs->lbnd.usType;

            DCIData->DCILineTypMask = 0x8000;
            DCIData->StyleNumber =
                    (ULONG)(0xFF00 | LineTypeTable[Attrs->lbnd.usType]);
        }

        if ( Mask & LBB_END )
            CurrAttrs->lbnd.usEnd = Attrs->lbnd.usEnd;

        if ( Mask & LBB_JOIN )
            CurrAttrs->lbnd.usJoin = Attrs->lbnd.usJoin;
    }

    return;
}
#undef TFUNC





/**********************************************************************/
/*                                                                    */
/*   FUNCTION: prda_SetMarkAttrs                                      */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*                                                                    */
/*   USHORT         DefMask;           Mask determines which values   */
/*                                     are to be set to default       */
/*   USHORT         AttrMask;          Mask determines which values   */
/*                                     are to be set from Attributes  */
/*   PDMARKERBUNDLE Attributes;        New attributes passed in       */
/*   PDMARKERBUNDLE CurrAttrs;         Current attributes to be set   */
/*                                     according to DefMask, AttrMask */
/*                                     and Attributes                 */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/*   This function is called from prda_DeviceSetAttributes to set the */
/*   marker attributes.  The attributes are set in two passes:  first */
/*   the default attributes requested in DefMask are copied into the  */
/*   CurrAttrs and then the values from Attributes requested          */
/*   in AttrMask are copied into CurrAttrs.  Note that this           */
/*   means that attributes selected in DefMask AND AttrMask will be   */
/*   set from Attributes and NOT from the default attributes.         */
/*                                                                    */
/**********************************************************************/
/*   CON3201  Convert to C/SET2                                       */
VOID prda_SetMarkAttrs ( USHORT         DefMask,
                         USHORT         AttrMask,
                         PDMARKERBUNDLE Attributes,
                         PDMARKERBUNDLE CurrAttrs )

{
#define TFUNC "prda_SetMarkAttrs"

    /******************************************************************/
    /* Local variables                                                */
    /******************************************************************/
    ULONG              Mask;           /* Mask determines which       */
                                       /* attributes to set           */
    PDMARKERBUNDLE     Attrs;          /* Pointer to supplied         */
                                       /* attributes                  */
    USHORT             i;              /* loop control variable       */


    /******************************************************************/
    /* The new set of current attributes are set up in two passes.    */
    /* The first pass sets any default values requested, the second   */
    /* sets any values supplied - this has the effect of setting the  */
    /* attributes to the supplied value when BOTH are requested.      */
    /******************************************************************/

    /******************************************************************/
    /* If a pointer to an attributes bundle has been passed then copy */
    /* the device bundle definition fields from this attributes       */
    /* bundle otherwise copy them from the default bundle and ensure  */
    /* that Attributes is a valid pointer by setting it up to point   */
    /* to the default attributes.                                     */
    /******************************************************************/
    if ( Attributes == FNULL )
        Attributes = &prda_DefMrkAts;

    Attrs = Attributes;

    CurrAttrs->mdef.defSet   = Attrs->mdef.defSet;
    CurrAttrs->mdef.fFlags   = Attrs->mdef.fFlags;
    CurrAttrs->mdef.CodePage = Attrs->mdef.CodePage;

    /******************************************************************/
    /* The loop is processed exactly twice.  Mask and Attrs are set   */
    /* to do the defaults in the first loop and then they are         */
    /* changed to do the supplied values in the second loop.          */
    /******************************************************************/
    for ( Mask = DefMask, Attrs = &prda_DefMrkAts, i = 2;
          i--;
          Mask = AttrMask, Attrs = Attributes )
    {
        TRACE4(TFUNC, "Mask", &Mask , 1);

        if ( Mask & MBB_COLOR )
            CurrAttrs->mbnd.lColor = Attrs->mbnd.lColor;

        if ( Mask & MBB_BACK_COLOR )
            CurrAttrs->mbnd.lBackColor = Attrs->mbnd.lBackColor;

        if ( Mask & MBB_MIX_MODE )
            CurrAttrs->mbnd.usMixMode = Attrs->mbnd.usMixMode;

        if ( Mask & MBB_BACK_MIX_MODE )
            CurrAttrs->mbnd.usBackMixMode = Attrs->mbnd.usBackMixMode;

        if ( Mask & MBB_SET )
            CurrAttrs->mbnd.usSet = Attrs->mbnd.usSet;

        if ( Mask & MBB_SYMBOL )
            CurrAttrs->mbnd.usSymbol = Attrs->mbnd.usSymbol;

        if ( Mask & MBB_BOX )
            CurrAttrs->mbnd.sizfxCell = Attrs->mbnd.sizfxCell;

    }

    /******************************************************************/
    /* If the symbol in the default set is MARKSYM_BLANK then change  */
    /* it to MARKSYM_SMALLCIRCLE + 1 so that the correct symbol is    */
    /* picked up (see PRDDATA.C where the default marker font is set  */
    /* up).  Then check if the symbol is within the correct range.    */
    /******************************************************************/
    if ( CurrAttrs->mdef.defSet == 0L )
    {
        if ( CurrAttrs->mbnd.usSymbol == (USHORT)MARKSYM_BLANK )
            CurrAttrs->mbnd.usSymbol = (USHORT)MARKSYM_SMALLCIRCLE + 1;

        if ( (CurrAttrs->mbnd.usSymbol < MARKSYM_DEFAULT) ||
             (CurrAttrs->mbnd.usSymbol > MARKSYM_SMALLCIRCLE + 1) )
            CurrAttrs->mbnd.usSymbol = MARKSYM_DEFAULT;
    }

    return;
}
#undef TFUNC





/**********************************************************************/
/*                                                                    */
/*   FUNCTION: prda_SetPtrnAttrs                                      */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*                                                                    */
/*   USHORT         DefMask;           Mask determines which values   */
/*                                     are to be set to default       */
/*   USHORT         AttrMask;          Mask determines which values   */
/*                                     are to be set from Attributes  */
/*   PDAREABUNDLE   Attributes;        New attributes passed in       */
/*   PDAREABUNDLE   CurrAttrs;         Current attributes to be set   */
/*                                     according to DefMask, AttrMask */
/*                                     and Attributes                 */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/*   This function is called from prda_DeviceSetAttributes to set the */
/*   pattern attributes.  The attributes are set in two passes: first */
/*   the default attributes requested in DefMask are copied into the  */
/*   CurrAttrs and then the values from Attributes requested          */
/*   in AttrMask are copied into CurrAttrs.  Note that this           */
/*   means that attributes selected in DefMask AND AttrMask will be   */
/*   set from Attributes and NOT from the default attributes.         */
/*                                                                    */
/**********************************************************************/
/*   CON3201  Convert to C/SET2                                       */
VOID prda_SetPtrnAttrs ( USHORT       DefMask,
                         USHORT       AttrMask,
                         PDAREABUNDLE Attributes,
                         PDAREABUNDLE CurrAttrs )

{
#define TFUNC "prda_SetPtrnAttrs"

    /******************************************************************/
    /* Local variables                                                */
    /******************************************************************/
    USHORT             Mask;           /* Mask determines which       */
                                       /* attributes to set           */
    PDAREABUNDLE       Attrs;          /* Pointer to supplied         */
                                       /* attributes                  */
    USHORT             i;              /* loop control variable       */



    /******************************************************************/
    /* The new set of current attributes are set up in two passes.    */
    /* The first pass sets any default values requested, the second   */
    /* sets any values supplied - this has the effect of setting the  */
    /* attributes to the supplied value when BOTH are requested.      */
    /******************************************************************/

    /******************************************************************/
    /* If a pointer to an attributes bundle has been passed then copy */
    /* the device bundle definition fields from this attributes       */
    /* bundle otherwise copy them from the default bundle and ensure  */
    /* that Attributes is a valid pointer by setting it up to point   */
    /* to the default attributes.                                     */
    /******************************************************************/
    if ( Attributes == FNULL )
        Attributes = &prda_DefPtnAts;

    Attrs = Attributes;

    CurrAttrs->adef.defSet   = Attrs->adef.defSet;
    CurrAttrs->adef.fFlags   = Attrs->adef.fFlags;
    CurrAttrs->adef.CodePage = Attrs->adef.CodePage;

    /******************************************************************/
    /* The loop is processed exactly twice.  Mask and Attrs are set   */
    /* to do the defaults in the first loop and then they are         */
    /* changed to do the supplied values in the second loop.          */
    /******************************************************************/
    for ( Mask = DefMask, Attrs = &prda_DefPtnAts, i = 2;
          i--;
          Mask = AttrMask, Attrs = Attributes )
    {
        TRACE4(TFUNC, "Mask", &Mask , 1);

        if ( Mask & ABB_COLOR )
            CurrAttrs->abnd.lColor = Attrs->abnd.lColor;

        if ( Mask & ABB_BACK_COLOR )
            CurrAttrs->abnd.lBackColor = Attrs->abnd.lBackColor;

        if ( Mask & ABB_MIX_MODE )
            CurrAttrs->abnd.usMixMode = Attrs->abnd.usMixMode;

        if ( Mask & ABB_BACK_MIX_MODE )
            CurrAttrs->abnd.usBackMixMode = Attrs->abnd.usBackMixMode;

        if ( Mask & ABB_SET )
            CurrAttrs->abnd.usSet = Attrs->abnd.usSet;

        if ( Mask & ABB_SYMBOL )
            CurrAttrs->abnd.usSymbol = Attrs->abnd.usSymbol;

        if ( Mask & ABB_REF_POINT )
        {
            CurrAttrs->abnd.ptlRefPoint.x = Attrs->abnd.ptlRefPoint.x;
            CurrAttrs->abnd.ptlRefPoint.y = Attrs->abnd.ptlRefPoint.y;
        }
    }

    return;
}
#undef TFUNC





/**********************************************************************/
/*                                                                    */
/*   FUNCTION: prda_SetImagAttrs                                      */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*                                                                    */
/*   USHORT         DefMask;           Mask determines which values   */
/*                                     are to be set to default       */
/*   USHORT         AttrMask;          Mask determines which values   */
/*                                     are to be set from Attributes  */
/*   PDIMAGEBUNDLE  Attributes;        New attributes passed in       */
/*   PDIMAGEBUNDLE  CurrAttrs;         Current attributes to be set   */
/*                                     according to DefMask, AttrMask */
/*                                     and Attributes                 */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/*   This function is called from prda_DeviceSetAttributes to set the */
/*   image attributes.  The attributes are set in two passes:  first  */
/*   the default attributes requested in DefMask are copied into the  */
/*   CurrAttrs and then the values from Attributes requested          */
/*   in AttrMask are copied into CurrAttrs.  Note that this           */
/*   means that attributes selected in DefMask AND AttrMask will be   */
/*   set from Attributes and NOT from the default attributes.         */
/*                                                                    */
/**********************************************************************/
/*   CON3201  Convert to C/SET2                                       */
VOID prda_SetImagAttrs ( USHORT        DefMask,
                         USHORT        AttrMask,
                         PDIMAGEBUNDLE Attributes,
                         PDIMAGEBUNDLE CurrAttrs )

{
#define TFUNC "prda_SetImagAttrs"

    /******************************************************************/
    /* Local variables                                                */
    /******************************************************************/
    USHORT             Mask;           /* Mask determines which       */
                                       /* attributes to set           */
    PDIMAGEBUNDLE      Attrs;          /* Pointer to supplied         */
                                       /* attributes                  */
    USHORT             i;              /* loop control variable       */


    /******************************************************************/
    /* The new set of current attributes are set up in two passes.    */
    /* The first pass sets any default values requested, the second   */
    /* sets any values supplied - this has the effect of setting the  */
    /* attributes to the supplied value when BOTH are requested.      */
    /******************************************************************/

    /******************************************************************/
    /* The loop is processed exactly twice.  Mask and Attrs are set   */
    /* to do the defaults in the first loop and then they are         */
    /* changed to do the supplied values in the second loop.          */
    /******************************************************************/
    for ( Mask = DefMask, Attrs = &prda_DefImgAts, i = 2;
          i--;
          Mask = AttrMask, Attrs = Attributes )
    {
        TRACE4(TFUNC, "Mask", &Mask , 1);

        if ( Mask & IBB_COLOR )
            CurrAttrs->ibnd.lColor = Attrs->ibnd.lColor;

        if ( Mask & IBB_BACK_COLOR )
            CurrAttrs->ibnd.lBackColor = Attrs->ibnd.lBackColor;

        if ( Mask & IBB_MIX_MODE )
            CurrAttrs->ibnd.usMixMode = Attrs->ibnd.usMixMode;

        if ( Mask & IBB_BACK_MIX_MODE )
            CurrAttrs->ibnd.usBackMixMode = Attrs->ibnd.usBackMixMode;
    }

    return;

}
#undef TFUNC






/**********************************************************************/
/*                                                                    */
/*   FUNCTION: prda_CheckFontValid                                    */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*                                                                    */
/*   PCHARDEFS      pCharDefs;                                        */
/*   lpDCI          DCIData;                                          */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/*   This function checks that the font "described" in the given      */
/*   char def structure is valid for this DC.                         */
/*                                                                    */
/**********************************************************************/
/*   CON3201  Convert to C/SET2                                       */
BOOL prda_CheckFontValid ( PCHARDEFS pCharDefs,
                           lpDCI     DCIData )

{
#define TFUNC "prda_ChkFontVld"

    /******************************************************************/
    /* Local variables                                                */
    /******************************************************************/
    lpPDBI             PDBInst;      /* Pointer to PDB Instance data  */
    LONG               Font;
    USHORT             RetVal;


    PDBInst = DCIData->DCIPdbInstance;
    Font = (LONG)pCharDefs->defSet;


    if ( !(pCharDefs->fFlags & CDEF_GENERIC) )
    {
        /**********************************************************/
        /* Device font - default marker font OK, other positive   */
        /* values are invalid, if negative check in range.        */
        /**********************************************************/
        if ( Font > 0L )
        {
            if ( Font == DFLT_MARKER_FONT )
                RetVal = TRUE;
            else
                RetVal = FALSE;
        }
        else    /* Font <= 0 */
        {
            if ( PDBInst->FontCount == 0 )
            {
                /**************************************************/
                /* No device fonts in this DC - could be memory   */
                /* DC or device fonts not available selected from */
                /* printer properties dialog box or landscape     */
                /* mode or ....                                   */
                /**************************************************/
                RetVal = FALSE;
            }
            else
            {
                /******************************************************/
                /* Here Font must be either zero, or a valid negative */
                /* match number. No longer have a simple test for     */
                /* the -ve case, so simply return OK - LocateFont     */
                /* will catch the invalid case.                       */
                /******************************************************/

                RetVal = TRUE;

            }
        }
    }
    else
    {
        /**********************************************************/
        /* Engine font - just check pointer is not null.          */
        /**********************************************************/
        if ( Font )
            RetVal = TRUE;
        else
            RetVal = FALSE;
    }

    return (RetVal);
}
#undef TFUNC






/**********************************************************************/
/*                                                                    */
/*   FUNCTION: prda_SetTextSimlFlag                                   */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*                                                                    */
/*   lpDCI          DCIData;                                          */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/*   This function is called from prda_SetTextAttrs to set the flags  */
/*   in DCIData which controls whether or not we attempt to return    */
/*   text calls to the engine for simulation.                         */
/*                                                                    */
/* Two flags are set up: TEXT_SIML_REQD  - on if                      */
/*                                                                    */
/*      - mode 2 or mode 3 engine text                                */
/*      - mode 3 non-outline device text                              */
/*      - mode 2 or outline device text with non-default              */
/*        char angle, shear or direction                              */
/*      - mode 1 text with non-default direction                      */
/*                                                                    */
/* and ENG_ATTS_REQD - on if bold, strikeout, italic or underscore    */
/* font requested.                                                    */
/*                                                                    */
/* ENG_ATTS_REQD is only used by CharStringPos: the query functions   */
/* are not affected by these attributes (except possibly BOLD?)       */
/*                                                                    */
/* TEXT_SIML_REQD is used by CharStringPos, QueryCharPositions,       */
/* QueryTextBox - if set, return to simulation.                       */
/* The Query functions also return engine fonts for simulation:       */
/* CharStringPos handles CM_MODE1 engine text, but query funcs don't. */
/* Also: QueryTextBox does NOT return CM_MODE2 image fonts with       */
/* non-default char angle/shear; this is an invalid call, so we       */
/* can return the untransformed values. (?).                          */
/*                                                                    */
/* Note Kerning is explicitly checked in each query function: could   */
/* move that into here? (If QTextBox does not do the extra checking). */
/**********************************************************************/
/*   CON3201  Convert to C/SET2                                       */
VOID prda_SetTextSimlFlag ( lpDCI DCIData )

{
#define TFUNC "prda_SetTxtSmlF"

    /******************************************************************/
    /* Local variables                                                */
    /******************************************************************/
    PDCHARBUNDLE     CurTxtAts;
    BOOL             bSimlReqd;
    BOOL             AngleShear;
    lpFontDataType   pFontData;


    /******************************************************************/
    /* Set up pointers.                                               */
    /******************************************************************/
    pFontData = &DCIData->DCIFontData;
    CurTxtAts = DCIData->DCICurTxtAts;

    /******************************************************************/
    /* Assume we don't need engine simulation unless proved otherwise.*/
    /******************************************************************/
    bSimlReqd = FALSE;

    /******************************************************************/
    /* Is there a char angle or shear?                                */
    /* Note: May later include -ve CharBox values here.               */
    /******************************************************************/
    AngleShear = ( (CurTxtAts->cbnd.ptlAngle.y != 0L) );

    /******************************************************************/
    /* AK - adding shear to driver 5/07/91.                           */
    /* Do not need to simulate shear attribute.                       */
    /*           ||(CurTxtAts->cbnd.ptlShear.x != 0L) );              */
    /******************************************************************/
    /******************************************************************/
    /* Set up the ENG_ATTS_REQD flag.                                 */
    /* PD00060 : Use the ENG_ATTS_REQD flag for system fonts - need   */
    /* to return these for simulation in CharStringPos.               */
    /******************************************************************/
    if ( CurTxtAts->cdef.fFlags &
         (CDEF_BOLD | CDEF_STRIKEOUT | CDEF_ITALIC | CDEF_UNDERSCORE) )
    {
        DCIData->DCIStateFlags |= ENG_ATTS_REQD;
    }
    else
    {
        DCIData->DCIStateFlags &= ~ENG_ATTS_REQD;
    }

    /******************************************************************/
    /* Set up the TEXT_SIML_REQD flag.                                */
    /******************************************************************/
    if ( CurTxtAts->cbnd.usDirection != CHDIRN_LEFTRIGHT )
    {
        /**************************************************************/
        /* Driver only handles left-to-right text.                    */
        /**************************************************************/
        bSimlReqd = TRUE;
    }
    else if ( AngleShear)
    {
        /**************************************************************/
        /* can never handle this - unless these attributes are        */
        /* ignored - i.e. Mode 1 and not outline.                     */
        /**************************************************************/
        if ( (CurTxtAts->cbnd.usPrecision != CM_MODE1) ||
             (pFontData->pMetrics->fsDefn & FM_DEFN_OUTLINE)  )
        {
            bSimlReqd = TRUE;
        }
    }
    else if ( (pFontData->Genre != DEVICE_FONT) &&
              ( (CurTxtAts->cbnd.usPrecision != CM_MODE1) ||
                (pFontData->pMetrics->fsDefn & FM_DEFN_OUTLINE) ) )

    {
        /**************************************************************/
        /* Can only handle mode 1 non-outline engine fonts.           */
        /* Return Mode2, Mode3 and outline to simulation.             */
        /**************************************************************/
        bSimlReqd = TRUE;
    }
    else if ( (pFontData->Genre == DEVICE_FONT) &&
              (CurTxtAts->cbnd.usPrecision == CM_MODE3) &&
              !(pFontData->pMetrics->fsDefn & FM_DEFN_OUTLINE)  )
    {
        /**************************************************************/
        /* Mode 3 device (not outline) text - simulate it.            */
        /**************************************************************/
        bSimlReqd = TRUE;
    }
    else if ((CurTxtAts->cbnd.fxExtra != 0) ||
             (CurTxtAts->cbnd.fxBreakExtra != 0) ||
             (CurTxtAts->cbnd.usTextAlign != (TA_NORMAL_HORIZ |
                                              TA_NORMAL_VERT)))
    {
        /**********************************************************************/
        /*  C/Set2 Conversion - Currently the engine by default will take     */
        /*  care of fxExtra and fxBreakExtra for 16-bit drivers.  We will     */
        /*  add the two conditions in the if statement so that the            */
        /*  engine will go ahead and do the simulation for us (ie figure      */
        /*  the character spacing for us). Also had to add similar conditions */
        /*  in prdt_CharStringPos.  Jim Russell                               */
        /*  This is also true for usTextAlign                                 */
        /**********************************************************************/
        bSimlReqd = TRUE;
    }

    if ( bSimlReqd )
        DCIData->DCIStateFlags |= TEXT_SIML_REQD;
    else
        DCIData->DCIStateFlags &= ~TEXT_SIML_REQD;

    return;

}
#undef TFUNC



/**********************************************************************/
/*                                                                    */
/*   FUNCTION: prda_GetDfltCharBox                                    */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*                                                                    */
/*   lpDCI          DCIData;                                          */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/*   This function is called from prda_SetTextAttrs to set up the     */
/*   default character box dimensions - these are fixed at 1/6" by    */
/*   1/6".                                                            */
/*                                                                    */
/*   Dimension takes value WIDTH or HEIGHT.                           */
/*   Units takes value WORLD_COORDS or DEVICE_COORDS.                 */
/*                                                                    */
/*   The function returns either the width or the height of the       */
/*   CharBox, in either World or DeviceCoords. If the values are      */
/*   requested in WorldCoords, they are returned as FIXED values.     */
/*                                                                    */
/*   This routine is called from SetTextAttrs and from DevQueryCaps.  */
/**********************************************************************/
/*   CON3201  Convert to C/SET2                                       */
ULONG prda_GetDfltCharBox ( HDC    DcH,
                            USHORT Dimension,
                            USHORT Units,
                            lpDCI  DCIData )

{
#define TFUNC "prda_GtDfltChBx"

    /******************************************************************/
    /* Local variables                                                */
    /******************************************************************/
    USHORT             fsXform;
    XFORM              xfm;
    POINTL             StepSize;

    /******************************************************************/
    /* Get local copy of device resolution.                           */
    /******************************************************************/
    StepSize.x = (LONG)
             DCIData->DCIPdbInstance->DDT.DDTRasterMode->ResWidth;
    StepSize.y = (LONG)
             DCIData->DCIPdbInstance->DDT.DDTRasterMode->ResDepth;

    /******************************************************************/
    /* If this was called from DevQueryCaps (units = DEVICE_COORDS)   */
    /* then FontData might not have been set up. In this case return  */
    /* 1/6" in device coords, taken from DDTRasterMode.               */
    /* NB 75/6 = 12. All other resolutions divide exactly by 6.       */
    /******************************************************************/
    if (Units == DEVICE_COORDS)
    {
        if (Dimension == WIDTH)
            /******************************************************************/
            /* PD00593 Round char box size returned                           */
            /******************************************************************/
/*          return( StepSize.x / 6 );  */
            return( prdg_ScaleValue( StepSize.x, 1L, 6L) );
        else
            /******************************************************************/
            /* PD00593 Round char box size returned                           */
            /******************************************************************/
/*          return( StepSize.y / 6 );  */
            return( prdg_ScaleValue( StepSize.y, 1L, 6L) );
    }

    /******************************************************************/
    /* Otherwise this was called from GetTextAttrs and world coords   */
    /* with FIXED type are wanted.                                    */
    /*                                                                */
    /* Start with DeviceCoords and FIXED. Get the vector we want to   */
    /* convert.                                                       */
    /******************************************************************/
    if (Dimension == WIDTH)
    {
        StepSize.x = (LONG)MAKEFIXED(StepSize.x, 0);
        StepSize.y = 0;
    }
    else
    {
        StepSize.x = 0;
        StepSize.y = (LONG)MAKEFIXED(StepSize.y, 0);
    }

    /******************************************************************/
    /* NB no rounding problem - as in FIXED units.                    */
    /******************************************************************/
/*  StepSize.x /= 6;  */
/*  StepSize.y /= 6;  */
    /**************************************************************************/
    /* PD00593 : Round stepsize                                               */
    /**************************************************************************/
    StepSize.x = prdg_ScaleValue(StepSize.x, 1L, 6L);
    StepSize.y = prdg_ScaleValue(StepSize.y, 1L, 6L);


    /******************************************************************/
    /* Get Device->World transform matrix.                            */
    /******************************************************************/
    fsXform = DEVICE_TO_WORLD | IGNORE_ORIGIN_SHIFT;

    if ( prdg_GetXformMatrix( DcH,
                              fsXform,
                              (PXFORM)&xfm,
                              DCIData ) != OK )
        return (ERROR_ZERO);

    /******************************************************************/
    /* Use prdg_XformPoint to convert this vector to a length in      */
    /* world coords, and return this.                                 */
    /******************************************************************/
    return ( prdg_XformPoint( DcH, (PPOINTL)&StepSize, (PXFORM)&xfm ) );
}
#undef TFUNC

