/*DDK*************************************************************************/
/*                                                                           */
/* COPYRIGHT (C) Microsoft 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.                                */
/*                                                                           */
/*****************************************************************************/
#pragma  pagesize(55)

/**************************************************************************
 *
 * SOURCE FILE NAME = ATTRIBS.C
 *
 * DESCRIPTIVE NAME = PLOTTER DRIVER ATTRIBUTES
 *
 *
 *
 * VERSION =   V2.0
 *
 * DATE        09/18/88
 *
 * DESCRIPTION PLOTTER DRIVER SOURCE
 *
 *
 * FUNCTIONS   get_area_attr_bundle()        Return current area attribute
 *             get_char_attr_bundle()        Return char attribute
 *             get_image_attr_bundle()       Get image attributes
 *             get_line_attr_bundle()        Get line attributes
 *             get_marker_attr_bundle()      Get marker attributes
 *             set_area_attr_bundle()        Set area attributes
 *             set_char_attr_bundle()        Set char attributes
 *             set_image_attr_bundle()       Set image attributes
 *             set_line_attr_bundle()        Set line attributes
 *             set_marker_attr_bundle()      Set marker attributes
 *             validate_any_color()          Validate color
 *             validate_background_color()   Validate background color
 *             validate_foreground_color()   Validate foreground color
 *             validate_background_mix()     Validate background mix
 *             validate_foreground_mix()     Validate foreground mix
 *             iniitialize_ddc()             Initialize Device driver instance
 *             DeviceGetAttributes()         Get plotter driver attributes
 *             DeviceSetAttributes()         Set plotter driver attributes
 *             DeviceSetDCOrigin()           Set DC Origin
 *             DeviceSetGlobalAttribute()    Set global attributes
 *             ErasePS()                     This function resets the
 *                                           presentation space.
 *             GetDCOrigin()                 Get Device Context origin
 *             GetStyleRatio()               Get Style Ratio
 *             LockDevice()                  This function locks a device
 *             SetStyleRatio()               Set Style Ratio
 *             UnlockDevice()                Allows all pending screen input or
 *                                           output operations
 *
 *
 * NOTES
 *
 *
 * STRUCTURES
 *
 * EXTERNAL REFERENCES
 *
 * EXTERNAL FUNCTIONS
 *
*/

#define  INCL_ERRORS
#include "plotters.h"
#include "attribs.h"
#include "bounds.h"
#include "color.h"
#include "error.h"
#include "font.h"
#include "utils.h"
#include "xforms.h"
#include "dispatch.h"

/*
** LOCAL FUNCTION PROTOTYPES
*/

LOCAL ULONG get_area_attr_bundle(PDDC,ULONG,PDAREABUNDLE);

LOCAL ULONG get_char_attr_bundle(PDDC,ULONG,PDCHARBUNDLE);
LOCAL ULONG get_image_attr_bundle(PDDC,ULONG,PDIMAGEBUNDLE);
LOCAL ULONG get_line_attr_bundle(HDC,PDDC,ULONG,PDLINEBUNDLE,ULONG);
LOCAL ULONG get_marker_attr_bundle(PDDC,ULONG,PDMARKERBUNDLE);
LOCAL BOOL  set_area_attr_bundle(PDDC,ULONG,ULONG,PDAREABUNDLE);
LOCAL BOOL  set_char_attr_bundle(PDDC,ULONG,ULONG,PDCHARBUNDLE);
LOCAL BOOL  set_image_attr_bundle(PDDC,ULONG,ULONG,PDIMAGEBUNDLE);
LOCAL BOOL  set_line_attr_bundle(HDC,PDDC,ULONG,ULONG,PDLINEBUNDLE,
                                             ULONG);

LOCAL BOOL  set_marker_attr_bundle(PDDC,ULONG,ULONG,PDMARKERBUNDLE);
LOCAL BOOL  validate_any_color(PDDC,LONG);
LOCAL BOOL  validate_background_color(PDDC,LONG);
LOCAL BOOL  validate_foreground_color(PDDC,LONG);
LOCAL BOOL  validate_background_mix(USHORT);
LOCAL BOOL  validate_foreground_mix(USHORT);

/*
** LOCAL MACROS
*/
#define TA_GOOD_HORIZ TA_NORMAL_HORIZ|TA_LEFT|TA_CENTER|TA_RIGHT|TA_STANDARD_HORIZ
#define TA_GOOD_VERT  TA_NORMAL_VERT|TA_TOP|TA_HALF|TA_BASE|TA_BOTTOM|TA_STANDARD_VERT
#define MAX_MARKER_SYMBOL 255
#pragma page()

/*
**  LOCAL FUNCTIONS
*/
/***********************************************************************
 *
 * FUNCTION NAME = GET_AREA_ATTR_BUNDLE()
 *
 * DESCRIPTION   = Return current area attribute
 *
 *                 return information from the current area attribute bundle
 *                 according to the "AttrsMask" parameter.
 *
 *
 * INPUT         = pDDC,AttrsMask,pAttrs
 *
 * OUTPUT        = NONE
 *
 *
 *
 *
 * RETURN-NORMAL = ANY ONE OF THE FOLLOWING
 *                 0L, ABB_COLOR, ABB_BACK_COLOR, ABB_MIX_MODE
 *                 ABB_BACK_MIX_MODE, ABB_REF_POINT
 *
 * RETURN-ERROR  =
 *
 ****************************************************************************/

LOCAL ULONG  get_area_attr_bundle(PDDC pDDC,ULONG AttrsMask,
                                  PDAREABUNDLE pAttrs)
{
  ULONG ulProcessed = 0L;

  /*
  ** pattern -- foreground
  */
  if (AttrsMask & ABB_COLOR)
  {
    pAttrs->abnd.lColor = pDDC->DCState.abnd.lColor;
    ulProcessed |= ABB_COLOR;
  }

  /*
  ** pattern -- background
  */
  if (AttrsMask & ABB_BACK_COLOR)
  {
    pAttrs->abnd.lBackColor = pDDC->DCState.abnd.lBackColor;
    ulProcessed |= ABB_BACK_COLOR;
  }

  /*
  ** pattern foreground mix mode
  */
  if (AttrsMask & ABB_MIX_MODE)
  {
    pAttrs->abnd.usMixMode = pDDC->DCState.abnd.usMixMode;
    ulProcessed |= ABB_MIX_MODE;
  }

  /*
  ** pattern -- background mix mode
  */
  if (AttrsMask & ABB_BACK_MIX_MODE)
  {
    pAttrs->abnd.usBackMixMode = pDDC->DCState.abnd.usBackMixMode;
    ulProcessed |= ABB_BACK_MIX_MODE;
  }

  /*
  ** pattern -- set, ie font id
  */
  if (AttrsMask & ABB_SET)
  {
    pAttrs->abnd.usSet = pDDC->DCState.abnd.usSet;
    ulProcessed |= ABB_SET;
  }
#pragma  page()

  /*
  ** pattern -- symbol
  */
  if (AttrsMask & ABB_SYMBOL)
  {
    pAttrs->abnd.usSymbol = pDDC->DCState.abnd.usSymbol;
    ulProcessed |= ABB_SYMBOL;
  }

  /*
  ** pattern -- reference point
  */
  if (AttrsMask & ABB_REF_POINT)
  {
    pAttrs->abnd.ptlRefPoint = pDDC->DCState.abnd.ptlRefPoint;
    ulProcessed |= ABB_REF_POINT;
  }
  return (ulProcessed);
}

#pragma  page()

/***********************************************************************
 *
 * FUNCTION NAME = GET_CHAR_ATTR_BUNDLE()
 *
 * DESCRIPTION   = Return char attribute
 *
 *                 return information from the current character
 *                 attribute bundle according to the "AttrsMask"
 *                 parameter.
 *
 * INPUT         = pDDC,AttrsMask,pAttrs
 *
 * OUTPUT        = NONE
 *
 *
 *
 *
 * RETURN-NORMAL = ANY ONE OF THE FOLLOWING
 *                  0L, CBB_COLOR, CBB_BACK_COLOR, CBB_MIX_MODE,
 *                  CBB_BACK_MIX_MODE, CBB_SET,CBB_MODE, CBB_BOX, CBB_ANGLE
 *                  CBB_SHEAR, CBB_DIRECTION
 * RETURN-ERROR  = NONE
 *
 *
 *
 ****************************************************************************/

