/*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 = PRDTXFRM
 *
 * DESCRIPTIVE NAME =
 *
 *
 * VERSION
 *
 * DATE
 *
 * DESCRIPTION
 *
 * FUNCTIONS   prdt_ScaleXMetricToDevice
 *             prdt_ScaleYMetricToDevice
 *             prdt_XformFontValue
 *             prdt_GetBoundingRect
 *             prdt_RescaleCharBox
 *
 * ENTRY POINTS:
 *
 * DEPENDENCIES:
 *
 * NOTES
 *
 *
 * STRUCTURES
 *
 * EXTERNAL REFERENCES
 *
 * EXTERNAL FUNCTIONS
 *
*/
#define INCL_32                        /* CON3201 */
#define INCL_DOSPROCESS                /* CON3201 */
#define INCL_DOSSEMAPHORES
#define INCL_GPIPRIMITIVES
#define INCL_WINHEAP
#define INCL_GPIBITMAPS
#include <os2.h>
#undef INCL_DOSPROCESS                 /* CON3201 */
#undef INCL_DOSSEMAPHORES
#undef INCL_GPIPRIMITIVES
#undef INCL_WINHEAP
#undef INCL_GPIBITMAPS

#define INCL_DDICOMFLAGS
#define INCL_DDIBUNDLES
#define INCL_DDIFONTSTRUCS
#define INCL_DDIDEFS
#define INCL_DDIMISC
#define INCL_GRE_XFORMS
#include <pmddi.h>
#undef INCL_DDICOMFLAGS
#undef INCL_DDIBUNDLES
#undef INCL_DDIFONTSTRUCS
#undef INCL_DDIDEFS
#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
#undef INCL_32                               /* CON3201 */

#include <prdtcone.h>
#include <prdinclt.h>
#include <prdtextf.h>
#include <prduextf.h>
#include <prdgextf.h>
#include <prdacone.h>

/******************************************************************************/
/*  FUNCTION: prdt_ScaleXMetricToDevice                                       */
/*                                                                            */
/*  PARAMETERS:                                                               */
/*                                                                            */
/*  lpDCI           DCIData                                                   */
/*  lpFontDataType  pFontData                                                 */
/*  LONG            XValue                                                    */
/*                                                                            */
/*  DESCRIPTION:                                                              */
/*                                                                            */
/*  This function scales the X metric value passed in to the char box and     */
/*  converts to device coordinates and returns the new value                  */
/******************************************************************************/
/*CON3201
ULONG prdt_ScaleXMetricToDevice(DCIData, pFontData, XValue)

lpDCI           DCIData;
lpFontDataType  pFontData;
LONG            XValue;
*/

ULONG prdt_ScaleXMetricToDevice(lpDCI           DCIData,
                                lpFontDataType  pFontData,
                                LONG            XValue)

