Annotation of ntddk/src/print/pscript/escape.c, revision 1.1.1.1

1.1       root        1: //--------------------------------------------------------------------------
                      2: //
                      3: // Module Name:  ESCAPE.C
                      4: //
                      5: // Brief Description:  This module contains the PSCRIPT driver's Escape
                      6: // functions and related routines.
                      7: //
                      8: // Author:  Kent Settle (kentse)
                      9: // Created: 08-Feb-1991
                     10: //
                     11: // Copyright (c) 1991 - 1992 Microsoft Corporation
                     12: //
                     13: // This routine contains routines to handle the various Escape functions.
                     14: //--------------------------------------------------------------------------
                     15: 
                     16: #include "pscript.h"
                     17: #include "enable.h"
                     18: 
                     19: // DrawEscape to output encapsulated PostScript data.
                     20: 
                     21: typedef struct tagEPSDATA
                     22: {
                     23:     DWORD    cbData;        // Size of the structure and EPS data in bytes.
                     24:     DWORD    nVersion;      // Language level, e.g. 1 for level 1 PostScript.
                     25:     POINTL   aptl[3];       // Output parallelogram in 28.4 FIX device coords.
                     26:                             // This is followed by the EPS data.
                     27: } EPSDATA, *PEPSDATA;
                     28: 
                     29: FLOAT FixToFloat(FIX);
                     30: BOOL  bDoEpsXform(PDEVDATA, PEPSDATA);
                     31: extern BOOL bDoClipObj(PDEVDATA, CLIPOBJ *, RECTL *, RECTL *, BOOL *, BOOL *, DWORD);
                     32: 
                     33: #define ESC_NOT_SUPPORTED   0xFFFFFFFF
                     34: #define ESC_IS_SUPPORTED    0x00000001
                     35: 
                     36: //--------------------------------------------------------------------------
                     37: // ULONG DrvEscape (pso, iEsc, cjIn, pvIn, cjOut, pvOut)
                     38: // SURFOBJ    *pso;
                     39: // ULONG       iEsc;
                     40: // ULONG       cjIn;
                     41: // PVOID       pvIn;
                     42: // ULONG       cjOut;
                     43: // PVOID       pvOut;
                     44: //
                     45: // This entry point serves more than one function call.  The particular
                     46: // function depends on the value of the iEsc parameter.
                     47: //
                     48: // In general, the DrvEscape functions will be device specific functions
                     49: // that don't belong in a device independent DDI.  This entry point is
                     50: // optional for all devices.
                     51: //
                     52: // Parameters:
                     53: //   pso
                     54: //     Identifies the surface that the call is directed to.
                     55: //
                     56: //   iEsc
                     57: //     Specifies the particular function to be performed.  The meaning of
                     58: //     the remaining arguments depends on this parameter.  Allowed values
                     59: //     are as follows.
                     60: //
                     61: //     ESC_QUERYESCSUPPORT
                     62: //     Asks if the driver supports a particular escape function.  The
                     63: //     escape function number is a ULONG pointed to by pvIn.    A non-zero
                     64: //     value should be returned if the function is supported.    cjIn has a
                     65: //     value of 4.  The arguments cjOut and pvOut are ignored.
                     66: //
                     67: //     ESC_PASSTHROUGH
                     68: //     Passes raw device data to the device driver.  The number of BYTEs of
                     69: //     raw data is indicated by cjIn.    The data is pointed to by pvIn.    The
                     70: //     arguments cjOut and pvOut are ignored.    Returns the number of BYTEs
                     71: //     written if the function is successful.  Otherwise, it returns zero
                     72: //     and logs an error code.
                     73: //   cjIn
                     74: //     The size, in BYTEs, of the data buffer pointed to by pvIn.
                     75: //
                     76: //   pvIn
                     77: //     The input data for the call.  The format of the input data depends
                     78: //     on the function specified by iEsc.
                     79: //
                     80: //   cjOut
                     81: //     The size, in BYTEs, of the output data buffer pointed to by pvOut.
                     82: //     The driver must never write more than this many BYTEs to the output
                     83: //     buffer.
                     84: //
                     85: //   pvOut
                     86: //     The output buffer for the call.    The format of the output data depends
                     87: //     on the function specified by iEsc.
                     88: //
                     89: // Returns:
                     90: //   Depends on the function specified by iEsc.    In general, the driver should
                     91: //   return 0xFFFFFFFF if an unsupported function is called.
                     92: //
                     93: // History:
                     94: //   02-Feb-1991     -by-     Kent Settle     (kentse)
                     95: //  Wrote it.
                     96: //--------------------------------------------------------------------------
                     97: 
                     98: ULONG DrvEscape (pso, iEsc, cjIn, pvIn, cjOut, pvOut)
                     99: SURFOBJ    *pso;
                    100: ULONG       iEsc;
                    101: ULONG       cjIn;
                    102: PVOID       pvIn;
                    103: ULONG       cjOut;
                    104: PVOID       pvOut;
                    105: {
                    106:     PDEVDATA    pdev;
                    107:     DWORD       cWritten;
                    108:     FLOAT       *pfloat;
                    109:     LONG        ytmp;
                    110:     ULONG       ulRet = ESC_NOT_SUPPORTED;
                    111: 
                    112:     // handle each case depending on which escape function is being asked for.
                    113: 
                    114:     switch (iEsc)
                    115:     {
                    116:         case QUERYESCSUPPORT:
                    117:             // when querying escape support, the function in question is
                    118:             // passed in the ULONG passed in pvIn.
                    119: 
                    120:             switch (*(PULONG)pvIn)
                    121:             {
                    122:                 case QUERYESCSUPPORT:
                    123:                 case PASSTHROUGH:
                    124:                 case POSTSCRIPT_PASSTHROUGH:
                    125:                 case GETDEVICEUNITS:
                    126:                     return(ESC_IS_SUPPORTED);
                    127: 
                    128:                 case SETCOPYCOUNT:
                    129:                     return(MAX_COPIES);
                    130: 
                    131:                 default:
                    132:                     // return 0 if the escape in question is not supported.
                    133: 
                    134:                    return(0);
                    135:             }
                    136: 
                    137:         case POSTSCRIPT_PASSTHROUGH:
                    138:         case PASSTHROUGH:
                    139:             // get the pointer to our DEVDATA structure and make sure it is ours.
                    140: 
                    141:             pdev = (PDEVDATA) pso->dhpdev;
                    142: 
                    143:             if (bValidatePDEV(pdev) == FALSE)
                    144:             {
                    145:                 RIP("PSCRIPT!DrvEscape: invalid pdev.\n");
                    146:                 SetLastError(ERROR_INVALID_PARAMETER);
                    147:                 ulRet = 0;
                    148:                 break;
                    149:             }
                    150: 
                    151:             // do nothing if the document has been cancelled.
                    152: 
                    153:             if (pdev->dwFlags & PDEV_CANCELDOC)
                    154:                 return(*(LPWORD)pvIn);
                    155: 
                    156:             if (iEsc == POSTSCRIPT_PASSTHROUGH)
                    157:             {
                    158:                 // initialize the current graphics state.
                    159: 
                    160:                 init_cgs(pdev);
                    161: 
                    162:                 if (pdev->dwFlags & PDEV_WITHINPAGE)
                    163:                 {
                    164:                     ps_restore(pdev, FALSE);
                    165:                     pdev->dwFlags &= ~PDEV_WITHINPAGE;
                    166:                 }
                    167: 
                    168:                 if (pdev->dwFlags & PDEV_PROCSET)
                    169:                 {
                    170:                     PrintString(pdev, "end\n");
                    171:                     pdev->dwFlags &= ~PDEV_PROCSET;
                    172:                 }
                    173:             }
                    174: 
                    175:             pdev->dwFlags |= PDEV_RAWDATASENT;
                    176: 
                    177:             // just write out what is in the buffer.  do NOT add a
                    178:             // header to the output.  that would be wrong.
                    179: 
                    180:             bPSFlush(pdev);
                    181: 
                    182:             cjIn = (*(LPWORD)pvIn);
                    183:             pvIn = (LPVOID)(((LPWORD)pvIn) + 1);
                    184: 
                    185:             if (!WritePrinter(pdev->hPrinter, pvIn, cjIn, &cWritten))
                    186:             {
                    187:                 DbgPrint("PSCRIPT!DrvEscape PASSTHROUGH: WritePrinter failed.\n");
                    188:                 ulRet = 0;
                    189:                 break;
                    190:             }
                    191:             else
                    192:                 ulRet = cWritten;
                    193: 
                    194:             break;
                    195: 
                    196:         case GETDEVICEUNITS:
                    197:             // get the pointer to our DEVDATA structure and make sure it is ours.
                    198: 
                    199:             pdev = (PDEVDATA) pso->dhpdev;
                    200: 
                    201:             if ((bValidatePDEV(pdev) == FALSE) || (cjOut < (sizeof(LONG) * 4)))
                    202:             {
                    203:                 RIP("PSCRIPT!DrvEscape GETDEVICEUNITS: invalid pdev or cjOut.\n");
                    204:                 SetLastError(ERROR_INVALID_PARAMETER);
                    205:                 ulRet = 0;
                    206:                 break;
                    207:             }
                    208: 
                    209:             pfloat = (FLOAT *)pvOut;
                    210: 
                    211:             // fill in the first two bytes with the resolution we actually
                    212:             // send to the printer.
                    213: 
                    214:             *pfloat++ =(FLOAT)(pdev->CurForm.imagearea.right -
                    215:                                pdev->CurForm.imagearea.left);
                    216: 
                    217:             // handle landscape vs portrait.
                    218: 
                    219:             ytmp = pdev->CurForm.imagearea.bottom -
                    220:                    pdev->CurForm.imagearea.top;
                    221: 
                    222: #ifndef LANDSCAPE_270_ROTATE // 90 degree case.
                    223:             if ((pdev->psdm.dm.dmFields & DM_ORIENTATION) &&
                    224:                 (pdev->psdm.dm.dmOrientation == DMORIENT_LANDSCAPE))
                    225:                 ytmp = -ytmp;
                    226: #endif
                    227: 
                    228:             *pfloat++ = (FLOAT)ytmp;
                    229: 
                    230:             // now fill in the offset of our origin from the upper left
                    231:             // corner of the piece of paper.
                    232: 
                    233:             *pfloat++ = (FLOAT)pdev->CurForm.imagearea.left;
                    234: 
                    235:             ytmp = pdev->CurForm.imagearea.top;
                    236: 
                    237:             *pfloat = (FLOAT)ytmp;
                    238: 
                    239:             ulRet = TRUE;
                    240:             break;
                    241: 
                    242:         case SETCOPYCOUNT:
                    243:             // the copy count is a DWORD count sitting at pvIn.
                    244: 
                    245:             if (!pvIn)
                    246:             {
                    247:                 ulRet = 0;
                    248:                 break;
                    249:             }
                    250: 
                    251:             // get the pointer to our DEVDATA structure and make sure it is ours.
                    252: 
                    253:             pdev = (PDEVDATA) pso->dhpdev;
                    254: 
                    255:             if (bValidatePDEV(pdev) == FALSE)
                    256:             {
                    257:                 RIP("PSCRIPT!DrvEscape: invalid pdev.\n");
                    258:                 SetLastError(ERROR_INVALID_PARAMETER);
                    259:                 ulRet = 0;
                    260:                 break;
                    261:             }
                    262: 
                    263:             // if user specified zero or one copy, do nothing.  one
                    264:             // copy will be printed by default.
                    265: 
                    266:             if (*(DWORD *)pvIn <= MIN_COPIES)
                    267:             {
                    268:                 // let the caller know how many copies we will do.
                    269: 
                    270:                 pdev->cCopies = 1;
                    271: 
                    272:                 if (pvOut)
                    273:                     *(DWORD *)pvOut = pdev->cCopies;
                    274: 
                    275:                 ulRet = TRUE;
                    276:                 break;
                    277:             }
                    278: 
                    279:             // we have a positive number of copies.  let's set a limit.
                    280: 
                    281:             pdev->cCopies = min(*(DWORD *)pvIn, MAX_COPIES);
                    282: 
                    283:             // let the caller know how many copies we will do.
                    284: 
                    285:             if (pvOut)
                    286:                 *(DWORD *)pvOut = pdev->cCopies;
                    287: 
                    288:             ulRet = TRUE;
                    289:             break;
                    290: 
                    291:         default:
                    292:             // if we get to the default case, we have been passed an
                    293:             // unsupported escape function number.
                    294: 
                    295:             DbgPrint("PSCRIPT!DrvEscape %x ESC_NOT_SUPPORTED.\n", iEsc);
                    296:             ulRet = ESC_NOT_SUPPORTED;
                    297:             break;
                    298: 
                    299:     }
                    300: 
                    301:     return(ulRet);
                    302: }
                    303: 
                    304: //--------------------------------------------------------------------------
                    305: // ULONG DrvDrawEscape(
                    306: // SURFOBJ *pso,
                    307: // ULONG    iEsc,
                    308: // CLIPOBJ *pco,
                    309: // RECTL   *prcl,
                    310: // ULONG    cjIn,
                    311: // PVOID    pvIn);
                    312: //
                    313: // Supports the ESCAPSULATED_POSTSCRIPT escape.
                    314: //
                    315: // History:
                    316: //   Sat May 08 13:27:52 1993          -by-    Hock San Lee    [hockl]
                    317: //  Wrote it.
                    318: //--------------------------------------------------------------------------
                    319: 
                    320: ULONG DrvDrawEscape(
                    321: SURFOBJ *pso,
                    322: ULONG    iEsc,
                    323: CLIPOBJ *pco,
                    324: RECTL   *prcl,
                    325: ULONG    cjIn,
                    326: PVOID    pvIn)
                    327: {
                    328:     PDEVDATA    pdev;
                    329:     DWORD       cWritten;
                    330:     PEPSDATA    pEpsData;
                    331:     BOOL        bRet;
                    332:     BOOL        bFirstClipPass;     // TRUE 1st call to bDoClipObj.
                    333:     BOOL        bMoreClipping;      // TRUE if more clipping to enumerate.
                    334:     BOOL        bClipping;          // TRUE if clipping being done.
                    335: 
                    336:     // handle each case depending on which escape function is being asked for.
                    337: 
                    338:     switch (iEsc)
                    339:     {
                    340:         case QUERYESCSUPPORT:
                    341:             // when querying escape support, the function in question is
                    342:             // passed in the ULONG passed in pvIn.
                    343: 
                    344:             switch (*(PULONG)pvIn)
                    345:             {
                    346:                 case QUERYESCSUPPORT:
                    347:                 case ENCAPSULATED_POSTSCRIPT:
                    348:                     return(ESC_IS_SUPPORTED);
                    349: 
                    350:                 default:
                    351:                     // return 0 if the escape in question is not supported.
                    352:                     return(0);
                    353:             }
                    354: 
                    355:         case ENCAPSULATED_POSTSCRIPT:
                    356: 
                    357:             // get the pointer to our DEVDATA structure and make sure it is ours.
                    358: 
                    359:             pdev = (PDEVDATA) pso->dhpdev;
                    360: 
                    361:             if (bValidatePDEV(pdev) == FALSE)
                    362:             {
                    363:                 RIP("PSCRIPT!DrvDrawEscape: invalid pdev.\n");
                    364:                 SetLastError(ERROR_INVALID_PARAMETER);
                    365:                 return(0);
                    366:             }
                    367: 
                    368:             // get the encapsulated PostScript data.
                    369: 
                    370:             pEpsData = (PEPSDATA) pvIn;
                    371: 
                    372:             // make sure that the driver can handle the eps language level.
                    373: 
                    374:             if ((pdev->pntpd->LangLevel < pEpsData->nVersion)
                    375:             && !(pdev->pntpd->LangLevel == 0 && pEpsData->nVersion <= 1))
                    376:             {
                    377:                 SetLastError(ERROR_NOT_SUPPORTED);
                    378:                 return(0);
                    379:             }
                    380: 
                    381:             // set up the clip path.
                    382: 
                    383:             bFirstClipPass = TRUE;
                    384:             bMoreClipping = TRUE;
                    385: 
                    386:             while (bMoreClipping)
                    387:             {
                    388:                 if (bClipping = bDoClipObj(pdev, pco, NULL, NULL,
                    389:                                            &bMoreClipping, &bFirstClipPass,
                    390:                                            25))
                    391:                     ps_clip(pdev, TRUE);
                    392: 
                    393:                 // prepare for the included EPS data.
                    394: 
                    395:                 ps_begin_eps(pdev);
                    396: 
                    397:                 // set up the transform needed to map the EPS to the device
                    398:                 // parallelogram.
                    399:                 // We ignore prcl here and assume that it is at (0,0).
                    400: 
                    401:                 if (!bDoEpsXform(pdev, pEpsData))
                    402:                 {
                    403:                     RIP("PSCRIPT!DrvDrawEscape: invalid xform.\n");
                    404:                     SetLastError(ERROR_INVALID_PARAMETER);
                    405:                     ps_end_eps(pdev);
                    406:                     return(0);
                    407:                 }
                    408: 
                    409:                 // write out the EPS data.  The EPS data is assumed to begin
                    410:                 // with %%BeginDocument as recommanded in the DSC version 3.0
                    411:                 // by Adobe.
                    412: 
                    413:                 bPSFlush(pdev);
                    414:                 bRet = WritePrinter(pdev->hPrinter,
                    415:                                     (PBYTE) pEpsData + sizeof(EPSDATA),
                    416:                                     pEpsData->cbData - sizeof(EPSDATA),
                    417:                                     &cWritten);
                    418:                 if (!bRet)
                    419:                     DbgPrint("PSCRIPT!DrvDrawEscape ENCAPSULATED_POSTSCRIPT: WritePrinter failed.\n");
                    420: 
                    421:                 // restore state and cleanup stacks.
                    422: 
                    423:                 ps_end_eps(pdev);
                    424: 
                    425:                 if (bClipping)
                    426:                     ps_restore(pdev, TRUE);
                    427: 
                    428:             }
                    429: 
                    430:             return(bRet ? 1 : 0);
                    431: 
                    432:         default:
                    433:             // if we get to the default case, we have been passed an
                    434:             // unsupported escape function number.
                    435: 
                    436:             DbgPrint("PSCRIPT!DrvDrawEscape %x ESC_NOT_SUPPORTED.\n", iEsc);
                    437: 
                    438:             return(ESC_NOT_SUPPORTED);
                    439:     }
                    440: }
                    441: 
                    442: BOOL bDoEpsXform(pdev, pEpsData)
                    443: PDEVDATA  pdev;
                    444: PEPSDATA  pEpsData;
                    445: {
                    446:     PBYTE  pbEps, pbEpsEnd, pbBoundingBox;
                    447:     FLOAT  aeBoundingBox[4];        // bl.x, bl.y, tr.x, tr.y
                    448:     XFORM  xform;
                    449:     PS_FIX psfxM11, psfxM12, psfxM21, psfxM22, psfxdx, psfxdy;
                    450:     int    i;
                    451:     BOOL   bIsNegative;
                    452:     POINTE apteDst[3], apteSrc[3];
                    453: 
                    454:     // look for the string %%BoundingBox:
                    455: 
                    456:     pbEps    = (PBYTE) pEpsData + sizeof(EPSDATA);
                    457:     pbEpsEnd = (PBYTE) pEpsData + pEpsData->cbData - 1;
                    458: 
                    459:     pbBoundingBox = pbEps;
                    460:     while (pbBoundingBox <= pbEpsEnd)
                    461:     {
                    462:         if (!memcmp(pbBoundingBox, "%%BoundingBox:", 14))
                    463:         {
                    464:             pbBoundingBox += 14;
                    465: 
                    466:             // store the bounding box coordinates in aeBoundingBox[].
                    467: 
                    468:             for (i = 0; i < 4; i++)
                    469:             {
                    470:                 // initialize bounding box.
                    471: 
                    472:                 aeBoundingBox[i] = 0.0f;
                    473: 
                    474:                 // skip white space.
                    475: 
                    476:                 while (*pbBoundingBox == ' ' || *pbBoundingBox == '\t')
                    477:                     pbBoundingBox++;
                    478: 
                    479:                 // get sign.
                    480: 
                    481:                 if (*pbBoundingBox == '-')
                    482:                 {
                    483:                     pbBoundingBox++;
                    484:                     bIsNegative = TRUE;
                    485:                 }
                    486:                 else
                    487:                     bIsNegative = FALSE;
                    488: 
                    489:                 // if this is not an integer, it may be an (atend) and
                    490:                 // the bounding box is at the end of the EPS data.
                    491: 
                    492:                 if (!(*pbBoundingBox >= '0' && *pbBoundingBox <= '9' || *pbBoundingBox == '.'))
                    493:                     goto find_bounding_box;
                    494: 
                    495:                 // get integer.
                    496: 
                    497:                 while (*pbBoundingBox >= '0' && *pbBoundingBox <= '9')
                    498:                 {
                    499:                     aeBoundingBox[i] = aeBoundingBox[i] * 10.0f
                    500:                                         + (FLOAT) (int) (*pbBoundingBox - '0');
                    501:                     pbBoundingBox++;
                    502:                 }
                    503: 
                    504:                 // get fraction if any.
                    505: 
                    506:                 if (*pbBoundingBox == '.')
                    507:                 {
                    508:                     FLOAT eDiv;
                    509: 
                    510:                     pbBoundingBox++;        // skip '.'
                    511: 
                    512:                     eDiv = 10.0f;
                    513:                     while (*pbBoundingBox >= '0' && *pbBoundingBox <= '9')
                    514:                     {
                    515:                         aeBoundingBox[i] += (FLOAT) (int) (*pbBoundingBox - '0')
                    516:                                                 / eDiv;
                    517:                         eDiv *= 10.0f;
                    518:                         pbBoundingBox++;
                    519:                     }
                    520:                 }
                    521: 
                    522:                 if (bIsNegative)
                    523:                     aeBoundingBox[i] = aeBoundingBox[i] * -1.0f;
                    524:             }
                    525:             break;        // got it!
                    526:         }
                    527:         else
                    528:             pbBoundingBox++;
                    529: 
                    530:         // look for the '%' character.
                    531: 
                    532:     find_bounding_box:
                    533: 
                    534:         while (*pbBoundingBox != '%' && pbBoundingBox <= pbEpsEnd)
                    535:             pbBoundingBox++;
                    536:     }
                    537: 
                    538:     if (pbBoundingBox > pbEpsEnd)
                    539:     {
                    540:         RIP("PSCRIPT!bDoEpsXform: invalid EPS bounding box.\n");
                    541:         SetLastError(ERROR_INVALID_PARAMETER);
                    542:         return(FALSE);
                    543:     }
                    544: 
                    545:     // convert the parallelogram to PostScript coordinates (FLOAT, 72dpi).
                    546: 
                    547:     apteDst[0].x = XE72DPI(FixToFloat(pEpsData->aptl[0].x));   // left   u0
                    548:     apteDst[0].y = YE72DPI(FixToFloat(pEpsData->aptl[0].y));   // top    v0
                    549:     apteDst[1].x = XE72DPI(FixToFloat(pEpsData->aptl[1].x));   // right  u1
                    550:     apteDst[1].y = YE72DPI(FixToFloat(pEpsData->aptl[1].y));   // top    v1
                    551:     apteDst[2].x = XE72DPI(FixToFloat(pEpsData->aptl[2].x));   // left   u2
                    552:     apteDst[2].y = YE72DPI(FixToFloat(pEpsData->aptl[2].y));   // bottom v2
                    553: 
                    554:     apteSrc[0].x = aeBoundingBox[0];    // left   x0
                    555:     apteSrc[0].y = aeBoundingBox[3];    // top    y0
                    556:     apteSrc[1].x = aeBoundingBox[2];    // right  x1
                    557:     apteSrc[1].y = aeBoundingBox[3];    // top    y1
                    558:     apteSrc[2].x = aeBoundingBox[0];    // left   x2
                    559:     apteSrc[2].y = aeBoundingBox[1];    // bottom y2
                    560: 
                    561: // Here is the transform equation from source EPS parallelogram
                    562: // [(x0,y0) (x1,y1) (x2,y2)] to the device parallelogram
                    563: // [(u0,v0) (u1,v1) (u2,v2)]:
                    564: //
                    565: //   (u)     (u0)        [(x)   (x0)]
                    566: //   ( )  =  (  )  + M * [( ) - (  )]
                    567: //   (v)     (v0)        [(y)   (y0)]
                    568: //
                    569: //  where
                    570: //
                    571: //          [(u1-u0)/(x1-x0)    (u2-u0)/(y2-y0)]
                    572: //      M = [                                  ]
                    573: //          [(v1-v0)/(x1-x0)    (v2-v0)/(y2-y0)]
                    574: 
                    575:     xform.eM11 = (apteDst[1].x - apteDst[0].x) / (apteSrc[1].x - apteSrc[0].x);
                    576:     xform.eM12 = (apteDst[1].y - apteDst[0].y) / (apteSrc[1].x - apteSrc[0].x);
                    577:     xform.eM21 = (apteDst[2].x - apteDst[0].x) / (apteSrc[2].y - apteSrc[0].y);
                    578:     xform.eM22 = (apteDst[2].y - apteDst[0].y) / (apteSrc[2].y - apteSrc[0].y);
                    579:     xform.eDx  = apteDst[0].x - xform.eM11 * apteSrc[0].x - xform.eM21 * apteSrc[0].y;
                    580:     xform.eDy  = apteDst[0].y - xform.eM12 * apteSrc[0].x - xform.eM22 * apteSrc[0].y;
                    581: 
                    582:     // output the transform.
                    583: 
                    584:     psfxM11 = ETOPSFX(xform.eM11);
                    585:     psfxM12 = ETOPSFX(xform.eM12);
                    586:     psfxM21 = ETOPSFX(xform.eM21);
                    587:     psfxM22 = ETOPSFX(xform.eM22);
                    588:     psfxdx  = ETOPSFX(xform.eDx);
                    589:     psfxdy  = ETOPSFX(xform.eDy);
                    590: 
                    591:     PrintString(pdev, "[");
                    592:     PrintPSFIX(pdev, 6, psfxM11, psfxM12, psfxM21, psfxM22,
                    593:                psfxdx, psfxdy);
                    594:     PrintString(pdev, "] concat\n");
                    595: 
                    596:     return(TRUE);
                    597: }
                    598: 
                    599: FLOAT ae16[16] = { 0.0f / 16.0f,  1.0f / 16.0f,  2.0f / 16.0f,  3.0f / 16.0f,
                    600:                    4.0f / 16.0f,  5.0f / 16.0f,  6.0f / 16.0f,  7.0f / 16.0f,
                    601:                    8.0f / 16.0f,  9.0f / 16.0f, 10.0f / 16.0f, 11.0f / 16.0f,
                    602:                   12.0f / 16.0f, 13.0f / 16.0f, 14.0f / 16.0f, 15.0f / 16.0f};
                    603: 
                    604: // Convert 28.4 FIX to FLOAT.
                    605: 
                    606: FLOAT FixToFloat(FIX fx)
                    607: {
                    608:     FLOAT e;
                    609: 
                    610:     e = (FLOAT) ((LONG) fx >> 4);
                    611:     e += ae16[fx & 0xF];
                    612: 
                    613:     return(e);
                    614: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.