Annotation of ntddk/src/print/pscript/escape.c, revision 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.