{

    /**************************************************************************/
    /*  Local Variables.                                                      */
    /**************************************************************************/
    ULONG           Result;
    POINTL          point;
    XFORM           Transform;
    POINTL          CharBox;                        /* PD00534                */
    USHORT          fsXform;                        /* PD00534                */
    BYTE            DfltFontRealized;               /* PD00681                */

    /**************************************************************************/
    /* IF a font has not been realized and the default font is an outline     */
    /* font and user has selected a pointsize (PDBInstance->DfltFontPointSz   */
    /* != 0), then set the char box to the pointsize. Otherwise just pick     */
    /* the char box up from the text attributes.                              */
    /**************************************************************************/
    /**************************************************************************/
    /* PD00681 : Get the lcid attrs to see if default font is realized.       */
    /**************************************************************************/
    DfltFontRealized =  prdm_GetLCIDEngineAttrs(pFontData->Info.LCID) &
                                                            FATTR_SEL_DEFAULT ;
    if ( (DCIData->DCICurTxtAts->cdef.defSet == 0 || DfltFontRealized ) &&
         (DCIData->DCIPdbInstance->DfltFontPointSz) )
    {
        /**********************************************************************/
        /* Get width of char box in device coords.                            */
        /**********************************************************************/
        /**********************************************************************/
        /* PD00534 : Added code to convert char box from device to world      */
        /* coords and then scale the char width to the char box.              */
        /**********************************************************************/
        CharBox.x = prdg_ScaleValue(
                     (LONG)DCIData->DCIPdbInstance->DfltFontPointSz,
                     (LONG)DCIData->DCIPdbInstance->DDT.DDTRasterMode->ResWidth,
                     72L) << 16;
        CharBox.y = 0;

        /**********************************************************************/
        /* Convert CharBox.x from device to world coords.                     */
        /* Get Device->World transform matrix.                                */
        /**********************************************************************/
        fsXform = DEVICE_TO_WORLD | IGNORE_ORIGIN_SHIFT;

        if ( prdg_GetXformMatrix( (HDC)DCIData->DcH, fsXform,
                                  (PXFORM)&Transform, DCIData ) != OK )
            return (ERROR_ZERO);

        /**********************************************************************/
        /* Use prdg_XformPoint to convert this vector to a length in world    */
        /* coordinates.                                                       */
        /**********************************************************************/
        CharBox.x = prdg_XformPoint( (HDC)DCIData->DcH, (PPOINTL)&CharBox,
                                     (PXFORM)&Transform );

    }
    else
    {
        /**********************************************************************/
        /* Pickup character box (world coords) from current text attributes   */
        /**********************************************************************/
        CharBox.x=abs((LONG)(DCIData->DCICurTxtAts->cbnd.sizfxCell.cx));
    }

    /**************************************************************************/
    /* PD00534 : Restructured code to always scale the char width to the      */
    /* char box and convert the returned char width to device coords.         */
    /*                                                                        */
    /* Scale the char width to the char box in world coordinates.             */
    /**************************************************************************/
    XValue = prdg_ScaleValue(XValue, (LONG)CharBox.x,
                             (LONG)pFontData->pMetrics->xEmInc << 16 );

    /**************************************************************************/
    /* Convert to device coordinates.  Just want the scaling factor, not a    */
    /* full transform, which may rotate/translate the width.                  */
    /**************************************************************************/
    Transform = DCIData->DCITransform;

    /**************************************************************************/
    /* Use prdg_XformPoint - as this performs the square root function, and   */
    /* also converts from FIXED to LONG.                                      */
    /**************************************************************************/
    point.x = XValue;
    point.y = 0;

    Result = prdg_XformPoint( (HDC)DCIData->DcH, &point, &Transform );
    return (Result);

}


/******************************************************************************/
/*  FUNCTION: prdt_ScaleYMetricToDevice                                       */
/*                                                                            */
/*  PARAMETERS:                                                               */
/*                                                                            */
/*  lpDCI           DCIData                                                   */
/*  lpFontDataType  pFontData                                                 */
/*  LONG            YValue                                                    */
/*                                                                            */
/*  DESCRIPTION:                                                              */
/*  This function scales the Y metric value passed in, to the char box and    */
/*  converts to device coordinates and returns the new value                  */
/*                                                                            */
/******************************************************************************/
/*CON3201
ULONG prdt_ScaleYMetricToDevice(DCIData, pFontData, YValue)

lpDCI           DCIData;
lpFontDataType  pFontData;
LONG            YValue;
*/

ULONG prdt_ScaleYMetricToDevice(lpDCI           DCIData,
                                lpFontDataType  pFontData,
                                LONG            YValue)