LOCAL ULONG  get_char_attr_bundle(PDDC pDDC,ULONG AttrsMask,
                                              PDCHARBUNDLE pAttrs)
{
  ULONG ulProcessed = 0L;

  /*
  ** character foreground attribute
  */
  if (AttrsMask & CBB_COLOR)
  {
    pAttrs->cbnd.lColor = pDDC->DCState.dcbnd.cbnd.lColor;
    ulProcessed |= CBB_COLOR;
  }

  /*
  ** character background attribute
  */
  if (AttrsMask & CBB_BACK_COLOR)
  {
    pAttrs->cbnd.lBackColor = pDDC->DCState.dcbnd.cbnd.lBackColor;
    ulProcessed |= CBB_BACK_COLOR;
  }

  /*
  ** character foreground mix mode
  */
  if (AttrsMask & CBB_MIX_MODE)
  {
    pAttrs->cbnd.usMixMode = pDDC->DCState.dcbnd.cbnd.usMixMode;
    ulProcessed |= CBB_MIX_MODE;
  }

  /*
  ** character background mix mode
  */
  if (AttrsMask & CBB_BACK_MIX_MODE)
  {
    pAttrs->cbnd.usBackMixMode = pDDC->DCState.dcbnd.cbnd.usBackMixMode;
    ulProcessed |= CBB_BACK_MIX_MODE;
  }
#pragma  page()

  /*
  ** character set, ie, font id
  */
  if (AttrsMask & CBB_SET)
  {
    pAttrs->cbnd.usSet = pDDC->DCState.dcbnd.cbnd.usSet;
    ulProcessed |= CBB_SET;
  }

  /*
  ** character mode, ie, rendering precision
  */
  if (AttrsMask & CBB_MODE)
  {
    pAttrs->cbnd.usPrecision = pDDC->DCState.dcbnd.cbnd.usPrecision;
    ulProcessed |= CBB_MODE;
  }

  /*
  ** character cell size
  */
  if (AttrsMask & CBB_BOX)
  {
    pAttrs->cbnd.sizfxCell = pDDC->DCState.dcbnd.cbnd.sizfxCell;
    ulProcessed |= CBB_BOX;
  }

  /*
  ** character angle
  */
  if (AttrsMask & CBB_ANGLE)
  {
    pAttrs->cbnd.ptlAngle = pDDC->DCState.dcbnd.cbnd.ptlAngle;
    ulProcessed |= CBB_ANGLE;
  }

  /*
  ** character shear
  */
  if (AttrsMask & CBB_SHEAR)
  {
    pAttrs->cbnd.ptlShear = pDDC->DCState.dcbnd.cbnd.ptlShear;
    ulProcessed |= CBB_SHEAR;
  }

  /*
  ** character direction
  */
  if (AttrsMask & CBB_DIRECTION)
  {
    pAttrs->cbnd.usDirection = pDDC->DCState.dcbnd.cbnd.usDirection;
    ulProcessed |= CBB_DIRECTION;
  }
  /*
  ** C/Set2 Conversion: New members added to the CHARBUNDLE structure
  */
  /*
  ** Alignment on page
  */
  if (AttrsMask & CBB_TEXT_ALIGN)
  {
    pAttrs->cbnd.usTextAlign = pDDC->DCState.dcbnd.cbnd.usTextAlign;
    ulProcessed |= CBB_TEXT_ALIGN;
  }
  /*
  ** Width added to character
  */
   if (AttrsMask & CBB_EXTRA)
  {
    pAttrs->cbnd.fxExtra = pDDC->DCState.dcbnd.cbnd.fxExtra;
    ulProcessed |= CBB_EXTRA;
  }
  /*
  ** Width added to break character
  */
   if (AttrsMask & CBB_BREAK_EXTRA)
  {
    pAttrs->cbnd.fxBreakExtra = pDDC->DCState.dcbnd.cbnd.fxBreakExtra;
    ulProcessed |= CBB_BREAK_EXTRA;
  }
  return (ulProcessed);
}

#pragma  page()

/***********************************************************************
 *
 * FUNCTION NAME = get_image_attr_bundle()
 *
 * DESCRIPTION   = Get image attributes
 *
 *                 return information from the current image attribute bundle
 *                 according to the "AttrsMask" parameter.
 *
 *
 *
 * INPUT         = pDDC,AttrsMask,pAttrs
 *
 * OUTPUT        = NONE
 *
 *
 *
 * RETURN-NORMAL = ANY ONE OF THE FOLLOWING
 *                 0L, IBB_COLOR, IBB_BACK_COLOR, IBB_MIX_MODE,
 *                 IBB_BACK_MIX_MODE
 *
 *
 * RETURN-ERROR  = NONE
 *
 *
 *
 *
 *
 ****************************************************************************/

LOCAL ULONG  get_image_attr_bundle(PDDC pDDC,ULONG AttrsMask,
                                               PDIMAGEBUNDLE pAttrs)
{
  ULONG ulProcessed = 0L;

  /*
  ** image foreground color
  */
  if (AttrsMask & IBB_COLOR)
  {
    pAttrs->ibnd.lColor = pDDC->DCState.ibnd.lColor;
    ulProcessed |= IBB_COLOR;
  }

  /*
  ** image background color
  */
  if (AttrsMask & IBB_BACK_COLOR)
  {
    pAttrs->ibnd.lBackColor = pDDC->DCState.ibnd.lBackColor;
    ulProcessed |= IBB_BACK_COLOR;
  }

  /*
  ** image foreground mix mode
  */
  if (AttrsMask & IBB_MIX_MODE)
  {
    pAttrs->ibnd.usMixMode = pDDC->DCState.ibnd.usMixMode;
    ulProcessed |= IBB_MIX_MODE;
  }

  /*
  ** image background mix mode
  */
  if (AttrsMask & IBB_BACK_MIX_MODE)
  {
    pAttrs->ibnd.usBackMixMode = pDDC->DCState.ibnd.usBackMixMode;
    ulProcessed |= IBB_BACK_MIX_MODE;
  }
  return (ulProcessed);
}

#pragma  page()

/***********************************************************************
 *
 * FUNCTION NAME =  get_line_attr_bundle()
 *
 * DESCRIPTION   = Get line attributes
 *
 *                 return information from the current line attribute bundle
 *                 according to the "AttrsMask" parameter.
 *
 *
 *
 * INPUT         =  pDDC,AttrsMask,pAttrs
 *
 * OUTPUT        =  NONE
 *
 *
 *
 *
 * RETURN-NORMAL =  ANY ONE OF THE FOLLOWING
 *                  0L, LBB_COLOR, LBB_MIX_MODE, LBB_WIDTH,
 *                  LBB_GEOM_WIDTH, LBB_TYPE, LBB_END, LBB_JOIN
 *
 * RETURN-ERROR  =  NONE
 *
 *
 *
 ****************************************************************************/

LOCAL ULONG  get_line_attr_bundle(HDC hDC,PDDC pDDC,ULONG AttrsMask
                                              ,PDLINEBUNDLE pAttrs,ULONG FunN)
{
  ULONG ulProcessed = 0L;

  /*
  ** line foreground attribute
  */
  if (AttrsMask & LBB_COLOR)
  {
    pAttrs->lbnd.lColor = pDDC->DCState.lbnd.lColor;
    ulProcessed |= LBB_COLOR;
  }

  /*
  ** line foreground mix mode attribute
  */
  if (AttrsMask & LBB_MIX_MODE)
  {
    pAttrs->lbnd.usMixMode = pDDC->DCState.lbnd.usMixMode;
    ulProcessed |= LBB_MIX_MODE;
  }

 /*
  ** line width attribute
  */
  if (AttrsMask & LBB_WIDTH)
  {
    pAttrs->lbnd.fxWidth = pDDC->DCState.lbnd.fxWidth;
    ulProcessed |= LBB_WIDTH;
  }

  /*
  ** geometric line width attribute
  */
  if (AttrsMask & LBB_GEOM_WIDTH)
  {
    /*
    ** if geometric line width is in world coordinates
    ** convert it to device for internal use.
    */
    //if (FunN & COM_TRANSFORM)
    if (TRUE)/* 1.3 engine is not setting the COM_TRANSFORM bit on this call */
    {

      /*
      ** Geometric width was stored in device units.
      ** Calculate the geometric width in World units.
      */

      POINTL aptlPoints[2];

      aptlPoints[0].x = 0;
      aptlPoints[0].y = 0;
      aptlPoints[1].x = pDDC->DCState.lbnd.lGeomWidth;
      aptlPoints[1].y = 0;
      convert_device_to_world(hDC, aptlPoints, 2L, pDDC);

      /*
      ** calc vector length of geometric width in World units
      */
      pAttrs->lbnd.lGeomWidth = (aptlPoints[1].x - aptlPoints[0].x) +
                                (aptlPoints[1].y - aptlPoints[0].y);
    }
    else
    {
      pAttrs->lbnd.lGeomWidth = pDDC->DCState.lbnd.lGeomWidth;
    }
    ulProcessed |= LBB_GEOM_WIDTH;
  }
#pragma  page()

  /*
  ** line type attribute
  */
  if (AttrsMask & LBB_TYPE)
  {
    pAttrs->lbnd.usType = pDDC->DCState.lbnd.usType;
    ulProcessed |= LBB_TYPE;
  }

  /*
  ** line end attribute
  */
  if (AttrsMask & LBB_END)
  {
    pAttrs->lbnd.usEnd = pDDC->DCState.lbnd.usEnd;
    ulProcessed |= LBB_END;
  }

  /*
  ** line join attribute
  */
  if (AttrsMask & LBB_JOIN)
  {
    pAttrs->lbnd.usJoin = pDDC->DCState.lbnd.usJoin;
    ulProcessed |= LBB_JOIN;
  }
  /*
  ** C/Set2 Conversion: New members added to the LINEBUNDLE structure
  */
  /*
  **  Line Background color
  */
  if (AttrsMask & LBB_BACK_COLOR)
  {
    pAttrs->lbnd.usJoin = pDDC->DCState.lbnd.lBackColor;
    ulProcessed |= LBB_BACK_COLOR;
  }
  /*
  ** Line Background mix mode
  */
  if (AttrsMask & LBB_BACK_MIX_MODE)
  {
    pAttrs->lbnd.usJoin = pDDC->DCState.lbnd.usBackMixMode;
    ulProcessed |= LBB_BACK_MIX_MODE;
  }
  return (ulProcessed);
}

#pragma  page()

/***********************************************************************
 *
 * FUNCTION NAME = get_marker_attr_bundle()
 *
 * DESCRIPTION   = Get marker attributes
 *
 *                 return information from the current marker attribute bundle
 *                 according to the "AttrsMask" parameter.
 *
 *
 * INPUT         = pDDC,AttrsMask,pAttrs
 *
 * OUTPUT        = NONE
 *
 *
 *
 *
 * RETURN-NORMAL = ANY ONE OF THE FOLLOWING
 *                 0L, MBB_COLOR, MBB_BACK_COLOR,MBB_MIX_MODE
 *                 MBB_BACK_MIX_MODE, MBB_SET, MBB_SYMBOL, MBB_BOX
 *
 *
 * RETURN-ERROR  = NONE
 *
 *
 ****************************************************************************/

