ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

xformobj.c
Go to the documentation of this file.
00001 /*
00002  * PROJECT:         ReactOS win32 kernel mode subsystem
00003  * LICENSE:         GPL - See COPYING in the top level directory
00004  * FILE:            subsystems/win32/win32k/objects/xformobj.c
00005  * PURPOSE:         XFORMOBJ API
00006  * PROGRAMMER:      Timo Kreuzer
00007  */
00008 
00011 #include <win32k.h>
00012 #define NDEBUG
00013 #include <debug.h>
00014 
00015 C_ASSERT(sizeof(FIX) == sizeof(LONG));
00016 #define FIX2LONG(x) ((x) >> 4)
00017 #define LONG2FIX(x) ((x) << 4)
00018 
00019 #define FLOATOBJ_Equal _FLOATOBJ_Equal
00020 #define FLOATOBJ_GetLong _FLOATOBJ_GetLong
00021 #define FLOATOBJ_GetFix _FLOATOBJ_GetFix
00022 #define FLOATOBJ_IsLong _FLOATOBJ_IsLong
00023 #define FLOATOBJ_Equal0 _FLOATOBJ_Equal0
00024 #define FLOATOBJ_Equal1 _FLOATOBJ_Equal1
00025 
00028 /*
00029  * Inline helper to calculate pfo1 * pfo2 + pfo3 * pfo4
00030  */
00031 FORCEINLINE
00032 VOID
00033 MulAdd(
00034     PFLOATOBJ pfoDest,
00035     PFLOATOBJ pfo1,
00036     PFLOATOBJ pfo2,
00037     PFLOATOBJ pfo3,
00038     PFLOATOBJ pfo4)
00039 {
00040     FLOATOBJ foTmp;
00041 
00042     *pfoDest = *pfo1;
00043     FLOATOBJ_Mul(pfoDest, pfo2);
00044     foTmp = *pfo3;
00045     FLOATOBJ_Mul(&foTmp, pfo4);
00046     FLOATOBJ_Add(pfoDest, &foTmp);
00047 }
00048 
00049 /*
00050  * Inline helper to calculate pfo1 * l2 + pfo3 * l4
00051  */
00052 FORCEINLINE
00053 VOID
00054 MulAddLong(
00055     PFLOATOBJ pfoDest,
00056     PFLOATOBJ pfo1,
00057     LONG l2,
00058     PFLOATOBJ pfo3,
00059     LONG l4)
00060 {
00061     FLOATOBJ foTmp;
00062 
00063     *pfoDest = *pfo1;
00064     FLOATOBJ_MulLong(pfoDest, l2);
00065     foTmp = *pfo3;
00066     FLOATOBJ_MulLong(&foTmp, l4);
00067     FLOATOBJ_Add(pfoDest, &foTmp);
00068 }
00069 
00070 /*
00071  * Inline helper to calculate pfo1 * pfo2 - pfo3 * pfo4
00072  */
00073 FORCEINLINE
00074 VOID
00075 MulSub(
00076     PFLOATOBJ pfoDest,
00077     PFLOATOBJ pfo1,
00078     PFLOATOBJ pfo2,
00079     PFLOATOBJ pfo3,
00080     PFLOATOBJ pfo4)
00081 {
00082     FLOATOBJ foTmp;
00083 
00084     *pfoDest = *pfo1;
00085     FLOATOBJ_Mul(pfoDest, pfo2);
00086     foTmp = *pfo3;
00087     FLOATOBJ_Mul(&foTmp, pfo4);
00088     FLOATOBJ_Sub(pfoDest, &foTmp);
00089 }
00090 
00091 /*
00092  * Inline helper to get the complexity hint from flAccel
00093  */
00094 FORCEINLINE
00095 ULONG
00096 HintFromAccel(ULONG flAccel)
00097 {
00098     switch (flAccel & (XFORM_SCALE|XFORM_UNITY|XFORM_NO_TRANSLATION))
00099     {
00100         case (XFORM_SCALE|XFORM_UNITY|XFORM_NO_TRANSLATION):
00101             return GX_IDENTITY;
00102         case (XFORM_SCALE|XFORM_UNITY):
00103             return GX_OFFSET;
00104         case XFORM_SCALE:
00105             return GX_SCALE;
00106         default:
00107             return GX_GENERAL;
00108     }
00109 }
00110 
00113 ULONG
00114 NTAPI
00115 XFORMOBJ_UpdateAccel(
00116     IN XFORMOBJ *pxo)
00117 {
00118     PMATRIX pmx = XFORMOBJ_pmx(pxo);
00119 
00120     /* Copy Dx and Dy to FIX format */
00121     pmx->fxDx = FLOATOBJ_GetFix(&pmx->efDx);
00122     pmx->fxDy = FLOATOBJ_GetFix(&pmx->efDy);
00123 
00124     pmx->flAccel = 0;
00125 
00126     if (FLOATOBJ_Equal0(&pmx->efDx) &&
00127         FLOATOBJ_Equal0(&pmx->efDy))
00128     {
00129         pmx->flAccel |= XFORM_NO_TRANSLATION;
00130     }
00131 
00132     if (FLOATOBJ_Equal0(&pmx->efM12) &&
00133         FLOATOBJ_Equal0(&pmx->efM21))
00134     {
00135         pmx->flAccel |= XFORM_SCALE;
00136     }
00137 
00138     if (FLOATOBJ_Equal1(&pmx->efM11) &&
00139         FLOATOBJ_Equal1(&pmx->efM22))
00140     {
00141         pmx->flAccel |= XFORM_UNITY;
00142     }
00143 
00144     if (FLOATOBJ_IsLong(&pmx->efM11) && FLOATOBJ_IsLong(&pmx->efM12) &&
00145         FLOATOBJ_IsLong(&pmx->efM21) && FLOATOBJ_IsLong(&pmx->efM22))
00146     {
00147         pmx->flAccel |= XFORM_INTEGER;
00148     }
00149 
00150     return HintFromAccel(pmx->flAccel);
00151 }
00152 
00153 
00154 ULONG
00155 NTAPI
00156 XFORMOBJ_iSetXform(
00157     OUT XFORMOBJ *pxo,
00158     IN const XFORML *pxform)
00159 {
00160     PMATRIX pmx = XFORMOBJ_pmx(pxo);
00161 
00162     /* Check parameters */
00163     if (!pxo || !pxform) return DDI_ERROR;
00164 
00165     /* Check if the xform is valid */
00166     if ((pxform->eM11 == 0) || (pxform->eM22 == 0)) return DDI_ERROR;
00167 
00168     /* Copy members */
00169     FLOATOBJ_SetFloat(&pmx->efM11, pxform->eM11);
00170     FLOATOBJ_SetFloat(&pmx->efM12, pxform->eM12);
00171     FLOATOBJ_SetFloat(&pmx->efM21, pxform->eM21);
00172     FLOATOBJ_SetFloat(&pmx->efM22, pxform->eM22);
00173     FLOATOBJ_SetFloat(&pmx->efDx, pxform->eDx);
00174     FLOATOBJ_SetFloat(&pmx->efDy, pxform->eDy);
00175 
00176     /* Update accelerators and return complexity */
00177     return XFORMOBJ_UpdateAccel(pxo);
00178 }
00179 
00180 
00181 /*
00182  * Multiplies pxo1 with pxo2 and stores the result in pxo.
00183  * returns complexity hint
00184  * | efM11 efM12 0 |
00185  * | efM21 efM22 0 |
00186  * | efDx  efDy  1 |
00187  */
00188 ULONG
00189 NTAPI
00190 XFORMOBJ_iCombine(
00191     IN XFORMOBJ *pxo,
00192     IN XFORMOBJ *pxo1,
00193     IN XFORMOBJ *pxo2)
00194 {
00195     MATRIX mx;
00196     PMATRIX pmx, pmx1, pmx2;
00197 
00198     pmx = XFORMOBJ_pmx(pxo);
00199     pmx1 =XFORMOBJ_pmx(pxo1);
00200     pmx2 = XFORMOBJ_pmx(pxo2);
00201 
00202     /* Do a 3 x 3 matrix multiplication with mx as destinantion */
00203     MulAdd(&mx.efM11, &pmx1->efM11, &pmx2->efM11, &pmx1->efM12, &pmx2->efM21);
00204     MulAdd(&mx.efM12, &pmx1->efM11, &pmx2->efM12, &pmx1->efM12, &pmx2->efM22);
00205     MulAdd(&mx.efM21, &pmx1->efM21, &pmx2->efM11, &pmx1->efM22, &pmx2->efM21);
00206     MulAdd(&mx.efM22, &pmx1->efM21, &pmx2->efM12, &pmx1->efM22, &pmx2->efM22);
00207     MulAdd(&mx.efDx, &pmx1->efDx, &pmx2->efM11, &pmx1->efDy, &pmx2->efM21);
00208     FLOATOBJ_Add(&mx.efDx, &pmx2->efDx);
00209     MulAdd(&mx.efDy, &pmx1->efDx, &pmx2->efM12, &pmx1->efDy, &pmx2->efM22);
00210     FLOATOBJ_Add(&mx.efDy, &pmx2->efDy);
00211 
00212     /* Copy back */
00213     *pmx = mx;
00214 
00215     /* Update accelerators and return complexity */
00216     return XFORMOBJ_UpdateAccel(pxo);
00217 }
00218 
00219 
00220 ULONG
00221 NTAPI
00222 XFORMOBJ_iCombineXform(
00223     IN XFORMOBJ *pxo,
00224     IN XFORMOBJ *pxo1,
00225     IN XFORML *pxform,
00226     IN BOOL bLeftMultiply)
00227 {
00228     MATRIX mx;
00229     XFORMOBJ xo2;
00230 
00231     XFORMOBJ_vInit(&xo2, &mx);
00232     XFORMOBJ_iSetXform(&xo2, pxform);
00233 
00234     if (bLeftMultiply)
00235     {
00236         return XFORMOBJ_iCombine(pxo, &xo2, pxo1);
00237     }
00238     else
00239     {
00240         return XFORMOBJ_iCombine(pxo, pxo1, &xo2);
00241     }
00242 }
00243 
00244 /*
00245  * A^-1 = adj(A) / det(AT)
00246  * A^-1 = 1/(a*d - b*c) * (a22,-a12,a21,-a11)
00247  */
00248 ULONG
00249 NTAPI
00250 XFORMOBJ_iInverse(
00251     OUT XFORMOBJ *pxoDst,
00252     IN XFORMOBJ *pxoSrc)
00253 {
00254     PMATRIX pmxDst, pmxSrc;
00255     FLOATOBJ foDet;
00256     XFORM xformSrc;
00257     union
00258     {
00259         FLOAT Float;
00260         LONG Long;
00261     } eDet;
00262 
00263     pmxDst = XFORMOBJ_pmx(pxoDst);
00264     pmxSrc = XFORMOBJ_pmx(pxoSrc);
00265 
00266     XFORMOBJ_iGetXform(pxoSrc, (XFORML*)&xformSrc);
00267 
00268     /* det = M11 * M22 - M12 * M21 */
00269     MulSub(&foDet, &pmxSrc->efM11, &pmxSrc->efM22, &pmxSrc->efM12, &pmxSrc->efM21);
00270 
00271     if (FLOATOBJ_Equal0(&foDet))
00272     {
00273         /* Determinant is 0! */
00274         return DDI_ERROR;
00275     }
00276 
00277     eDet.Long = FLOATOBJ_GetFloat(&foDet);
00278 
00279     /* Calculate adj(A) / det(A) */
00280     pmxDst->efM11 = pmxSrc->efM22;
00281     FLOATOBJ_Div(&pmxDst->efM11, &foDet);
00282     pmxDst->efM22 = pmxSrc->efM11;
00283     FLOATOBJ_Div(&pmxDst->efM22, &foDet);
00284 
00285     /* The other 2 are negative, negate foDet for that */
00286     FLOATOBJ_Neg(&foDet);
00287     pmxDst->efM12 = pmxSrc->efM12;
00288     FLOATOBJ_Div(&pmxDst->efM12, &foDet);
00289     pmxDst->efM21 = pmxSrc->efM21;
00290     FLOATOBJ_Div(&pmxDst->efM21, &foDet);
00291 
00292     /* Update accelerators and return complexity */
00293     return XFORMOBJ_UpdateAccel(pxoDst);
00294 }
00295 
00296 
00297 BOOL
00298 NTAPI
00299 XFORMOBJ_bXformFixPoints(
00300     IN XFORMOBJ  *pxo,
00301     IN ULONG  cPoints,
00302     IN PPOINTL  pptIn,
00303     OUT PPOINTL  pptOut)
00304 {
00305     PMATRIX pmx;
00306     INT i;
00307     FLOATOBJ fo1, fo2;
00308     FLONG flAccel;
00309 
00310     pmx = XFORMOBJ_pmx(pxo);
00311     flAccel = pmx->flAccel;
00312 
00313     if ((flAccel & (XFORM_SCALE|XFORM_UNITY)) == (XFORM_SCALE|XFORM_UNITY))
00314     {
00315         /* Identity transformation, nothing todo */
00316     }
00317     else if (flAccel & XFORM_INTEGER)
00318     {
00319         if (flAccel & XFORM_UNITY)
00320         {
00321             /* 1-scale integer transform */
00322             i = cPoints - 1;
00323             do
00324             {
00325                 LONG x = pptIn[i].x + pptIn[i].y * FLOATOBJ_GetLong(&pmx->efM21);
00326                 LONG y = pptIn[i].y + pptIn[i].x * FLOATOBJ_GetLong(&pmx->efM12);
00327                 pptOut[i].y = y;
00328                 pptOut[i].x = x;
00329             }
00330             while (--i >= 0);
00331         }
00332         else if (flAccel & XFORM_SCALE)
00333         {
00334             /* Diagonal integer transform */
00335             i = cPoints - 1;
00336             do
00337             {
00338                 pptOut[i].x = pptIn[i].x * FLOATOBJ_GetLong(&pmx->efM11);
00339                 pptOut[i].y = pptIn[i].y * FLOATOBJ_GetLong(&pmx->efM22);
00340             }
00341             while (--i >= 0);
00342         }
00343         else
00344         {
00345             /* Full integer transform */
00346             i = cPoints - 1;
00347             do
00348             {
00349                 LONG x;
00350                 x  = pptIn[i].x * FLOATOBJ_GetLong(&pmx->efM11);
00351                 x += pptIn[i].y * FLOATOBJ_GetLong(&pmx->efM21);
00352                 pptOut[i].y  = pptIn[i].y * FLOATOBJ_GetLong(&pmx->efM22);
00353                 pptOut[i].y += pptIn[i].x * FLOATOBJ_GetLong(&pmx->efM12);
00354                 pptOut[i].x = x;
00355             }
00356             while (--i >= 0);
00357         }
00358     }
00359     else if (flAccel & XFORM_UNITY)
00360     {
00361         /* 1-scale transform */
00362         i = cPoints - 1;
00363         do
00364         {
00365             fo1 = pmx->efM21;
00366             FLOATOBJ_MulLong(&fo1, pptIn[i].y);
00367             fo2 = pmx->efM12;
00368             FLOATOBJ_MulLong(&fo2, pptIn[i].x);
00369             pptOut[i].x = pptIn[i].x + FLOATOBJ_GetLong(&fo1);
00370             pptOut[i].y = pptIn[i].y + FLOATOBJ_GetLong(&fo2);
00371         }
00372         while (--i >= 0);
00373     }
00374     else if (flAccel & XFORM_SCALE)
00375     {
00376         /* Diagonal float transform */
00377         i = cPoints - 1;
00378         do
00379         {
00380             fo1 = pmx->efM11;
00381             FLOATOBJ_MulLong(&fo1, pptIn[i].x);
00382             pptOut[i].x = FLOATOBJ_GetLong(&fo1);
00383             fo2 = pmx->efM22;
00384             FLOATOBJ_MulLong(&fo2, pptIn[i].y);
00385             pptOut[i].y = FLOATOBJ_GetLong(&fo2);
00386         }
00387         while (--i >= 0);
00388     }
00389     else
00390     {
00391         /* Full float transform */
00392         i = cPoints - 1;
00393         do
00394         {
00395             MulAddLong(&fo1, &pmx->efM11, pptIn[i].x, &pmx->efM21, pptIn[i].y);
00396             MulAddLong(&fo2, &pmx->efM12, pptIn[i].x, &pmx->efM22, pptIn[i].y);
00397             pptOut[i].x = FLOATOBJ_GetLong(&fo1);
00398             pptOut[i].y = FLOATOBJ_GetLong(&fo2);
00399         }
00400         while (--i >= 0);
00401     }
00402 
00403     if (!(pmx->flAccel & XFORM_NO_TRANSLATION))
00404     {
00405         /* Translate points */
00406         i = cPoints - 1;
00407         do
00408         {
00409             pptOut[i].x += pmx->fxDx;
00410             pptOut[i].y += pmx->fxDy;
00411         }
00412         while (--i >= 0);
00413     }
00414 
00415     return TRUE;
00416 }
00417 
00420 // www.osr.com/ddk/graphics/gdifncs_0s2v.htm
00421 ULONG
00422 APIENTRY
00423 XFORMOBJ_iGetXform(
00424     IN XFORMOBJ *pxo,
00425     OUT XFORML *pxform)
00426 {
00427     PMATRIX pmx = XFORMOBJ_pmx(pxo);
00428 
00429     /* Check parameters */
00430     if (!pxo || !pxform)
00431     {
00432         return DDI_ERROR;
00433     }
00434 
00435     /* Copy members */
00436     pxform->eM11 = FLOATOBJ_GetFloat(&pmx->efM11);
00437     pxform->eM12 = FLOATOBJ_GetFloat(&pmx->efM12);
00438     pxform->eM21 = FLOATOBJ_GetFloat(&pmx->efM21);
00439     pxform->eM22 = FLOATOBJ_GetFloat(&pmx->efM22);
00440     pxform->eDx = FLOATOBJ_GetFloat(&pmx->efDx);
00441     pxform->eDy = FLOATOBJ_GetFloat(&pmx->efDy);
00442 
00443     /* Return complexity hint */
00444     return HintFromAccel(pmx->flAccel);
00445 }
00446 
00447 
00448 // www.osr.com/ddk/graphics/gdifncs_5ig7.htm
00449 ULONG
00450 APIENTRY
00451 XFORMOBJ_iGetFloatObjXform(
00452     IN XFORMOBJ *pxo,
00453     OUT FLOATOBJ_XFORM *pxfo)
00454 {
00455     PMATRIX pmx = XFORMOBJ_pmx(pxo);
00456 
00457     /* Check parameters */
00458     if (!pxo || !pxfo)
00459     {
00460         return DDI_ERROR;
00461     }
00462 
00463     /* Copy members */
00464     pxfo->eM11 = pmx->efM11;
00465     pxfo->eM12 = pmx->efM12;
00466     pxfo->eM21 = pmx->efM21;
00467     pxfo->eM22 = pmx->efM22;
00468     pxfo->eDx = pmx->efDx;
00469     pxfo->eDy = pmx->efDy;
00470 
00471     /* Return complexity hint */
00472     return HintFromAccel(pmx->flAccel);
00473 }
00474 
00475 
00476 // www.osr.com/ddk/graphics/gdifncs_027b.htm
00477 BOOL
00478 APIENTRY
00479 XFORMOBJ_bApplyXform(
00480     IN XFORMOBJ *pxo,
00481     IN ULONG iMode,
00482     IN ULONG cPoints,
00483     IN PVOID pvIn,
00484     OUT PVOID pvOut)
00485 {
00486     MATRIX mx;
00487     XFORMOBJ xoInv;
00488     POINTL *pptl;
00489     INT i;
00490 
00491     /* Check parameters */
00492     if (!pxo || !pvIn || !pvOut || cPoints < 1)
00493     {
00494         return FALSE;
00495     }
00496 
00497     /* Use inverse xform? */
00498     if (iMode == XF_INV_FXTOL || iMode == XF_INV_LTOL)
00499     {
00500         XFORMOBJ_vInit(&xoInv, &mx);
00501         if (XFORMOBJ_iInverse(&xoInv, pxo) == DDI_ERROR)
00502         {
00503             return FALSE;
00504         }
00505         pxo = &xoInv;
00506     }
00507 
00508     /* Convert POINTL to POINTFIX? */
00509     if (iMode == XF_LTOFX || iMode == XF_LTOL || iMode == XF_INV_LTOL)
00510     {
00511         pptl = pvIn;
00512         for (i = cPoints - 1; i >= 0; i--)
00513         {
00514             pptl[i].x = LONG2FIX(pptl[i].x);
00515             pptl[i].y = LONG2FIX(pptl[i].y);
00516         }
00517     }
00518 
00519     /* Do the actual fixpoint transformation */
00520     if (!XFORMOBJ_bXformFixPoints(pxo, cPoints, pvIn, pvOut))
00521     {
00522         return FALSE;
00523     }
00524 
00525     /* Convert POINTFIX to POINTL? */
00526     if (iMode == XF_INV_FXTOL || iMode == XF_INV_LTOL || iMode == XF_LTOL)
00527     {
00528         pptl = pvOut;
00529         for (i = cPoints - 1; i >= 0; i--)
00530         {
00531             pptl[i].x = FIX2LONG(pptl[i].x);
00532             pptl[i].y = FIX2LONG(pptl[i].y);
00533         }
00534     }
00535 
00536     return TRUE;
00537 }
00538 
00539 /* EOF */

Generated on Sun May 27 2012 04:38:27 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.