{

    /**************************************************************************/
    /*  Local Variables.                                                      */
    /**************************************************************************/
    ULONG            Result;
    POINTL           point;
    XFORM            Transform;
    POINTL           CharBox;
    USHORT           fsXform;                        /* PD00534               */
    BYTE             DfltFontRealized;               /* PD00681                */

    /**************************************************************************/
    /* IF a font has not been realized and the default font is an outline     */
    /* font and user has selected a pointsize (PDBInstance->DfltFontPointSz   */
    /* != 0), then set the char box to the pointsize. Otherwise just pick     */
    /* the char box up from the text attributes.                              */
    /**************************************************************************/
    /**************************************************************************/
    /* PD00681 : Get the lcid attrs to see if default font is realized.       */
    /**************************************************************************/
    DfltFontRealized =  prdm_GetLCIDEngineAttrs(pFontData->Info.LCID) &
                                                            FATTR_SEL_DEFAULT ;
    if ( (DCIData->DCICurTxtAts->cdef.defSet == 0 || DfltFontRealized ) &&
         (DCIData->DCIPdbInstance->DfltFontPointSz) )
    {
        /**********************************************************************/
        /* PD00534 : Added code to convert char box from device to world      */
        /* coords and then scale the char width to the char box.              */
        /**********************************************************************/
        CharBox.y = prdg_ScaleValue(
                     (LONG)DCIData->DCIPdbInstance->DfltFontPointSz,
                     (LONG)DCIData->DCIPdbInstance->DDT.DDTRasterMode->ResWidth,
                     72L) << 16;
        CharBox.x = 0;

        /**********************************************************************/
        /* Convert CharBox.x from device to world coords.                     */
        /* Get Device->World transform matrix.                                */
        /**********************************************************************/
        fsXform = DEVICE_TO_WORLD | IGNORE_ORIGIN_SHIFT;

        if ( prdg_GetXformMatrix( (HDC)DCIData->DcH, fsXform,
                                  (PXFORM)&Transform, DCIData ) != OK )
            return (ERROR_ZERO);

        /**********************************************************************/
        /* Use prdg_XformPoint to convert this vector to a length in world    */
        /* coordinates.                                                       */
        /**********************************************************************/
        CharBox.y = prdg_XformPoint( (HDC)DCIData->DcH, (PPOINTL)&CharBox,
                                     (PXFORM)&Transform );

    }
    else
    {
        CharBox.y = abs((LONG)(DCIData->DCICurTxtAts->cbnd.sizfxCell.cy));
    }

    /**************************************************************************/
    /* Scale the width to the character box.                                  */
    /**************************************************************************/
    YValue = prdg_ScaleValue(
                             YValue,
                             (LONG)CharBox.y,
                             (LONG)pFontData->pMetrics->yEmHeight << 16 );

    /**************************************************************************/
    /* Convert to device coordinates.  Just want the scaling factor, not a    */
    /* full transform, which may rotate/translate the width.                  */
    /**************************************************************************/
    Transform = DCIData->DCITransform;

    /**************************************************************************/
    /* Use prdg_XformPoint - as this performs the square root function, and   */
    /* also converts from FIXED to LONG.                                      */
    /**************************************************************************/
    point.x = 0;
    point.y = YValue;

    Result = prdg_XformPoint( (HDC)DCIData->DcH, &point, &Transform );

    return (Result);

}


/******************************************************************************/
/*  FUNCTION: prdt_RescaleCharBox                                             */
/*                                                                            */
/*  PARAMETERS:                                                               */
/*                                                                            */
/*  lpDCI           DCIData;                                                  */
/*  XFORM           OldXform                                                  */
/*  XFORM           NewXform                                                  */
/*                                                                            */
/*  DESCRIPTION:                                                              */
/*                                                                            */
/* This function rescales the charbox to the new xform matrix                 */
/* passed in.                                                                 */
/*                                                                            */
/******************************************************************************/
/*
VOID prdt_RescaleCharBox( DCIData, OldXform, NewXform )

lpDCI   DCIData;
XFORM   OldXform;
XFORM   NewXform;
*/

VOID prdt_RescaleCharBox(lpDCI   DCIData,
                         XFORM   OldXform,
                         XFORM   NewXform)