LOCAL ULONG  get_marker_attr_bundle(PDDC pDDC,ULONG AttrsMask,
                                                PDMARKERBUNDLE pAttrs)
{
  ULONG ulProcessed = 0L;

  /*
  ** foreground color attribute
  */
  if (AttrsMask & MBB_COLOR)
  {
    pAttrs->mbnd.lColor = pDDC->DCState.mbnd.lColor;
    ulProcessed |= MBB_COLOR;
  }

  /*
  ** background color attribute
  */
  if (AttrsMask & MBB_BACK_COLOR)
  {
    pAttrs->mbnd.lBackColor = pDDC->DCState.mbnd.lBackColor;
    ulProcessed |= MBB_BACK_COLOR;
  }

  /*
  ** foreground mix mode attribute
  */
  if (AttrsMask & MBB_MIX_MODE)
  {
    pAttrs->mbnd.usMixMode = pDDC->DCState.mbnd.usMixMode;
    ulProcessed |= MBB_MIX_MODE;
  }

  /*
  ** background mix mode attribute
  */
  if (AttrsMask & MBB_BACK_MIX_MODE)
  {
    pAttrs->mbnd.usBackMixMode = pDDC->DCState.mbnd.usBackMixMode;
    ulProcessed |= MBB_BACK_MIX_MODE;
  }
#pragma  page()

  /*
  ** set attribute, ie, font id
  */
  if (AttrsMask & MBB_SET)
  {
    pAttrs->mbnd.usSet = pDDC->DCState.mbnd.usSet;
    ulProcessed |= MBB_SET;
  }

  /*
  ** symbol attribute
  */
  if (AttrsMask & MBB_SYMBOL)
  {
    pAttrs->mbnd.usSymbol = pDDC->DCState.mbnd.usSymbol;
    ulProcessed |= MBB_SYMBOL;
  }

  /*
  ** marker box size attribute
  */
  if (AttrsMask & MBB_BOX)
  {
    pAttrs->mbnd.sizfxCell = pDDC->DCState.mbnd.sizfxCell;
    ulProcessed |= MBB_BOX;
  }
  return (ulProcessed);
}

#pragma  page()

/***********************************************************************
 *
 * FUNCTION NAME = set_area_attr_bundle()
 *
 * DESCRIPTION   = Set area attributes
 *
 *
 * INPUT         = pDDC,DefsMask,AttrsMask,pAttrs
 *
 * OUTPUT        = NONE
 *
 *
 *
 *
 * RETURN-NORMAL = SUCCESS
 *                     TRUE
 *
 * RETURN-ERROR  = FAILURE
 *                     FALSE
 *
 *
 *
 ****************************************************************************/

LOCAL BOOL  set_area_attr_bundle(PDDC pDDC,ULONG DefsMask,ULONG
                                             AttrsMask,PDAREABUNDLE pAttrs)
{
  BOOL bErrors = FALSE;
  AREABUNDLE abndIncoming;

  abndIncoming = pDDC->DCState.abnd;

  if (AttrsMask & ABB_COLOR)
  {
    if (DefsMask & ABB_COLOR)
    {
      pDDC->DCState.abnd.lColor = (pDDC->DCState.usColorFormat != LCOLF_RGB)?
         CLR_BLACK:COLOR_BLACK;
    }
    else
      if (validate_foreground_color(pDDC, pAttrs->abnd.lColor))
        pDDC->DCState.abnd.lColor = pAttrs->abnd.lColor;
      else
        bErrors = TRUE;
  }

  if (AttrsMask & ABB_BACK_COLOR)
  {
    if (DefsMask & ABB_BACK_COLOR)
      pDDC->DCState.abnd.lBackColor = (pDDC->DCState.usColorFormat != LCOLF_RGB)
         ?CLR_WHITE:COLOR_WHITE;
    else
      if (validate_background_color(pDDC, pAttrs->abnd.lBackColor))
        pDDC->DCState.abnd.lBackColor = pAttrs->abnd.lBackColor;
      else
        bErrors = TRUE;
  }

  if (AttrsMask & ABB_MIX_MODE)
  {
    if (DefsMask & ABB_MIX_MODE)
      pDDC->DCState.abnd.usMixMode = FM_DEFAULT;
    else
      if (validate_foreground_mix(pAttrs->abnd.usMixMode))
        pDDC->DCState.abnd.usMixMode = pAttrs->abnd.usMixMode;
      else
        bErrors = TRUE;
  }

  if (AttrsMask & ABB_BACK_MIX_MODE)
  {
    if (DefsMask & ABB_BACK_MIX_MODE)
      pDDC->DCState.abnd.usBackMixMode = BM_DEFAULT;
    else
      if (validate_background_mix(pAttrs->abnd.usBackMixMode))
        pDDC->DCState.abnd.usBackMixMode = pAttrs->abnd.usBackMixMode;
      else
        bErrors = TRUE;
  }

  if (AttrsMask & ABB_SET)
  {
    if (DefsMask & ABB_SET)
      pDDC->DCState.abnd.usSet = 0;
    else
   {
#ifdef DEBUG
      if (pDDC->DCState.abnd.usSet != pAttrs->abnd.usSet)
      {
        DBPRINTF (("User defined Pattern set usSet = %d \n",pAttrs->abnd.usSet));
      }
#endif
      pDDC->DCState.abnd.usSet = pAttrs->abnd.usSet;
    }
  }

  if (AttrsMask & ABB_SYMBOL)
  {
    if (DefsMask & ABB_SYMBOL || pAttrs->abnd.usSymbol == PATSYM_DEFAULT)
      pDDC->DCState.abnd.usSymbol = PATSYM_SOLID;
    else
      if (pAttrs->abnd.usSymbol <= PATSYM_HALFTONE ||
          pAttrs->abnd.usSymbol == PATSYM_BLANK)
        pDDC->DCState.abnd.usSymbol = pAttrs->abnd.usSymbol;
      else
      {
        GplErrSetError(PMERR_INV_PATTERN_ATTR);
        bErrors = TRUE;
      }
  }

  if (AttrsMask & ABB_REF_POINT)
  {
    if (DefsMask & ABB_REF_POINT)
      pDDC->DCState.abnd.ptlRefPoint.x = pDDC->DCState.abnd.ptlRefPoint.y = 0;
    else
      pDDC->DCState.abnd.ptlRefPoint = pAttrs->abnd.ptlRefPoint;
  }

  if (bErrors)
    pDDC->DCState.abnd = abndIncoming; /* Restore initial state  */

  return (bErrors?FALSE:TRUE);
}

/***********************************************************************
 *
 * FUNCTION NAME = set_char_attr_bundle()
 *
 * DESCRIPTION   = Set char attributes
 *
 *                 Set information from the current character attribute bundle
 *                 according to the "AttrsMask" parameter.
 *
 *
 *
 * INPUT         = pDDC, DefsMask, AttrsMask, pAttrs
 *
 * OUTPUT        = NONE
 *
 *
 *
 *
 * RETURN-NORMAL = SUCCESS
 *                     TRUE
 *
 * RETURN-ERROR  = FAILURE
 *                     FALSE
 *
 *
 *
 *
 ****************************************************************************/