{
    /**************************************************************************/
    /*  Local Variables.                                                      */
    /**************************************************************************/
    PDCHARBUNDLE    CurTxtAts;
    FIXED           Xo, Yo;
    FIXED           fxMx, fxMy, fxNx, fxNy;
    POINTL          fxM;

    CurTxtAts = DCIData->DCICurTxtAts;
    /**************************************************************************/
    /* Get the cell size                                                      */
    /**************************************************************************/
    Xo = CurTxtAts->cbnd.sizfxCell.cx;
    Yo = CurTxtAts->cbnd.sizfxCell.cy;

    /**************************************************************************/
    /* Calculate the original scaling factors.  Note that values are FIXED    */
    /* type.                                                                  */
    /**************************************************************************/
    fxM.x = (LONG)OldXform.fxM11;
    fxM.y = (LONG)OldXform.fxM12;
    fxMx = (FIXED)far_get_vector_length( &fxM );

    fxM.x = (LONG)OldXform.fxM21;
    fxM.y = (LONG)OldXform.fxM22;
    fxMy = (FIXED)far_get_vector_length( &fxM );


    /**************************************************************************/
    /* Calculate the new scaling factors.  (FIXED)                            */
    /**************************************************************************/
    fxM.x = (LONG)NewXform.fxM11;
    fxM.y = (LONG)NewXform.fxM12;
    fxNx = (FIXED)far_get_vector_length( &fxM );

    fxM.x = (LONG)NewXform.fxM21;
    fxM.y = (LONG)NewXform.fxM22;
    fxNy = (FIXED)far_get_vector_length( &fxM );


    /**************************************************************************/
    /* Finally, rescale the Character Box.                                    */
    /*                                                                        */
    /* Note: use prdg_ScaleValue to allow for overflow in multiplication.     */
    /**************************************************************************/
    CurTxtAts->cbnd.sizfxCell.cx = prdg_ScaleValue( Xo, fxMx, fxNx );
    CurTxtAts->cbnd.sizfxCell.cy = prdg_ScaleValue( Yo, fxMy, fxNy );

    return;
}


/******************************************************************************/
/*  FUNCTION: prdt_XformFontValue                                             */
/*                                                                            */
/*  PARAMETERS:                                                               */
/*                                                                            */
/*  USHORT          Value;                                                    */
/*  USHORT          fsXform;    Conversion flags                              */
/*  lpFontDataType  pFontData;                                                */
/*                                                                            */
/*  DESCRIPTION:                                                              */
/*                                                                            */
/*  Scales a value between font and device coords depending on given flags.   */
/*  Note that the Xform flags defaults to a xform of an x-value from Device to*/
/*  Font coords.                                                              */
/*                                                                            */
/*  ASSUMPTIONS:                                                              */
/*                                                                            */
/*  The function is called with either CONV_X_VALUE or CONV_Y_VALUE set and   */
/*  with either FONT_TO_DEVICE or DEVICE_TO_FONT set in the conversion flags. */
/******************************************************************************/
/*CON3201
USHORT prdt_XformFontValue(Value, fsXform, pFontData)

USHORT          Value;
USHORT          fsXform;
lpFontDataType  pFontData;
*/

USHORT prdt_XformFontValue(USHORT          Value,
                           USHORT          fsXform,
                           lpFontDataType  pFontData)

{

    /**************************************************************************/
    /*  Local variables                                                       */
    /**************************************************************************/
    ULONG         Multiplier;
    ULONG         Divisor;
    lpResAdjType  pResAdj;

    /**************************************************************************/
    /*  Set up scaling factors according to flags.                            */
    /**************************************************************************/
    pResAdj = &pFontData->ResAdj;
    if ((fsXform & (FONT_TO_DEVICE | CONV_Y_VALUE)) == (FONT_TO_DEVICE |
                                                        CONV_Y_VALUE))
    {
        Multiplier = pResAdj->DeviceResY;
        Divisor    = pResAdj->FontResY;
    }
    else if ((fsXform & (DEVICE_TO_FONT | CONV_Y_VALUE)) == (DEVICE_TO_FONT |
                                                             CONV_Y_VALUE))
    {
        Multiplier = pResAdj->FontResY;
        Divisor    = pResAdj->DeviceResY;
    }
    else if ((fsXform & (FONT_TO_DEVICE | CONV_X_VALUE)) == (FONT_TO_DEVICE |
                                                             CONV_X_VALUE))
    {
        Multiplier = pResAdj->DeviceResX;
        Divisor    = pResAdj->FontResX;
    }
    else
    {
        Multiplier = pResAdj->FontResX;
        Divisor    = pResAdj->DeviceResX;
    }
    return((USHORT)prdg_ScaleValue((ULONG)Value, Multiplier, Divisor));
}