LOCAL BOOL  set_char_attr_bundle(PDDC pDDC,ULONG DefsMask,ULONG
                                             AttrsMask,PDCHARBUNDLE pAttrs)
{
  BOOL bErrors = FALSE;
  PPDEVICE pPDevice = pDDC->pPDevice;
  DCHARBUNDLE dcbndLocal;

  dcbndLocal = pDDC->DCState.dcbnd;

  if (AttrsMask & CBB_COLOR)
  {
    if (DefsMask & CBB_COLOR)
      pDDC->DCState.dcbnd.cbnd.lColor = (pDDC->DCState.usColorFormat !=
         LCOLF_RGB)?CLR_BLACK:COLOR_BLACK;
    else
      if (validate_foreground_color(pDDC, pAttrs->cbnd.lColor))
        pDDC->DCState.dcbnd.cbnd.lColor = pAttrs->cbnd.lColor;
      else
        bErrors = TRUE;
  }

  if (AttrsMask & CBB_BACK_COLOR)
  {
    if (DefsMask & CBB_BACK_COLOR)
      pDDC->DCState.dcbnd.cbnd.lBackColor = (pDDC->DCState.usColorFormat !=
         LCOLF_RGB)?CLR_WHITE:COLOR_WHITE;
    else
      if (validate_background_color(pDDC, pAttrs->cbnd.lBackColor))
        pDDC->DCState.dcbnd.cbnd.lBackColor = pAttrs->cbnd.lBackColor;
      else
        bErrors = TRUE;
  }

  if (AttrsMask & CBB_MIX_MODE)
  {
    if (DefsMask & CBB_MIX_MODE)
      pDDC->DCState.dcbnd.cbnd.usMixMode = FM_DEFAULT;
    else
      if (validate_foreground_mix(pAttrs->cbnd.usMixMode))
        pDDC->DCState.dcbnd.cbnd.usMixMode = pAttrs->cbnd.usMixMode;
      else
        bErrors = TRUE;
  }

  if (AttrsMask & CBB_BACK_MIX_MODE)
  {
    if (DefsMask & CBB_BACK_MIX_MODE)
      pDDC->DCState.dcbnd.cbnd.usBackMixMode = BM_DEFAULT;
    else
      if (validate_background_mix(pAttrs->cbnd.usBackMixMode))
        pDDC->DCState.dcbnd.cbnd.usBackMixMode = pAttrs->cbnd.usBackMixMode;
      else
        bErrors = TRUE;
  }

  if (AttrsMask & CBB_SET)
  {
    if (DefsMask & CBB_SET)
      pDDC->DCState.dcbnd.cbnd.usSet = 0;
    else
      pDDC->DCState.dcbnd.cbnd.usSet = pAttrs->cbnd.usSet;

    /*
    ** if we did not set the font to the default- use the cdef info
    ** else set cdef to the default   MarkV PTR # ?
    */
    if ((pDDC->DCState.dcbnd.cbnd.usSet != 0)  && pAttrs)
    {
      /*
      ** We have an input address AND some values from it are used
      */
      pDDC->DCState.dcbnd.cdef.fFlags = pAttrs->cdef.fFlags;
      pDDC->DCState.dcbnd.cdef.defSet = pAttrs->cdef.defSet;
      pDDC->DCState.dcbnd.cdef.CodePage = pAttrs->cdef.CodePage;
    }
    else
    {
      /*
      ** We are setting the default
      */
      pDDC->DCState.dcbnd.cdef.fFlags   = 0L;
      pDDC->DCState.dcbnd.cdef.defSet   = 0;
      pDDC->DCState.dcbnd.cdef.CodePage = 0;
    }                                  /* end usSet set to 0           ******/
  }                                    /* end CBB_SET                  ******/

  if (AttrsMask & CBB_MODE)
  {
    if (DefsMask & CBB_MODE || pAttrs->cbnd.usPrecision == CM_DEFAULT)
      pDDC->DCState.dcbnd.cbnd.usPrecision = CM_MODE1;
    else
      if (pAttrs->cbnd.usPrecision <= CM_MODE3)
        pDDC->DCState.dcbnd.cbnd.usPrecision = pAttrs->cbnd.usPrecision;
      else
      {
        GplErrSetError(PMERR_INV_CHAR_MODE_ATTR);
        bErrors = TRUE;
      }
  }

  if (AttrsMask & CBB_BOX)
  {
    if (DefsMask & CBB_BOX)
    {
      pDDC->DCState.dcbnd.cbnd.sizfxCell.cx =
                     MAKEFIXED(pPDevice->lCapsDefCharWidth, 0);
      pDDC->DCState.dcbnd.cbnd.sizfxCell.cy =
                     MAKEFIXED(pPDevice->lCapsDefCharHeight, 0);
    }
    else
      pDDC->DCState.dcbnd.cbnd.sizfxCell = pAttrs->cbnd.sizfxCell;
  }

  if (AttrsMask & CBB_ANGLE)
  {
    if (DefsMask & CBB_ANGLE)
    {
      pDDC->DCState.dcbnd.cbnd.ptlAngle.x = 100L;
      pDDC->DCState.dcbnd.cbnd.ptlAngle.y = 0L;
    }
    else
      if (pAttrs->cbnd.ptlAngle.x == 0L && pAttrs->cbnd.ptlAngle.y == 0L)
      {
        GplErrSetError(PMERR_INV_CHAR_ANGLE_ATTR);
        bErrors = TRUE;
      }
      else
        pDDC->DCState.dcbnd.cbnd.ptlAngle = pAttrs->cbnd.ptlAngle;
  }

  if (AttrsMask & CBB_SHEAR)
  {
    if (DefsMask & CBB_SHEAR)
    {
      pDDC->DCState.dcbnd.cbnd.ptlShear.x = 0;
      pDDC->DCState.dcbnd.cbnd.ptlShear.y = 1;
    }
    else
      if (pAttrs->cbnd.ptlShear.y == 0)
      {
        GplErrSetError(PMERR_INV_CHAR_SHEAR_ATTR);
        bErrors = TRUE;
      }
      else
        pDDC->DCState.dcbnd.cbnd.ptlShear = pAttrs->cbnd.ptlShear;
  }

  if (AttrsMask & CBB_DIRECTION)
  {
    if (DefsMask & CBB_DIRECTION || pAttrs->cbnd.usDirection == CHDIRN_DEFAULT)
      pDDC->DCState.dcbnd.cbnd.usDirection = CHDIRN_LEFTRIGHT;
    else
    {
      if (pAttrs->cbnd.usDirection == CHDIRN_LEFTRIGHT ||
         pAttrs->cbnd.usDirection == CHDIRN_TOPBOTTOM ||
         pAttrs->cbnd.usDirection == CHDIRN_RIGHTLEFT ||
         pAttrs->cbnd.usDirection == CHDIRN_BOTTOMTOP)
        pDDC->DCState.dcbnd.cbnd.usDirection = pAttrs->cbnd.usDirection;
      else
      {
        GplErrSetError(PMERR_INV_CHAR_DIRECTION_ATTR);
        bErrors = TRUE;
      }
    }
  }
  /*
  ** C/Set2 Conversion: New members added to the CHARBUNDLE structure
  */
  if(AttrsMask & CBB_TEXT_ALIGN)
  {
    if(DefsMask & CBB_TEXT_ALIGN)
    {
      pDDC->DCState.dcbnd.cbnd.usTextAlign = (TA_NORMAL_HORIZ | TA_NORMAL_VERT);
    }
    else
    {
      if ((LOBYTE(pAttrs->cbnd.usTextAlign) <= TA_STANDARD_HORIZ) &&
         (pAttrs->cbnd.usTextAlign & TA_GOOD_HORIZ) &&
         (HIBYTE(pAttrs->cbnd.usTextAlign) <= TA_STANDARD_VERT) &&
         (pAttrs->cbnd.usTextAlign & TA_GOOD_VERT))
        pDDC->DCState.dcbnd.cbnd.usTextAlign = pAttrs->cbnd.usTextAlign;
      else
      {
        GplErrSetError(PMERR_INV_CHAR_ALIGN_ATTR);
        bErrors = TRUE;
      }
    }
  }

  if (AttrsMask & CBB_EXTRA)
  {
    if(DefsMask & CBB_EXTRA)
    {
      pDDC->DCState.dcbnd.cbnd.fxExtra = 0;
    }
    else
    {
      pDDC->DCState.dcbnd.cbnd.fxExtra = pAttrs->cbnd.fxExtra;
    }
  }

  if (AttrsMask & CBB_BREAK_EXTRA)
  {
    if(DefsMask & CBB_BREAK_EXTRA)
    {
      pDDC->DCState.dcbnd.cbnd.fxBreakExtra = 0;
    }
    else
    {
      pDDC->DCState.dcbnd.cbnd.fxBreakExtra = pAttrs->cbnd.fxBreakExtra;
    }
  }
  if (bErrors)
    pDDC->DCState.dcbnd = dcbndLocal;

  return  bErrors?FALSE:TRUE;
}

/***********************************************************************
 *
 * FUNCTION NAME = set_image_attr_bundle()
 *
 * DESCRIPTION   = Set image attributes
 *
 *
 * INPUT         = pDDC,DefsMask,AttrsMask,pAttrs
 *
 * OUTPUT        = NONE
 *
 *
 * RETURN-NORMAL = SUCCESS
 *                     TRUE
 *
 * RETURN-ERROR  = FAILURE
 *                     FALSE
 *
 *
 *
 *
 *
 *
 ****************************************************************************/

LOCAL BOOL  set_image_attr_bundle(PDDC pDDC,ULONG DefsMask,ULONG
                                              AttrsMask,PDIMAGEBUNDLE pAttrs)
{
  BOOL bErrors = FALSE;
  IMAGEBUNDLE ibndIncoming;

  ibndIncoming = pDDC->DCState.ibnd;

  if (AttrsMask & IBB_COLOR)
  {
    if (DefsMask & IBB_COLOR)
      pDDC->DCState.ibnd.lColor = (pDDC->DCState.usColorFormat != LCOLF_RGB)?
         CLR_BLACK:COLOR_BLACK;
    else
      if (validate_foreground_color(pDDC, pAttrs->ibnd.lColor))
        pDDC->DCState.ibnd.lColor = pAttrs->ibnd.lColor;
      else
        bErrors = TRUE;
  }

  if (AttrsMask & IBB_BACK_COLOR)
  {
    if (DefsMask & IBB_BACK_COLOR)
      pDDC->DCState.ibnd.lBackColor = (pDDC->DCState.usColorFormat != LCOLF_RGB)
         ?CLR_WHITE:COLOR_WHITE;
    else
      if (validate_background_color(pDDC, pAttrs->ibnd.lBackColor))
        pDDC->DCState.ibnd.lBackColor = pAttrs->ibnd.lBackColor;
      else
        bErrors = TRUE;
  }

  if (AttrsMask & IBB_MIX_MODE)
  {
    if (DefsMask & IBB_MIX_MODE)
      pDDC->DCState.ibnd.usMixMode = FM_DEFAULT;
    else
      if (validate_foreground_mix(pAttrs->ibnd.usMixMode))
        pDDC->DCState.ibnd.usMixMode = pAttrs->ibnd.usMixMode;
      else
        bErrors = TRUE;
  }

  if (AttrsMask & IBB_BACK_MIX_MODE)
  {
    if (DefsMask & IBB_BACK_MIX_MODE)
      pDDC->DCState.ibnd.usBackMixMode = BM_DEFAULT;
    else
      if (validate_background_mix(pAttrs->ibnd.usBackMixMode))
        pDDC->DCState.ibnd.usBackMixMode = pAttrs->ibnd.usBackMixMode;
      else
        bErrors = TRUE;
  }

  if (bErrors)
    pDDC->DCState.ibnd = ibndIncoming;

  return  bErrors?FALSE:TRUE;
}

/***********************************************************************
 *
 * FUNCTION NAME = set_line_attr_bundle()
 *
 * DESCRIPTION   = Set line attributes
 *
 *
 *
 * INPUT         = pDDC,DefsMask,AttrsMask,pAttrs
 * OUTPUT        = NONE
 *
 *
 *
 * RETURN-NORMAL = SUCCESS
 *                     TRUE
 *
 * RETURN-ERROR  = FAILURE
 *                     FALSE
 *
 *
 *
 *
 ****************************************************************************/

LOCAL BOOL  set_line_attr_bundle(HDC hDC,PDDC pDDC,ULONG DefsMask,
                                             ULONG AttrsMask,PDLINEBUNDLE
                                             pAttrs,ULONG FunN)
{
  BOOL bErrors = FALSE;
  LINEBUNDLE lbndIncoming;

  lbndIncoming = pDDC->DCState.lbnd;

  if (AttrsMask & LBB_COLOR)
  {
    if (DefsMask & LBB_COLOR)
      pDDC->DCState.lbnd.lColor = (pDDC->DCState.usColorFormat != LCOLF_RGB)?
         CLR_BLACK:COLOR_BLACK;
    else
      if (validate_foreground_color(pDDC, pAttrs->lbnd.lColor))
        pDDC->DCState.lbnd.lColor = pAttrs->lbnd.lColor;
      else
        bErrors = TRUE;
  }

  if (AttrsMask & LBB_MIX_MODE)
  {
    if (DefsMask & LBB_MIX_MODE)
      pDDC->DCState.lbnd.usMixMode = FM_DEFAULT;
    else
      if (validate_foreground_mix(pAttrs->lbnd.usMixMode))
        pDDC->DCState.lbnd.usMixMode = pAttrs->lbnd.usMixMode;
      else
        bErrors = TRUE;
  }

  if (AttrsMask & LBB_WIDTH)
  {
    if (DefsMask & LBB_WIDTH)
      pDDC->DCState.lbnd.fxWidth = LINEWIDTH_NORMAL;
    else
    {
      if (pAttrs->lbnd.fxWidth == LINEWIDTH_DEFAULT)
        pDDC->DCState.lbnd.fxWidth = LINEWIDTH_NORMAL;
      else
      {
        if (pAttrs->lbnd.fxWidth == LINEWIDTH_NORMAL ||
            pAttrs->lbnd.fxWidth == LINEWIDTH_THICK)
        {
          pDDC->DCState.lbnd.fxWidth = pAttrs->lbnd.fxWidth;
        }
        else
        {
          pDDC->DCState.lbnd.fxWidth = LINEWIDTH_NORMAL;
          GplErrSetWarning(PMERR_INV_LINE_WIDTH_ATTR);
        }
      }
    }
  }

  if (AttrsMask & LBB_GEOM_WIDTH)
  {
    if (DefsMask & LBB_GEOM_WIDTH)
      pDDC->DCState.lbnd.lGeomWidth = 0L;
    else
    {
      /*
      ** if geometric line width is in world coordinates
      ** convert it to device for internal use.
      */
      //if (FunN & COM_TRANSFORM)
      if (TRUE)/* 1.3 engine is not setting the COM_TRANSFORM bit on this call */
      {
        /*
        ** Store the geometric width in device units
        **
        ** Calculate the geometric width in device units
        */
        POINTL aptlPoints[2];

        aptlPoints[0].x = 0;
        aptlPoints[0].y = 0;
        aptlPoints[1].x = pAttrs->lbnd.lGeomWidth;
        aptlPoints[1].y = 0;
        convert_world_to_device(hDC, aptlPoints, 2L, pDDC);

        /*
        ** calc vector length of geometric width in device units
        */

        pDDC->DCState.lbnd.lGeomWidth = (aptlPoints[1].x - aptlPoints[0].x) +
                                        (aptlPoints[1].y - aptlPoints[0].y);
      }
      else
      {
        pDDC->DCState.lbnd.lGeomWidth = pAttrs->lbnd.lGeomWidth;
      }
    }
  }

  if (AttrsMask & LBB_TYPE)
  {
    if (DefsMask & LBB_TYPE)
      pDDC->DCState.lbnd.usType = LINETYPE_SOLID;
    else
      if (pAttrs->lbnd.usType <= LINETYPE_ALTERNATE)
        pDDC->DCState.lbnd.usType = pAttrs->lbnd.usType;
      else
      {
        GplErrSetError(PMERR_INV_LINE_TYPE_ATTR);
        bErrors = TRUE;
      }
  }

  if (AttrsMask & LBB_END)
  {
    if (DefsMask & LBB_END)
      pDDC->DCState.lbnd.usEnd = LINEEND_DEFAULT;
    else
      if (pAttrs->lbnd.usEnd <= LINEEND_ROUND)
        pDDC->DCState.lbnd.usEnd = pAttrs->lbnd.usEnd;
      else
      {
        GplErrSetError(PMERR_INV_LINE_END_ATTR);
        bErrors = TRUE;
      }
  }

  if (AttrsMask & LBB_JOIN)
  {
    if (DefsMask & LBB_JOIN)
      pDDC->DCState.lbnd.usJoin = LINEJOIN_DEFAULT;
    else
      if (pAttrs->lbnd.usJoin <= LINEJOIN_MITRE)
        pDDC->DCState.lbnd.usJoin = pAttrs->lbnd.usJoin;
      else
      {
        GplErrSetError(PMERR_INV_LINE_JOIN_ATTR);
        bErrors = TRUE;
      }
  }

  if (AttrsMask & LBB_BACK_COLOR)
  {
    if (DefsMask & LBB_BACK_COLOR)
      pDDC->DCState.lbnd.lBackColor = (pDDC->DCState.usColorFormat != LCOLF_RGB)
         ?CLR_WHITE:COLOR_WHITE;
    else
      if (validate_background_color(pDDC, pAttrs->lbnd.lBackColor))
        pDDC->DCState.lbnd.lBackColor = pAttrs->lbnd.lBackColor;
      else
        bErrors = TRUE;
  }

  if (AttrsMask & LBB_BACK_MIX_MODE)
  {
    if (DefsMask & LBB_BACK_MIX_MODE)
      pDDC->DCState.lbnd.usBackMixMode = BM_DEFAULT;
    else
      if (validate_background_mix(pAttrs->lbnd.usBackMixMode))
        pDDC->DCState.lbnd.usBackMixMode = pAttrs->lbnd.usBackMixMode;
      else
        bErrors = TRUE;
  }

  if (bErrors)
    pDDC->DCState.lbnd = lbndIncoming;

  return (bErrors?FALSE:TRUE);
}

/***********************************************************************
 *
 * FUNCTION NAME = set_marker_attr_bundle()
 *
 * DESCRIPTION   = Set marker attributes
 *
 *
 *
 * INPUT         = pDDC,DefsMask,AttrsMask,pAttrs
 *
 * OUTPUT        = NONE
 *
 *
 *
 * RETURN-NORMAL = SUCCESS
 *                     TRUE
 *
 * RETURN-ERROR  = FAILURE
 *                     FALSE
 *
 *
 *
 *
 *
 ****************************************************************************/

LOCAL BOOL  set_marker_attr_bundle(PDDC pDDC,ULONG DefsMask,ULONG
                                               AttrsMask,PDMARKERBUNDLE pAttrs
)
{
  BOOL bErrors = FALSE;
  MARKERBUNDLE mbndIncoming;
  PPDEVICE pPDevice = pDDC->pPDevice;

  mbndIncoming = pDDC->DCState.mbnd;

  if (AttrsMask & MBB_COLOR)
  {
    if (DefsMask & MBB_COLOR)
      pDDC->DCState.mbnd.lColor = (pDDC->DCState.usColorFormat != LCOLF_RGB)?
         CLR_BLACK:COLOR_BLACK;
    else
      if (validate_foreground_color(pDDC, pAttrs->mbnd.lColor))
        pDDC->DCState.mbnd.lColor = pAttrs->mbnd.lColor;
      else
        bErrors = TRUE;
  }

  if (AttrsMask & MBB_BACK_COLOR)
  {
    if (DefsMask & MBB_BACK_COLOR)
      pDDC->DCState.mbnd.lBackColor = (pDDC->DCState.usColorFormat != LCOLF_RGB)
         ?CLR_WHITE:COLOR_WHITE;
    else
      if (validate_background_color(pDDC, pAttrs->mbnd.lBackColor))
        pDDC->DCState.mbnd.lBackColor = pAttrs->mbnd.lBackColor;
      else
        bErrors = TRUE;
  }

  if (AttrsMask & MBB_MIX_MODE)
  {
    if (DefsMask & MBB_MIX_MODE)
      pDDC->DCState.mbnd.usMixMode = FM_DEFAULT;
    else
      if (validate_foreground_mix(pAttrs->mbnd.usMixMode))
        pDDC->DCState.mbnd.usMixMode = pAttrs->mbnd.usMixMode;
      else
        bErrors = TRUE;
  }

  if (AttrsMask & MBB_BACK_MIX_MODE)
  {
    if (DefsMask & MBB_BACK_MIX_MODE)
      pDDC->DCState.mbnd.usBackMixMode = BM_DEFAULT;
    else
      if (validate_background_mix(pAttrs->mbnd.usBackMixMode))
        pDDC->DCState.mbnd.usBackMixMode = pAttrs->mbnd.usBackMixMode;
      else
        bErrors = TRUE;
  }

  if (AttrsMask & MBB_SET)
  {
    if (DefsMask & MBB_SET)
      pDDC->DCState.mbnd.usSet = 0;
    else
      pDDC->DCState.mbnd.usSet = pAttrs->mbnd.usSet;
  }

  if (AttrsMask & MBB_SYMBOL)
  {
    if (DefsMask & MBB_SYMBOL)
      pDDC->DCState.mbnd.usSymbol = MARKSYM_DEFAULT;
    else
      if (pAttrs->mbnd.usSymbol <= MAX_MARKER_SYMBOL)
        pDDC->DCState.mbnd.usSymbol = pAttrs->mbnd.usSymbol;
      else
      {
        GplErrSetError(PMERR_INV_MARKER_SYMBOL_ATTR);
        bErrors = TRUE;
      }
  }

  if (AttrsMask & MBB_BOX)
  {
    if (DefsMask & MBB_BOX)
    {
      pDDC->DCState.mbnd.sizfxCell.cx = pPDevice->lCapsDefMarkerWidth *65536L;
      pDDC->DCState.mbnd.sizfxCell.cy = pPDevice->lCapsDefMarkerHeight *65536L;
    }
    else
      pDDC->DCState.mbnd.sizfxCell = pAttrs->mbnd.sizfxCell;
  }

  if (bErrors)
    pDDC->DCState.mbnd = mbndIncoming;

  return (bErrors?FALSE:TRUE);
}

/***********************************************************************
 *
 * FUNCTION NAME = validate_any_color()
 *
 * DESCRIPTION   = Validate color
 *
 *
 * INPUT         = pDDC,Color
 *
 * OUTPUT        = NONE
 *
 *
 * RETURN-NORMAL = SUCCESS
 *                     TRUE
 *
 * RETURN-ERROR  = FAILURE
 *                     FALSE
 *
 *
 *
 *
 *
 ****************************************************************************/

LOCAL BOOL  validate_any_color(PDDC pDDC,LONG lColor)
{
  BOOL bResult = FALSE;

  if (lColor < 0L)
  {
    if (lColor == CLR_BLACK || lColor == CLR_WHITE || lColor == CLR_FALSE ||
        lColor == CLR_DEFAULT || lColor == CLR_TRUE)
      bResult = TRUE;
  }
  else
  {
    if (pDDC->DCState.usColorFormat != LCOLF_RGB)
    {
      if (lColor <= pDDC->DCState.lColorHiIndex)
        bResult = TRUE;
    }
    else
    {
      if (HIUCHAR(HIUSHORT(lColor)) == 0)
        bResult = TRUE;
      else
        bResult = FALSE;
    }
  }
  return (bResult);
}

/***********************************************************************
 *
 * FUNCTION NAME = validate_background_color()
 *
 * DESCRIPTION   = Validate background color
 *
 *
 *
 * INPUT         = pDDC,lColor
 *
 * OUTPUT        = NONE
 *
 *
 *
 * RETURN-NORMAL = SUCCESS
 *                     TRUE
 *
 * RETURN-ERROR  = FAILURE
 *                     FALSE
 *
 *
 *
 *
 *
 ****************************************************************************/

LOCAL BOOL  validate_background_color(PDDC pDDC,LONG lColor)
{
  BOOL bResult = validate_any_color(pDDC, lColor);


  if (bResult == FALSE)
    GplErrSetError(PMERR_INV_BACKGROUND_COL_ATTR);
  return (bResult);
}

/***********************************************************************
 *
 * FUNCTION NAME = validate_foreground_color()
 *
 * DESCRIPTION   = Validate foreground color
 *
 *
 *
 * INPUT         = pDDC,lColor
 *
 * OUTPUT        = NONE
 *
 *
 * RETURN-NORMAL = SUCCESS
 *                     TRUE
 *
 * RETURN-ERROR  = FAILURE
 *                     FALSE
 *
 *
 *
 *
 ****************************************************************************/

LOCAL BOOL  validate_foreground_color(PDDC pDDC,LONG lColor)
{
  BOOL bResult = validate_any_color(pDDC, lColor);

  if (bResult == FALSE)
    GplErrSetError(PMERR_INV_COLOR_ATTR);
  return (bResult);
}

/***********************************************************************
 *
 * FUNCTION NAME = validate_background_mix()
 *
 * DESCRIPTION   = Validate background mix
 *
 *
 * INPUT         = Mix
 *
 * OUTPUT        = NONE
 *
 *
 *
 * RETURN-NORMAL = SUCCESS
 *                     TRUE
 *
 * RETURN-ERROR  = FAILURE
 *                     FALSE
 *
 *
 *
 *
 ****************************************************************************/

LOCAL BOOL  validate_background_mix(USHORT Mix)
{
  BOOL bResult;


  if (Mix == BM_DEFAULT || Mix == BM_OVERPAINT ||
      Mix == BM_LEAVEALONE || Mix == BM_OR || Mix == BM_XOR)
    bResult = TRUE;
  else
  {
    bResult = FALSE;
    GplErrSetError(PMERR_INV_BACKGROUND_MIX_ATTR);
  }
  return (bResult);
}

/***********************************************************************
 *
 * FUNCTION NAME =  validate_foreground_mix()
 *
 * DESCRIPTION   = Validate foreground mix
 *
 *
 *
 *
 * INPUT         = Mix
 *
 * OUTPUT        = NONE
 *
 *
 *
 * RETURN-NORMAL = SUCCESS
 *                     TRUE
 *
 * RETURN-ERROR  = FAILURE
 *                     FALSE
 *
 *
 *
 *
 *
 ****************************************************************************/

LOCAL BOOL  validate_foreground_mix(USHORT Mix)
{
  BOOL bResult;


  if (Mix == FM_DEFAULT || Mix == FM_OVERPAINT || Mix == FM_LEAVEALONE ||
     Mix == FM_OR || Mix == FM_XOR || Mix == FM_AND || Mix == FM_SUBTRACT ||
     Mix == FM_MASKSRCNOT || Mix == FM_ZERO || Mix == FM_NOTMERGESRC ||
     Mix == FM_NOTXORSRC || Mix == FM_INVERT || Mix == FM_MERGESRCNOT ||
     Mix == FM_NOTCOPYSRC || Mix == FM_MERGENOTSRC || Mix == FM_NOTMASKSRC ||
     Mix == FM_ONE)
    bResult = TRUE;
  else
  {
    bResult = FALSE;
    GplErrSetError(PMERR_INV_MIX_ATTR);
  }
  return (bResult);
}

/*
** PUBLIC FUNCTIONS
*/
/***********************************************************************
 *
 * FUNCTION NAME = initialize_ddc()
 *
 * DESCRIPTION   = Initialize Device driver instance
 *
 *                 reset the device driver instance data structure to
 *                 its base state
 *
 *
 *
 * INPUT         = pDDC
 *
 * OUTPUT        = NONE
 *
 *
 *
 * RETURN-NORMAL = SUCCESS
 *                     TRUE
 *
 * RETURN-ERROR  = FAILURE
 *                     FALSE
 *
 *
 *
 ****************************************************************************/

BOOL  initialize_ddc(PDDC pDDC)
{
  BOOL bResult = FALSE;
  ULONG     rc = 0;
  /*
  ** miscellaneous
  */
  pDDC->DCState.LogPosition.x   = pDDC->DCState.LogPosition.y   = 0L;
  pDDC->DCState.WorldPosition.x = pDDC->DCState.WorldPosition.y = 0L;
  pDDC->DCState.ArcParams.lP    = pDDC->DCState.ArcParams.lQ = 1L;
  pDDC->DCState.ArcParams.lR    = pDDC->DCState.ArcParams.lS = 0L;
  pDDC->DCState.bInArea         = FALSE;
  pDDC->DCState.bDoFills        = TRUE;
  pDDC->DCState.bDrawingText    = FALSE;
  pDDC->DCState.bFilling        = FALSE;
  pDDC->DCState.ulAreaFlags     = 0L;
  pDDC->ulCodePage              = CP_850;
  pDDC->pCPVector               = 0;
  pDDC->DCState.ulLineStyle     = DDC_FIRST_PEL;


  /*
  ** region/clip
  */
  pDDC->DCState.ClipComplexity  = 0L;
  pDDC->DCState.ClipRect.xLeft  = pDDC->DCState.ClipRect.yBottom = 0L;
  pDDC->DCState.ClipRect.xRight = pDDC->DCState.ClipRect.yTop = 0L;

  /*
  ** bounds
  */
  pDDC->bGpiBoundsIsReset = pDDC->bUserBoundsIsReset = TRUE;
  pDDC->GpiBounds.xLeft   = pDDC->GpiBounds.yBottom  = MAX_BOUNDS;
  pDDC->UserBounds.xLeft  = pDDC->UserBounds.yBottom = MAX_BOUNDS;
  pDDC->GpiBounds.xRight  = pDDC->GpiBounds.yTop     = MIN_BOUNDS;
  pDDC->UserBounds.xRight = pDDC->UserBounds.yTop    = MIN_BOUNDS;

  /*
  ** set up color table
  */
  bResult = create_default_color_table(pDDC);

  /*
  ** attributes
  */

  set_line_attr_bundle((HDC)NULL, pDDC, 0xffffffffL, 0xffffffffL,
                       (PDLINEBUNDLE)0, (ULONG)0);
  set_char_attr_bundle(pDDC, 0xffffffffL, 0xffffffffL, (PDCHARBUNDLE)0);
  set_marker_attr_bundle(pDDC, 0xffffffffL, 0xffffffffL, (PDMARKERBUNDLE)0);
  set_area_attr_bundle(pDDC, 0xffffffffL, 0xffffffffL, (PDAREABUNDLE)0);
  set_image_attr_bundle(pDDC, 0xffffffffL, 0xffffffffL, (PDIMAGEBUNDLE)0);

  /*
  ** transform related
  */
  /*
  ** Last seen by NotifyTransformChange
  */
  pDDC->DCState.xfLastMatrix.fxM11 = MAKEFIXED(1, 0);/* Last seen by
                                                     NotifyTransformChange  */
  pDDC->DCState.xfLastMatrix.fxM12 = MAKEFIXED(0, 0);
  pDDC->DCState.xfLastMatrix.fxM21 = MAKEFIXED(0, 0);
  pDDC->DCState.xfLastMatrix.fxM22 = MAKEFIXED(1, 0);
  pDDC->DCState.xfLastMatrix.lM41 = 0; /* x translation                     */
  pDDC->DCState.xfLastMatrix.lM42 = 0; /* y translation                     */
  pDDC->DCState.ptlRotation.x = 0;     /* Inferred Rotation information     */
  pDDC->DCState.ptlRotation.y = 0;
  pDDC->DCState.ptlShear.x = 0;        /* Shear information                 */
  pDDC->DCState.ptlShear.y = 0;
  pDDC->DCState.usXfData = 0;          /* Status information - see #define  */



  return (bResult);
}

/*
** EXPORTED FUNCTIONS
*/
/***********************************************************************
 *
 * FUNCTION NAME = DeviceGetAttributes()
 *
 * DESCRIPTION   = Get plotter driver attributes
 *
 *                 entry point for external processes to obtain
 *                 information about the current attributes of the
 *                 plotter driver.
 *
 *
 * INPUT         = hDC, BType, AttrsMask, pAttrs, pDDC, FunN
 *
 *
 *
 * OUTPUT        = NONE
 *
 *
 *
 * RETURN-NORMAL = SUCCESS
 *                     TRUE
 *
 * RETURN-ERROR  = FAILURE
 *                     FALSE
 *
 *
 *
 ****************************************************************************/

LONG  DeviceGetAttributes(HDC hDC,ULONG BType,ULONG AttrsMask,PULONG
                                     pAttrs,PDDC pDDC,ULONG FunN)
{
  LONG lResult = 0L;
  if (!EnterDriver(pDDC))
      return(GPI_ERROR);
  /*
  **          In case of MEMORYDC Dispatch to Graphics Engine
  */
  if (pDDC->usDCType == OD_MEMORY)
  {
    lResult = InnerGreDeviceGetAttributes( pDDC->hdcMemory, BType,
                                           AttrsMask,pAttrs, FunN );
    LeaveDriver( pDDC );
    return( lResult );
  }

  switch (LOUSHORT(BType))
  {
    case  PRIM_LINE :
      lResult = get_line_attr_bundle(hDC, pDDC, AttrsMask,
                                     (PDLINEBUNDLE)pAttrs, FunN);
      break;
    case  PRIM_CHAR :
      lResult = get_char_attr_bundle(pDDC, AttrsMask, (PDCHARBUNDLE)pAttrs);
      break;
    case  PRIM_MARKER :
      lResult = get_marker_attr_bundle(pDDC, AttrsMask, (PDMARKERBUNDLE)pAttrs);
      break;
    case  PRIM_AREA :
      lResult = get_area_attr_bundle(pDDC, AttrsMask, (PDAREABUNDLE)pAttrs);
      break;
    case  PRIM_IMAGE :
      lResult = get_image_attr_bundle(pDDC, AttrsMask, (PDIMAGEBUNDLE)pAttrs);
      break;
    default  :
      GplErrSetError(PMERR_DEV_FUNC_NOT_INSTALLED);
      break;
  }

  if (lResult)
  {
    LeaveDriver(pDDC);
    return (TRUE);
  }
  else
  {
    LeaveDriver(pDDC);
    return (FALSE);
  }
}

/***********************************************************************
 *
 * FUNCTION NAME = DeviceSetAttributes()
 *
 * DESCRIPTION   = Set plotter driver attributes
 *
 *                 entry point for external processes to modify the
 *                 current plotter driver attributes
 *
 *
 *
 * INPUT         = hDC,BType,DefsMask,AttrsMask,pAttrs,pDDC,FunN
 *
 * OUTPUT        = NONE
 *
 *
 *
 * RETURN-NORMAL = Result value
 * RETURN-ERROR  =
 *
 *
 *
 *
 ****************************************************************************/

LONG  DeviceSetAttributes(HDC hDC,ULONG BType,ULONG DefsMask,ULONG
                                     AttrsMask,PULONG pAttrs,PDDC pDDC,ULONG
                                     FunN)
{
  LONG Result = 0L;
  LONG lStatus;

  if (!EnterDriver(pDDC))
      return(GPI_ERROR);

  /**************************************************************************
  **                    Support for MEMORYDC                               **
  **                            Kran                                       **
  **************************************************************************/
  if (pDDC->usDCType == OD_MEMORY)
  {
    ULONG ulDevSetAttr = 0;
    ULONG ulDefSet = 0;

    if (BType == PRIM_CHAR && AttrsMask & CBB_SET)
    {
       AttrsMask &= ~CBB_SET;
       ulDevSetAttr = CBB_SET;
    }
    else if (BType == PRIM_MARKER && AttrsMask & MBB_SET)
    {
       AttrsMask &= ~MBB_SET;
       ulDevSetAttr = MBB_SET;
    }
    else if (BType == PRIM_AREA && AttrsMask & ABB_SET)
    {
       ulDefSet = ((PDAREABUNDLE)pAttrs)->adef.defSet;

      /*
      ** Check if the defSet is handle to a bitmap.
      ** I hate to do this kind of hardcoded values!
      */
       if (ulDefSet >> 16 == 0x0400)
       {
          ULONG ulDevHandle;

          ulDevHandle = GetDriverInfo( (HBITMAP) ulDefSet, 1L, pDDC->hdcMemory );

          if (ulDevHandle != GPI_ALTERROR)
          {
            ((PDAREABUNDLE) pAttrs)->adef.defSet = ulDevHandle;
            AttrsMask &= ~ABB_SET;
            ulDevSetAttr = ABB_SET;
          }
          else
          {
            ulDefSet = 0;
          }
       }
       else
       {
          ulDefSet = 0;
       }
    }

    lStatus = InnerGreSetAttributes (pDDC->hdcMemory, BType, DefsMask,
                                     AttrsMask, (PBYTE) ((ULONG) pAttrs +
                                     sizeof (((PDLINEBUNDLE)pAttrs)->cAttr) +
                                     sizeof (((PDLINEBUNDLE)pAttrs)->cDefs)),
                                     FunN );

    if (lStatus && ulDevSetAttr)
    {
       lStatus = InnerGreDeviceSetAttributes( pDDC->hdcMemory, BType,
                                             DefsMask,
                                             ulDevSetAttr,
                                             pAttrs, FunN );
       if (ulDefSet)
       {
          ((PDAREABUNDLE) pAttrs)->adef.defSet = ulDefSet ;
       }
    }
    LeaveDriver( pDDC );
    return( lStatus );
  }

  /*
  ** If we are running on the new engine
  ** we must inform the gre the attributes are changing
  **/
  if (pDDC->lEngineVersion >= RASTER_ENGINE_22)
  {
     (*daDeviceSetAttributes)(hDC, BType, DefsMask, AttrsMask,
                           pAttrs, pDDC, FunN);
  }

  switch (LOUSHORT(BType))
  {
    case  PRIM_LINE :
      Result = (LONG)set_line_attr_bundle(hDC, pDDC, DefsMask, AttrsMask,
                                          (PDLINEBUNDLE)pAttrs, FunN);
      break;
    case  PRIM_CHAR :
      Result = (LONG)set_char_attr_bundle(pDDC, DefsMask, AttrsMask,
                                          (PDCHARBUNDLE)pAttrs);
      break;
    case  PRIM_MARKER :
      Result = (LONG)set_marker_attr_bundle(pDDC, DefsMask, AttrsMask,
                                            (PDMARKERBUNDLE)pAttrs);
      break;
    case  PRIM_AREA :
      Result = (LONG)set_area_attr_bundle(pDDC, DefsMask, AttrsMask,
                                          (PDAREABUNDLE)pAttrs);
      break;
    case  PRIM_IMAGE :
      Result = (LONG)set_image_attr_bundle(pDDC, DefsMask, AttrsMask,
                                           (PDIMAGEBUNDLE)pAttrs);
      break;
  }
  LeaveDriver(pDDC);
  return (Result);
}

/***********************************************************************
 *
 * FUNCTION NAME = DeviceSetDCOrigin()
 *
 * DESCRIPTION   = Set DC Origin
 *
 *                 Sets the DC origin.  Note that the device origin
 *                 is 0,0 when enabled.  The device is responsible
 *                 for adding this offset to all transformed
 *                 coordinates.  The plotter driver returns error
 *                 because SetDCOrigin is not journaled, and would
 *                 cause problems in color-sorting mode.
 *
 *
 *
 *
 * INPUT         = hDC,pXY,pDDC,FunN
 *
 * OUTPUT        = NONE
 *
 *
 *
 *
 * RETURN-NORMAL = OL
 * RETURN-ERROR  =
 *
 *
 *
 ****************************************************************************/

LONG  DeviceSetDCOrigin(HDC hDC,PPOINTL pXY,PDDC pDDC,ULONG FunN)
{
  GplErrSetError(PMERR_DEV_FUNC_NOT_INSTALLED);
  return (0L);
}

/***********************************************************************
 *
 * FUNCTION NAME = DeviceSetGlobalAttribute()
 *
 *
 * DESCRIPTION   = Set global attributes
 *
 *                 Sets the global attributes of different types of
 *                 attributes
 *
 *
 * INPUT         = hDC,AttributeType,Attribute,Options,pDDC,FunN
 *
 * OUTPUT        = NONE
 *
 *
 *
 * RETURN-NORMAL = SUCCESS
 *                     IL
 *
 * RETURN-ERROR  = FAILURE
 *                     OL
 *
 *
 *
 ****************************************************************************/

LONG APIENTRY DeviceSetGlobalAttribute(HDC hDC,ULONG AttributeType,ULONG
                                          Attribute,ULONG Options,PDDC pDDC,
                                          ULONG FunN)
{
  LONG Result = 1L;

  if (!EnterDriver(pDDC))
      return(GPI_ERROR);

  /*
  **          In case of MEMORYDC Dispatch to Graphics Engine
  */
  if (pDDC->usDCType == OD_MEMORY)
  {
    Result = InnerGreSetGlobalAttribute( pDDC->hdcMemory,AttributeType,
                                        Attribute, Options, FunN );
    LeaveDriver( pDDC );
    return( 1L );
  }

  /*
  ** If we are running on the new engine
  ** we must inform the GRE the attributes are changing.
  **/
  if (pDDC->lEngineVersion >= RASTER_ENGINE_22)
  {
     (*daDeviceSetGlobalAttribute)(hDC, AttributeType, Attribute, Options,
                                   pDDC, FunN);
  }

  switch (LOUSHORT(AttributeType))
  {
    case  ATYPE_COLOR :
      if (Options & GATTR_DEFAULT)
        pDDC->DCState.lbnd.lColor =
        pDDC->DCState.dcbnd.cbnd.lColor =
           pDDC->DCState.mbnd.lColor =
           pDDC->DCState.abnd.lColor =
           pDDC->DCState.ibnd.lColor =
              (pDDC->DCState.usColorFormat != LCOLF_RGB) ?
                 CLR_BLACK : COLOR_BLACK;
      else
        if (validate_foreground_color(pDDC, Attribute))
          pDDC->DCState.lbnd.lColor = pDDC->DCState.dcbnd.cbnd.lColor =
             pDDC->DCState.mbnd.lColor = pDDC->DCState.abnd.lColor =
             pDDC->DCState.ibnd.lColor = Attribute;
        else
          Result = 0L;
      break;

    case  ATYPE_BACK_COLOR :
      if (Options & GATTR_DEFAULT)
        pDDC->DCState.dcbnd.cbnd.lBackColor = pDDC->DCState.mbnd.lBackColor =
           pDDC->DCState.abnd.lBackColor = pDDC->DCState.ibnd.lBackColor =
           (pDDC->DCState.usColorFormat != LCOLF_RGB)?CLR_WHITE:COLOR_WHITE;
      else
        if (validate_background_color(pDDC, Attribute))
          pDDC->DCState.dcbnd.cbnd.lBackColor = pDDC->DCState.mbnd.lBackColor
             = pDDC->DCState.abnd.lBackColor = pDDC->DCState.ibnd.lBackColor =
             Attribute;
        else
          Result = 0L;
      break;

    case  ATYPE_MIX_MODE :
      if (Options & GATTR_DEFAULT)
        pDDC->DCState.lbnd.usMixMode = pDDC->DCState.dcbnd.cbnd.usMixMode =
           pDDC->DCState.mbnd.usMixMode = pDDC->DCState.abnd.usMixMode =
           pDDC->DCState.ibnd.usMixMode = FM_DEFAULT;
      else
        if (validate_foreground_mix((USHORT)Attribute))
          pDDC->DCState.lbnd.usMixMode = pDDC->DCState.dcbnd.cbnd.usMixMode =
             pDDC->DCState.mbnd.usMixMode = pDDC->DCState.abnd.usMixMode =
             pDDC->DCState.ibnd.usMixMode = (USHORT)Attribute;
        else
          Result = 0L;
      break;

    case  ATYPE_BACK_MIX_MODE :
      if (Options & GATTR_DEFAULT)
        pDDC->DCState.dcbnd.cbnd.usBackMixMode =
           pDDC->DCState.mbnd.usBackMixMode = pDDC->DCState.abnd.usBackMixMode
           = pDDC->DCState.ibnd.usBackMixMode = BM_DEFAULT;
      else
        if (validate_background_mix((USHORT)Attribute))
          pDDC->DCState.dcbnd.cbnd.usBackMixMode =
             pDDC->DCState.mbnd.usBackMixMode =
             pDDC->DCState.abnd.usBackMixMode =
             pDDC->DCState.ibnd.usBackMixMode = (USHORT)Attribute;
        else
          Result = 0L;
      break;

    default  :
      Result = 0L;
      break;
  }
  LeaveDriver(pDDC);
  return (Result);
}
#if 0
X/***********************************************************************
X *
X * FUNCTION NAME = SetDefaultAttributes()
X *
X *
X * DESCRIPTION   = Set Default attributes
X *
X *                 Sets the Default attributes of different types of
X *                 attributes
X *
X *
X * INPUT         = hDC,lPrimType,fulAttrMask,pBundle,pDDC,FunN
X *
X * OUTPUT        = NONE
X *
X *
X *
X * RETURN-NORMAL = SUCCESS
X *                     TRUE
X *
X * RETURN-ERROR  = FAILURE
X *                     FALSE
X *
X *
X *
X ****************************************************************************/
X
XBOOL APIENTRY SetDefaultAttributes(HDC hDC,LONG lPrimType,ULONG fulAttrMask,
X                                   PBUNDLE pBundle, PDDC pDDC,ULONG FunN)
X{
X  LONG Result = TRUE;
X
X  if (!EnterDriver(pDDC))
X      return(GPI_ERROR);
X
X  /*
X  ** If we are running on the new engine
X  ** we must inform the GRE the attributes are changing.
X  **/
X  if (pDDC->lEngineVersion >= RASTER_ENGINE_22)
X  {
X     (*daSetDefaultAttributes)(hDC, AttributeType, Attribute, Options,
X                                pDDC, FunN);
X  }
X
X  switch (LOUSHORT(lPrimType))
X  {
X    case  PRIM_LINE :
X    case  PRIM_CHAR :
X    case  PRIM_MARKER :
X    case  PRIM_AREA :
X    case  PRIM_IMAGE :
X    default:
X  }
X
X  LeaveDriver(pDDC);
X  return (Result);
X}
#endif

/***********************************************************************
 *
 * FUNCTION NAME =   ErasePS()
 *
 * DESCRIPTION   = This function resets the presentation space.
 *
 *
 *
 * INPUT         = hDC,pDDC,FunN
 *
 * OUTPUT        = NONE
 *
 *
 *
 * RETURN-NORMAL = SUCCESS
 *                     1L
 *
 * RETURN-ERROR  = FAILURE
 *                     0L
 *
 *
 *
 *
 ****************************************************************************/

LONG  ErasePS(HDC hDC,PDDC pDDC,ULONG FunN)
{
  ULONG ulRet;

  if (!EnterDriver(pDDC))
      return(GPI_ERROR);

  /*
  **          In case of MEMORYDC Dispatch to Graphics Engine
  */
  if (pDDC->usDCType == OD_MEMORY)
  {
    ulRet = InnerGreErasePS (pDDC->hdcMemory, FunN);
  }
  else
    ulRet = (FunN & COM_PATH)?0L:1L;
  LeaveDriver( pDDC );
  return (ulRet);
}

/***********************************************************************
 *
 * FUNCTION NAME = GetDCOrigin()
 *
 * DESCRIPTION   = Get Device Context origin
 *
 *                 Assigns values to the coordinates
 *
 *
 *
 * INPUT         = hDC,pXY,pDDC,FunN
 *
 * OUTPUT        =
 *
 *
 * RETURN-NORMAL = SUCCESS
 *                     TRUE
 *
 * RETURN-ERROR  =
 *
 *
 *
 ****************************************************************************/

BOOL  GetDCOrigin(HDC hDC,PPOINTL pXY,PDDC pDDC,ULONG FunN)
{
  if (!EnterDriver(pDDC))
      return(GPI_ERROR);
  pXY->x = pXY->y = 0L;
  LeaveDriver(pDDC);
  return (1);
}

/***********************************************************************
 *
 * FUNCTION NAME = GetStyleRatio()
 *
 * DESCRIPTION   = Get Style Ratio
 *
 *                 This function is used for banding printers which use the
 *                 display driver for writing into bitmaps.
 *
 *                 The plotter returns 1:1
 *
 *
 *
 *
 *
 * INPUT         = hDC,pRatio,pDDC,FunN
 *
 * OUTPUT        = NONE
 *
 *
 *
 * RETURN-NORMAL = SUCCESS
 *                     1L
 *
 * RETURN-ERROR  = NONE
 *
 *
 *
 *
 ****************************************************************************/

LONG  GetStyleRatio(HDC hDC,PBYTE pRatio,PDDC pDDC,ULONG FunN)
{
  ULONG ulRet;

  if (!EnterDriver(pDDC))
      return(GPI_ERROR);

  /*
  **          In case of MEMORYDC Dispatch to Graphics Engine
  */
  if (pDDC->usDCType == OD_MEMORY)
  {
    ulRet = InnerGreGetStyleRatio (pDDC->hdcMemory, pRatio, FunN);
    LeaveDriver( pDDC );
    return( ulRet );
  }
  pRatio[0] = pRatio[1] = 0x01;
  LeaveDriver(pDDC);
  return (1L);
}

/***********************************************************************
 *
 * FUNCTION NAME = LockDevice()
 *
 * DESCRIPTION   = This function locks a device
 *
 *
 *
 * INPUT         = hDC,pDDC,Fun
 *
 * OUTPUT        =
 *
 *
 *
 *
 * RETURN-NORMAL = SUCCESS
 *                     1L
 *
 * RETURN-ERROR  = NONE
 *
 *
 *
 *
 ****************************************************************************/

LONG  LockDevice(HDC hDC,PDDC pDDC,ULONG FunN)
{
  ULONG ulRet;

  if (!EnterDriver(pDDC))
      return(GPI_ERROR);

  /*
  **          In case of MEMORYDC Dispatch to Graphics Engine
  */
  if (pDDC->usDCType == OD_MEMORY)
  {
    ulRet = InnerGreLockDevice (pDDC->hdcMemory, FunN);
    LeaveDriver( pDDC );
    return( ulRet );
  }
  LeaveDriver(pDDC);
  return (1L);
}

/***********************************************************************
 *
 * FUNCTION NAME = SetStyleRatio()
 *
 * DESCRIPTION   = Set Style Ratio
 *
 *
 *
 * INPUT         = hDC,pRatio,pDDC,FunN
 *
 * OUTPUT        = NONE
 *
 *
 *
 * RETURN-NORMAL = SUCCESS
 *                     0L
 *
 * RETURN-ERROR  = NONE
 *
 *
 *
 *
 ****************************************************************************/

LONG  SetStyleRatio(HDC hDC,PBYTE pRatio,PDDC pDDC,ULONG FunN)
{
  GplErrSetError(PMERR_DEV_FUNC_NOT_INSTALLED);
  return (0L);
}

/***********************************************************************
 *
 * FUNCTION NAME = UnlockDevice()
 *
 * DESCRIPTION   = Allows all pending screen input or output operations
 *                 blocked by LockDevice() to continue
 *
 *
 *
 * INPUT         = hDC,pDDC,FunN
 *
 * OUTPUT        = NONE
 *
 *
 *
 * RETURN-NORMAL = SUCCESS
 *                     1L
 *
 * RETURN-ERROR  = NONE
 *
 *
 *
 *
 ****************************************************************************/

LONG  UnlockDevice(HDC hDC,PDDC pDDC,ULONG FunN)
{
  ULONG ulRet;

  if (!EnterDriver(pDDC))
      return(GPI_ERROR);

  /*
  **          In case of MEMORYDC Dispatch to Graphics Engine
  */
  if (pDDC->usDCType == OD_MEMORY)
    ulRet = InnerGreUnlockDevice (pDDC->hdcMemory, FunN);
  else
    ulRet = 1L;
  LeaveDriver(pDDC);
  return (ulRet);
}

