sitetran.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:180k
源码类别:

Symbian

开发平台:

C/C++

  1.    points[3].x = right - ((right - left) * completeness)/ 1000;
  2.    points[3].y = bottom;
  3.         
  4.    if (lines)
  5.    {
  6.       lines->m_nLines = 2;
  7.       lines->m_pLines = new LineSegment[2];
  8.       if (!lines->m_pLines)
  9.       {
  10.          lines->m_nLines = 0;
  11.       }
  12.       else
  13.       {
  14.          lines->m_pLines[0].start.x = points[1].x;
  15.          lines->m_pLines[0].start.y = points[1].y;
  16.          lines->m_pLines[0].finish.x = points[2].x;
  17.          lines->m_pLines[0].finish.y = points[2].y;
  18.          lines->m_pLines[1].start.x = points[2].x;
  19.          lines->m_pLines[1].start.y = points[2].y;
  20.          lines->m_pLines[1].finish.x = points[3].x;
  21.          lines->m_pLines[1].finish.y = points[3].y;
  22.       }
  23.    }
  24.    return HXPolygonRegion( points, 4, WindingRule);
  25. }
  26. HXREGION* BottomLeftEdgeWipe(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  27. {
  28.    HXxPoint points[4];
  29.         
  30.    points[0].x = left;
  31.    points[0].y = bottom;
  32.    points[1].x = left;
  33.    points[1].y = bottom - ((bottom - top) * completeness )/ 1000;
  34.    points[2].y = bottom - ((bottom - top) * completeness )/ 1000;
  35.    points[2].x = left + ((right - left) * completeness )/ 1000;
  36.    points[3].x = left + ((right - left) * completeness )/ 1000;
  37.    points[3].y = bottom;
  38.         
  39.    if (lines)
  40.    {
  41.       lines->m_nLines = 2;
  42.       lines->m_pLines = new LineSegment[2];
  43.       if (!lines->m_pLines)
  44.       {
  45.          lines->m_nLines = 0;
  46.       }
  47.       else
  48.       {
  49.          lines->m_pLines[0].start.x = points[1].x;
  50.          lines->m_pLines[0].start.y = points[1].y;
  51.          lines->m_pLines[0].finish.x = points[2].x;
  52.          lines->m_pLines[0].finish.y = points[2].y;
  53.          lines->m_pLines[1].start.x = points[2].x;
  54.          lines->m_pLines[1].start.y = points[2].y;
  55.          lines->m_pLines[1].finish.x = points[3].x;
  56.          lines->m_pLines[1].finish.y = points[3].y;
  57.       }
  58.    }
  59.    return HXPolygonRegion( points, 4, WindingRule);
  60. }
  61. HXREGION* FourCornerEdgeWipe(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  62. {
  63.    tranLines *tl1 = NULL, *tl2 = NULL, *tl3 = NULL;
  64.    if (lines)
  65.    {
  66.       tl1 = new tranLines;
  67.       tl2 = new tranLines;
  68.       tl3 = new tranLines;
  69.    }
  70.    HXREGION* retRGN = HXCreateRectRegion(0, 0, 0, 0);
  71.    HXREGION* rgn1 = TopLeftEdgeWipe(left, top, left+(right-left)/2, top+(bottom-top)/2, completeness,lines);
  72.    HXREGION* rgn2 = TopRightEdgeWipe(left+(right-left)/2, top, right, top+(bottom-top)/2, completeness,tl1);
  73.    HXREGION* rgn3 = BottomRightEdgeWipe(left+(right-left)/2, top+(bottom-top)/2, right, bottom, completeness,tl2);
  74.    HXREGION* rgn4 = BottomLeftEdgeWipe(left, top+(bottom-top)/2, left+(right-left)/2, bottom, completeness,tl3);
  75.    if (lines)
  76.    {
  77.       *lines += *tl1;
  78.       *lines += *tl2;
  79.       *lines += *tl3;
  80.       delete tl1;
  81.       delete tl2;
  82.       delete tl3;
  83.    }
  84.     
  85.    HXCombineRgn(retRGN, retRGN, rgn1, HX_RGN_OR);
  86.    HXCombineRgn(retRGN, retRGN, rgn2, HX_RGN_OR);
  87.    HXCombineRgn(retRGN, retRGN, rgn3, HX_RGN_OR);
  88.    HXCombineRgn(retRGN, retRGN, rgn4, HX_RGN_OR);
  89.         
  90.    HXDestroyRegion(rgn1);
  91.    HXDestroyRegion(rgn2);
  92.    HXDestroyRegion(rgn3);
  93.    HXDestroyRegion(rgn4);
  94.     
  95.    return retRGN;
  96. }
  97. HXREGION* BoxEdgeWipe(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  98. {
  99.    double dleft     = left;
  100.    double dtop              = top;
  101.    double dright            = right;
  102.    double dbottom           = bottom;
  103.    double dcompleteness    = completeness;
  104.    int l = (int) (((dleft+dright)/2.0 ) - ((dright - dleft)/2.0 ) * dcompleteness/1000.0);
  105.    int t = (int) (((dtop+dbottom)/2.0 ) - ((dbottom - dtop)/2.0 ) * dcompleteness/1000.0);
  106.    int r = (int) (((dleft+dright)/2.0 ) + ((dright - dleft)/2.0 ) * dcompleteness/1000.0);
  107.    int b = (int) (((dtop+dbottom)/2.0 ) + ((dbottom - dtop)/2.0 ) * dcompleteness/1000.0);
  108.    if (lines)
  109.    {
  110.       lines->m_nLines = 4;
  111.       lines->m_pLines = new LineSegment[4];
  112.       if (!lines->m_pLines)
  113.       {
  114.          lines->m_nLines = 0;
  115.       }
  116.       else
  117.       {
  118.          lines->m_pLines[0].start.x = l;
  119.          lines->m_pLines[0].start.y = t;
  120.          lines->m_pLines[0].finish.x = r;
  121.          lines->m_pLines[0].finish.y = t;
  122.          lines->m_pLines[1].start.x = r;
  123.          lines->m_pLines[1].start.y = t;
  124.          lines->m_pLines[1].finish.x = r;
  125.          lines->m_pLines[1].finish.y = b;
  126.          lines->m_pLines[2].start.x = r;
  127.          lines->m_pLines[2].start.y = b;
  128.          lines->m_pLines[2].finish.x = l;
  129.          lines->m_pLines[2].finish.y = b;
  130.          lines->m_pLines[3].start.x = l;
  131.          lines->m_pLines[3].start.y = b;
  132.          lines->m_pLines[3].finish.x = l;
  133.          lines->m_pLines[3].finish.y = t;
  134.       }
  135.    }
  136.    return HXCreateRectRegion(l,t,r-l,b-t);
  137. }
  138. HXREGION* FourBoxEdgeWipe(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  139. {
  140.    tranLines *tl1 = NULL, *tl2 = NULL, *tl3 = NULL;
  141.    if (lines)
  142.    {
  143.       tl1 = new tranLines;
  144.       tl2 = new tranLines;
  145.       tl3 = new tranLines;
  146.    }
  147.    HXREGION* retRGN = HXCreateRectRegion(0, 0, 0, 0);
  148.    HXREGION* rgn1 = BoxEdgeWipe(left, top, left+(right-left)/2, top+(bottom-top)/2, completeness,lines);
  149.    HXREGION* rgn2 = BoxEdgeWipe(left+(right-left)/2, top, right, top+(bottom-top)/2, completeness,tl1);
  150.    HXREGION* rgn3 = BoxEdgeWipe(left+(right-left)/2, top+(bottom-top)/2, right, bottom, completeness,tl2);
  151.    HXREGION* rgn4 = BoxEdgeWipe(left, top+(bottom-top)/2, left+(right-left)/2, bottom, completeness,tl3);
  152.         
  153.    if (lines)
  154.    {
  155.       *lines += *tl1;
  156.       *lines += *tl2;
  157.       *lines += *tl3;
  158.       delete tl1;
  159.       delete tl2;
  160.       delete tl3;
  161.    }
  162.         
  163.    HXCombineRgn(retRGN, retRGN, rgn1, HX_RGN_OR);
  164.    HXCombineRgn(retRGN, retRGN, rgn2, HX_RGN_OR);
  165.    HXCombineRgn(retRGN, retRGN, rgn3, HX_RGN_OR);
  166.    HXCombineRgn(retRGN, retRGN, rgn4, HX_RGN_OR);
  167.         
  168.    HXDestroyRegion(rgn1);
  169.    HXDestroyRegion(rgn2);
  170.    HXDestroyRegion(rgn3);
  171.    HXDestroyRegion(rgn4);
  172.         
  173.    return retRGN;
  174. }
  175. HXREGION* BarnVerticalEdgeWipe(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  176. {
  177.    int l = (int)(((double)(left+right)/2)-((double) (right - left)/2 ) * ((double)completeness/1000.0));
  178.    int r = (int) (((double) (left+right)/2 ) + ((double) (right - left)/2 ) * ((double)completeness/1000.0));
  179.    if (lines)
  180.    {
  181.       lines->m_nLines = 2;
  182.       lines->m_pLines = new LineSegment[2];
  183.       if (!lines->m_pLines)
  184.       {
  185.          lines->m_nLines = 0;
  186.       }
  187.       else
  188.       {
  189.          lines->m_pLines[0].start.x = l;
  190.          lines->m_pLines[0].start.y = top;
  191.          lines->m_pLines[0].finish.x = l;
  192.          lines->m_pLines[0].finish.y = bottom;
  193.          lines->m_pLines[1].start.x = r;
  194.          lines->m_pLines[1].start.y = top;
  195.          lines->m_pLines[1].finish.x = r;
  196.          lines->m_pLines[1].finish.y = bottom;
  197.       }
  198.    }
  199.    return HXCreateRectRegion(l,top,r-l,bottom-top);
  200. }
  201. HXREGION* BarnHorizontalEdgeWipe(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  202. {
  203.    int t = (int) (((double) (top+bottom)/2 ) - ((double) (bottom - top)/2 ) * ((double)completeness/1000.0));
  204.    int b = (int) (((double) (top+bottom)/2 ) + ((double) (bottom - top)/2 ) * ((double)completeness/1000.0));
  205.    if (lines)
  206.    {
  207.       lines->m_nLines = 2;
  208.       lines->m_pLines = new LineSegment[2];
  209.       if (!lines->m_pLines)
  210.       {
  211.          lines->m_nLines = 0;
  212.       }
  213.       else
  214.       {
  215.          lines->m_pLines[0].start.x = left;
  216.          lines->m_pLines[0].start.y = t;
  217.          lines->m_pLines[0].finish.x = right;
  218.          lines->m_pLines[0].finish.y = t;
  219.          lines->m_pLines[1].start.x = left;
  220.          lines->m_pLines[1].start.y = b;
  221.          lines->m_pLines[1].finish.x = right;
  222.          lines->m_pLines[1].finish.y = b;
  223.       }
  224.    }
  225.    return HXCreateRectRegion(left,t,right-left,b-t);
  226. }
  227. HXREGION* TopCenterEdgeWipe(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  228. {
  229.    int l = (int) (((double) (left+right)/2 ) - ((double) (right - left)/2 ) * ((double)completeness/1000.0));
  230.    int r = (int) (((double) (left+right)/2 ) + ((double) (right - left)/2 ) * ((double)completeness/1000.0));
  231.    int b = (int) (((double) top + ((double) (bottom - top) )) * ((double)completeness/1000.0));
  232.    if (lines)
  233.    {
  234.       lines->m_nLines = 3;
  235.       lines->m_pLines = new LineSegment[3];
  236.       if (!lines->m_pLines)
  237.       {
  238.          lines->m_nLines = 0;
  239.       }
  240.       else
  241.       {
  242.          lines->m_pLines[0].start.x = l;
  243.          lines->m_pLines[0].start.y = top;
  244.          lines->m_pLines[0].finish.x = l;
  245.          lines->m_pLines[0].finish.y = b;
  246.          lines->m_pLines[1].start.x = l;
  247.          lines->m_pLines[1].start.y = b;
  248.          lines->m_pLines[1].finish.x = r;
  249.          lines->m_pLines[1].finish.y = b;
  250.          lines->m_pLines[2].start.x = r;
  251.          lines->m_pLines[2].start.y = b;
  252.          lines->m_pLines[2].finish.x = r;
  253.          lines->m_pLines[2].finish.y = top;
  254.       }
  255.    }
  256.    HXREGION* retRGN = HXCreateRectRegion(l,top,r-l,b-top);
  257.         
  258.    return retRGN;
  259. }
  260. HXREGION* CenterRightEdgeWipe(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  261. {
  262.    int l = (int) (left + ((double) (right - left) ) * ( 1.0 - (double)completeness/1000.0));
  263.    int t = (int) (((double) (top+bottom)/2 ) - ((double) (bottom - top)/2 ) * ((double)completeness/1000.0));
  264.    int b = (int) (((double) (top+bottom)/2 ) + ((double) (bottom - top)/2 ) * ((double)completeness/1000.0));
  265.    if (lines)
  266.    {
  267.       lines->m_nLines = 3;
  268.       lines->m_pLines = new LineSegment[3];
  269.       if (!lines->m_pLines)
  270.       {
  271.          lines->m_nLines = 0;
  272.       }
  273.       else
  274.       {
  275.          lines->m_pLines[0].start.x = right;
  276.          lines->m_pLines[0].start.y = t;
  277.          lines->m_pLines[0].finish.x = l;
  278.          lines->m_pLines[0].finish.y = t;
  279.          lines->m_pLines[1].start.x = l;
  280.          lines->m_pLines[1].start.y = t;
  281.          lines->m_pLines[1].finish.x = l;
  282.          lines->m_pLines[1].finish.y = b;
  283.          lines->m_pLines[2].start.x = l;
  284.          lines->m_pLines[2].start.y = b;
  285.          lines->m_pLines[2].finish.x = right;
  286.          lines->m_pLines[2].finish.y = b;
  287.       }
  288.    }
  289.    HXREGION* retRGN = HXCreateRectRegion(l,t,right-l,b-t);
  290.     
  291.    return retRGN;
  292. }
  293. HXREGION* BottomCenterEdgeWipe(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  294. {
  295.    int l = (int) (((double) (left+right)/2 ) - ((double) (right - left)/2 ) * ((double)completeness/1000.0));
  296.    int t = (int) (bottom - ((double) (bottom - top) ) * ((double)completeness/1000.0));
  297.    int r = (int) (((double) (left+right)/2 ) + ((double) (right - left)/2 ) * ((double)completeness/1000.0));
  298.    if (lines)
  299.    {
  300.       lines->m_nLines = 3;
  301.       lines->m_pLines = new LineSegment[3];
  302.       if (!lines->m_pLines)
  303.       {
  304.          lines->m_nLines = 0;
  305.       }
  306.       else
  307.       {
  308.          lines->m_pLines[0].start.x = l;
  309.          lines->m_pLines[0].start.y = bottom;
  310.          lines->m_pLines[0].finish.x = l;
  311.          lines->m_pLines[0].finish.y = t;
  312.          lines->m_pLines[1].start.x = l;
  313.          lines->m_pLines[1].start.y = t;
  314.          lines->m_pLines[1].finish.x = r;
  315.          lines->m_pLines[1].finish.y = t;
  316.          lines->m_pLines[2].start.x = r;
  317.          lines->m_pLines[2].start.y = t;
  318.          lines->m_pLines[2].finish.x = r;
  319.          lines->m_pLines[2].finish.y = bottom;
  320.       }
  321.    }
  322.    HXREGION* retRGN = HXCreateRectRegion(l,t,r-l,bottom-t);
  323.     
  324.    return retRGN;
  325. }
  326. HXREGION* LeftCenterEdgeWipe(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  327. {
  328.    int t = (int) (((double) (top+bottom)/2 ) - ((double) (bottom - top)/2 ) * ((double)completeness/1000.0));
  329.    int r = (int) (left + ((double) (right - left) ) * ((double)completeness/1000.0));
  330.    int b = (int) (((double) (top+bottom)/2 ) + ((double) (bottom - top)/2 ) * ((double)completeness/1000.0));
  331.    if (lines)
  332.    {
  333.       lines->m_nLines = 3;
  334.       lines->m_pLines = new LineSegment[3];
  335.       if (!lines->m_pLines)
  336.       {
  337.          lines->m_nLines = 0;
  338.       }
  339.       else
  340.       {
  341.          lines->m_pLines[0].start.x = left;
  342.          lines->m_pLines[0].start.y = t;
  343.          lines->m_pLines[0].finish.x = r;
  344.          lines->m_pLines[0].finish.y = t;
  345.          lines->m_pLines[1].start.x = r;
  346.          lines->m_pLines[1].start.y = t;
  347.          lines->m_pLines[1].finish.x = r;
  348.          lines->m_pLines[1].finish.y = b;
  349.          lines->m_pLines[2].start.x = r;
  350.          lines->m_pLines[2].start.y = b;
  351.          lines->m_pLines[2].finish.x = left;
  352.          lines->m_pLines[2].finish.y = b;
  353.       }
  354.    }
  355.    HXREGION* retRGN = HXCreateRectRegion(left,t,r-left,b-t);
  356.     
  357.    return retRGN;
  358. }
  359. HXREGION* DiagonalLeftDownEdgeWipe(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  360. {
  361.    HXREGION* retRGN = HXCreateRectRegion(left, top, right-left, bottom-top);
  362.    HXxPoint points[4];
  363.         
  364.    points[0].x = left;
  365.    points[0].y = top;
  366.    points[1].x = left + ((right - left) * completeness * 2)/ 1000;
  367.    points[1].y = top;
  368.    points[2].x = left;
  369.    points[2].y = top + ((bottom - top) * completeness * 2)/ 1000;
  370.    if (lines)
  371.    {
  372.       lines->m_nLines = 1;
  373.       lines->m_pLines = new LineSegment[1];
  374.       if (!lines->m_pLines)
  375.       {
  376.          lines->m_nLines = 0;
  377.       }
  378.       else
  379.       {
  380.          lines->m_pLines->start.x = points[1].x;
  381.          lines->m_pLines->start.y = points[1].y;
  382.          lines->m_pLines->finish.x = points[2].x;
  383.          lines->m_pLines->finish.y = points[2].y;
  384.       }
  385.    }
  386.         
  387.    HXREGION* tempRGN = HXPolygonRegion( points, 3, WindingRule);
  388.         
  389.    HXCombineRgn(retRGN, retRGN, tempRGN, HX_RGN_AND);
  390.    HXDestroyRegion(tempRGN);
  391.    return retRGN;
  392. }
  393. HXREGION* DiagonalRightDownEdgeWipe(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  394. {
  395.    HXREGION* retRGN = HXCreateRectRegion(left, top, right-left, bottom-top);
  396.    HXxPoint points[4];
  397.         
  398.    points[0].x = right;
  399.    points[0].y = top;
  400.    points[1].x = right - ((right - left) * completeness * 2)/ 1000;
  401.    points[1].y = top;
  402.    points[2].x = right;
  403.    points[2].y = top + ((bottom - top) * completeness * 2)/ 1000;
  404.         
  405.    if (lines)
  406.    {
  407.       lines->m_nLines = 1;
  408.       lines->m_pLines = new LineSegment[1];
  409.       if (!lines->m_pLines)
  410.       {
  411.          lines->m_nLines = 0;
  412.       }
  413.       else
  414.       {
  415.          lines->m_pLines->start.x = points[1].x;
  416.          lines->m_pLines->start.y = points[1].y;
  417.          lines->m_pLines->finish.x = points[2].x;
  418.          lines->m_pLines->finish.y = points[2].y;
  419.       }
  420.    }
  421.         
  422.    HXREGION* tempRGN = HXPolygonRegion( points, 3, WindingRule);
  423.         
  424.    HXCombineRgn(retRGN, retRGN, tempRGN, HX_RGN_AND);
  425.    HXDestroyRegion(tempRGN);
  426.    return retRGN;
  427. }
  428. HXREGION* HalfBowTieEdgeWipe(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  429. {
  430.    HXREGION* retRGN = NULL;
  431.    HXxPoint points[5];
  432.    if (completeness < 500)
  433.    {
  434.       points[0].x = left;
  435.       points[0].y = top;
  436.       points[1].x = (int) ((right + left) / 2 - ((double)(right - left)) * (double)completeness / 1000.0);
  437.       points[1].y = top;
  438.       points[2].x = points[1].x + (right + left) / 2;
  439.       points[2].y = (top + bottom) / 2;
  440.       points[3].x = points[1].x;
  441.       points[3].y = bottom;
  442.       points[4].x = left;
  443.       points[4].y = bottom;
  444.       if (lines)
  445.       {
  446.          lines->m_nLines = 2;
  447.          lines->m_pLines = new LineSegment[2];
  448.          if (!lines->m_pLines)
  449.          {
  450.             lines->m_nLines = 0;
  451.          }
  452.          else
  453.          {
  454.             lines->m_pLines[0].start.x = points[1].x;
  455.             lines->m_pLines[0].start.y = points[1].y;
  456.             lines->m_pLines[0].finish.x = points[2].x;
  457.             lines->m_pLines[0].finish.y = points[2].y;
  458.             lines->m_pLines[1].start.x = points[2].x;
  459.             lines->m_pLines[1].start.y = points[2].y;
  460.             lines->m_pLines[1].finish.x = points[3].x;
  461.             lines->m_pLines[1].finish.y = points[3].y;
  462.          }
  463.       }
  464.       retRGN = InvertRGN(HXPolygonRegion(points, 5, WindingRule),left, top, right, bottom);
  465.    }
  466.    else
  467.    {
  468.       int vOffset = (int)((bottom - top) / 2 * (double)(completeness - 500) / 500.0);
  469.       points[0].x = left;
  470.       points[0].y = top + vOffset;
  471.       points[1].x = (right + left) / 2 - (int)((left + right) / 2 * (double)(completeness - 500) / 500.0);
  472.       points[1].y = (top + bottom) / 2;
  473.       points[2].x = left;
  474.       points[2].y = bottom - vOffset;
  475.       if (lines)
  476.       {
  477.          lines->m_nLines = 2;
  478.          lines->m_pLines = new LineSegment[2];
  479.          if (!lines->m_pLines)
  480.          {
  481.             lines->m_nLines = 0;
  482.          }
  483.          else
  484.          {
  485.             lines->m_pLines[0].start.x = points[0].x;
  486.             lines->m_pLines[0].start.y = points[0].y;
  487.             lines->m_pLines[0].finish.x = points[1].x;
  488.             lines->m_pLines[0].finish.y = points[1].y;
  489.             lines->m_pLines[1].start.x = points[1].x;
  490.             lines->m_pLines[1].start.y = points[1].y;
  491.             lines->m_pLines[1].finish.x = points[2].x;
  492.             lines->m_pLines[1].finish.y = points[2].y;
  493.          }
  494.       }
  495.       retRGN = InvertRGN(HXPolygonRegion(points, 3, WindingRule),left, top, right, bottom);
  496.    }
  497.    return retRGN;
  498. }
  499. HXREGION* VerticalBowTieEdgeWipe(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  500. {
  501.    HXREGION* retRGN = HalfBowTieEdgeWipe(left, top, right, bottom, completeness,  NULL);
  502.    HXREGION* tempRGN = MirrorVertical(HalfBowTieEdgeWipe(left, top, right, bottom, completeness,lines),(left + right) / 2);
  503.    HXCombineRgn(retRGN, retRGN, tempRGN, HX_RGN_AND);
  504.    HXDestroyRegion(tempRGN);
  505.    if (lines)
  506.    {
  507.       tranLines tmpLines;
  508.       tmpLines += *lines;
  509.       MirrorVertical(&tmpLines,(left + right) / 2);
  510.       *lines += tmpLines;
  511.    }
  512.    return retRGN;
  513. }
  514. HXREGION* HorizontalBowTieEdgeWipe(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  515. {
  516.    HXREGION* retRGN = InvertRGN(VerticalBowTieEdgeWipe(left, top, right, bottom, 1000 - completeness,lines), left, top, right, bottom);
  517.    if (lines && lines->m_nLines == 4)
  518.    {
  519.       MirrorHorizontal(lines,(top + bottom) / 2);
  520.       lines->m_pLines[0].Clip(left,top,(right + left) / 2, bottom);
  521.       lines->m_pLines[1].Clip(left,top,(right + left) / 2, bottom);
  522.       lines->m_pLines[2].Clip((right + left) / 2,top,right, bottom);
  523.       lines->m_pLines[3].Clip((right + left) / 2,top,right, bottom);
  524.    }
  525.    return retRGN;
  526. }
  527. HXREGION* DiagonaLeftOutEdgeWipe(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  528. {
  529.    HXxPoint points[6];
  530.         
  531.    points[0].x = (int) (right - ((double)(right - left)) * ((double)completeness / 1000.0));
  532.    points[0].y = top;
  533.    points[1].x = right;
  534.    points[1].y = top;
  535.    points[2].x = right;
  536.    points[2].y = (int) (top + ((double)(bottom - top)) * ((double)completeness/ 1000.0));
  537.    points[3].x = (int) (left + ((double)(right - left)) * ((double)completeness/ 1000.0));
  538.    points[3].y = bottom;
  539.    points[4].x = left;
  540.    points[4].y = bottom;
  541.    points[5].x = left;
  542.    points[5].y = (int) (bottom - ((double)(bottom - top)) * ((double)completeness/ 1000.0));
  543.         
  544.    if (lines)
  545.    {
  546.       lines->m_nLines = 2;
  547.       lines->m_pLines = new LineSegment[2];
  548.       if (!lines->m_pLines)
  549.       {
  550.          lines->m_nLines = 0;
  551.       }
  552.       else
  553.       {
  554.          lines->m_pLines[0].start.x = points[0].x;
  555.          lines->m_pLines[0].start.y = points[0].y;
  556.          lines->m_pLines[0].finish.x = points[5].x;
  557.          lines->m_pLines[0].finish.y = points[5].y;
  558.          lines->m_pLines[1].start.x = points[2].x;
  559.          lines->m_pLines[1].start.y = points[2].y;
  560.          lines->m_pLines[1].finish.x = points[3].x;
  561.          lines->m_pLines[1].finish.y = points[3].y;
  562.       }
  563.    }
  564.    return HXPolygonRegion(points, 6, WindingRule);
  565. }
  566. HXREGION* DiagonaRightOutEdgeWipe(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  567. {
  568.    HXREGION* retRGN = DiagonaLeftOutEdgeWipe(left,top,right,bottom,completeness,lines);
  569.    if (lines)
  570.       MirrorVertical(lines,(right - left) / 2);
  571.    return MirrorVertical(retRGN,(right - left) / 2);
  572. }
  573. HXREGION* DiagonaCrossEdgeWipe(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  574. {
  575.    LineSegment ls;
  576.    HXxPoint p[16];
  577.    int xOff = int(double(right - left) / 2000.0 * completeness);
  578.    int yOff = int(double(bottom - top) / 2000.0 * completeness);
  579.    int midX = (right + left) / 2;
  580.    int midY = (bottom + top) / 2;
  581.    p[0].x = left + xOff;
  582.    p[0].y = top;
  583.    p[1].x = midX;
  584.    p[1].y = midY - yOff;
  585.    p[2].x = right - xOff;
  586.    p[2].y = top;
  587.    p[3].x = right;
  588.    p[3].y = top;
  589.    if (lines)
  590.    {
  591.       ls.start.x = p[0].x;
  592.       ls.start.y = p[0].y;
  593.       ls.finish.x = p[1].x;
  594.       ls.finish.y = p[1].y;
  595.       *lines += ls;
  596.       ls.start.x = p[2].x;
  597.       ls.start.y = p[2].y;
  598.       ls.finish.x = p[1].x;
  599.       ls.finish.y = p[1].y;
  600.       *lines += ls;
  601.    }
  602.    p[4].x = right;
  603.    p[4].y = top + yOff;
  604.    p[5].x = midX + xOff;
  605.    p[5].y = midY;
  606.    p[6].x = right;
  607.    p[6].y = bottom - yOff;
  608.    p[7].x = right;
  609.    p[7].y = bottom;
  610.    if (lines)
  611.    {
  612.       ls.start.x = p[4].x;
  613.       ls.start.y = p[4].y;
  614.       ls.finish.x = p[5].x;
  615.       ls.finish.y = p[5].y;
  616.       *lines += ls;
  617.       ls.start.x = p[6].x;
  618.       ls.start.y = p[6].y;
  619.       ls.finish.x = p[5].x;
  620.       ls.finish.y = p[5].y;
  621.       *lines += ls;
  622.    }
  623.         
  624.    p[8].x = right - xOff;
  625.    p[8].y = bottom;
  626.    p[9].x = midX;
  627.    p[9].y = midY + yOff;
  628.    p[10].x = left + xOff;
  629.    p[10].y = bottom;
  630.    p[11].x = left;
  631.    p[11].y = bottom;
  632.    if (lines)
  633.    {
  634.       ls.start.x = p[8].x;
  635.       ls.start.y = p[8].y;
  636.       ls.finish.x = p[9].x;
  637.       ls.finish.y = p[9].y;
  638.       *lines += ls;
  639.       ls.start.x = p[10].x;
  640.       ls.start.y = p[10].y;
  641.       ls.finish.x = p[9].x;
  642.       ls.finish.y = p[9].y;
  643.       *lines += ls;
  644.    }
  645.    p[12].x = left;
  646.    p[12].y = bottom - yOff;
  647.    p[13].x = midX - xOff;
  648.    p[13].y = midY;
  649.    p[14].x = left;
  650.    p[14].y = top + yOff;
  651.    p[15].x = left;
  652.    p[15].y = top;
  653.    if (lines)
  654.    {
  655.       ls.start.x = p[12].x;
  656.       ls.start.y = p[12].y;
  657.       ls.finish.x = p[13].x;
  658.       ls.finish.y = p[13].y;
  659.       *lines += ls;
  660.       ls.start.x = p[14].x;
  661.       ls.start.y = p[14].y;
  662.       ls.finish.x = p[13].x;
  663.       ls.finish.y = p[13].y;
  664.       *lines += ls;
  665.    }
  666.         
  667.    return HXPolygonRegion(p, 16, WindingRule);
  668. }
  669. HXREGION* DiagonalBoxEdgeWipe(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  670. {
  671.    tranLines* tmpLines = NULL;
  672.    if (lines)
  673.       tmpLines = new tranLines;
  674.    HXREGION* retRGN = DiamondIris(left, top, right, bottom, completeness/2+500,lines);
  675.    HXREGION* rgn1 = DiamondIris(left, top, right, bottom, 500 - completeness/2,tmpLines);
  676.    HXCombineRgn(retRGN, retRGN, rgn1, HX_RGN_XOR);
  677.    HXDestroyRegion(rgn1);
  678.    if (lines)
  679.    {
  680.       *lines += *tmpLines;
  681.       delete tmpLines;
  682.    }
  683.         
  684.    return retRGN;
  685. }
  686. HXREGION* FilledVEdgeWipe(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  687. {
  688.    HXxPoint points[3];
  689.         
  690.    points[0].x = (int) ((right+left)/2 + ((double)(right - left)) * (  (double)completeness/ 1000.0));
  691.    points[0].y = top;
  692.    points[1].x = (int) ((right+left)/2 - ((double)(right - left)) * (  (double)completeness/ 1000.0));
  693.    points[1].y = top;
  694.    points[2].x = (right+left)/2;
  695.    points[2].y = (int) (top + ((double)(bottom - top)) * 2.0  * ( (double)completeness/ 1000.0));
  696.         
  697.    if (lines)
  698.    {
  699.       lines->m_nLines = 2;
  700.       lines->m_pLines = new LineSegment[2];
  701.       if (!lines->m_pLines)
  702.       {
  703.          lines->m_nLines = 0;
  704.       }
  705.       else
  706.       {
  707.          lines->m_pLines[0].start.x = points[0].x;
  708.          lines->m_pLines[0].start.y = points[0].y;
  709.          lines->m_pLines[0].finish.x = points[2].x;
  710.          lines->m_pLines[0].finish.y = points[2].y;
  711.          lines->m_pLines[1].start.x = points[1].x;
  712.          lines->m_pLines[1].start.y = points[1].y;
  713.          lines->m_pLines[1].finish.x = points[2].x;
  714.          lines->m_pLines[1].finish.y = points[2].y;
  715.       }
  716.    }
  717.    return HXPolygonRegion( points, 3, WindingRule);
  718. }
  719. HXREGION* FilledVRightEdgeWipe(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  720. {
  721.    HXxPoint points[3];
  722.         
  723.    points[0].x = right; 
  724.    points[0].y = (int) ((bottom+top)/2 + ((double)(bottom - top)) * (  (double)completeness/ 1000.0));
  725.    points[1].x = right; 
  726.    points[1].y = (int) ((bottom+top)/2 - ((double)(bottom - top)) * (  (double)completeness/ 1000.0));
  727.    points[2].x = (int) (right - ((double)(right - top)) * 2.0  * ( (double)completeness/ 1000.0));
  728.    points[2].y = (bottom+top)/2;
  729.         
  730.    if (lines)
  731.    {
  732.       lines->m_nLines = 2;
  733.       lines->m_pLines = new LineSegment[2];
  734.       if (!lines->m_pLines)
  735.       {
  736.          lines->m_nLines = 0;
  737.       }
  738.       else
  739.       {
  740.          lines->m_pLines[0].start.x = points[0].x;
  741.          lines->m_pLines[0].start.y = points[0].y;
  742.          lines->m_pLines[0].finish.x = points[2].x;
  743.          lines->m_pLines[0].finish.y = points[2].y;
  744.          lines->m_pLines[1].start.x = points[1].x;
  745.          lines->m_pLines[1].start.y = points[1].y;
  746.          lines->m_pLines[1].finish.x = points[2].x;
  747.          lines->m_pLines[1].finish.y = points[2].y;
  748.       }
  749.    }
  750.    return HXPolygonRegion( points, 3, WindingRule);
  751. }
  752. HXREGION* FilledVBottomEdgeWipe(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  753. {
  754.    HXREGION* retRgn = FilledVEdgeWipe(left,top,right,bottom,completeness,lines);
  755.    if (lines)
  756.       MirrorHorizontal(lines,(top + bottom) / 2);
  757.    return MirrorHorizontal(retRgn,(top + bottom) / 2);
  758. }
  759. HXREGION* FilledVLeftEdgeWipe(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  760. {
  761.    HXREGION* retRgn = FilledVRightEdgeWipe(left,top,right,bottom,completeness,lines);
  762.    if (lines)
  763.       MirrorVertical(lines,(left + right) / 2);
  764.    return MirrorVertical(retRgn,(left + right) / 2);
  765. }
  766. HXREGION* HollowVEdgeWipe(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  767. {
  768.    tranLines* tmp = NULL;
  769.    if (lines)
  770.       tmp = new tranLines;
  771.    HXREGION* retRGN = FilledVEdgeWipe(left, top, right, bottom, 500+ completeness/2,lines);
  772.    HXREGION* rgn1 = FilledVEdgeWipe(left, top, right, bottom, 500 - completeness/2,tmp);
  773.    if (lines)
  774.    {
  775.       *lines += *tmp;
  776.       delete tmp;
  777.    }
  778.         
  779.    HXCombineRgn(retRGN, retRGN, rgn1, HX_RGN_XOR);
  780.    HXDestroyRegion(rgn1);
  781.         
  782.    return retRGN;
  783. }
  784. HXREGION* HollowVRightEdgeWipe(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  785. {
  786.    tranLines* tmp = NULL;
  787.    if (lines)
  788.       tmp = new tranLines;
  789.    HXREGION* retRGN = FilledVRightEdgeWipe(left, top, right, bottom, 500+ completeness/2,lines);
  790.    HXREGION* rgn1 = FilledVRightEdgeWipe(left, top, right, bottom, 500 - completeness/2,tmp);
  791.         
  792.    if (lines)
  793.    {
  794.       *lines += *tmp;
  795.       delete tmp;
  796.    }
  797.         
  798.    HXCombineRgn(retRGN, retRGN, rgn1, HX_RGN_XOR);
  799.    HXDestroyRegion(rgn1);
  800.         
  801.    return retRGN;
  802. }
  803. HXREGION* HollowVLeftEdgeWipe(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  804. {
  805.    HXREGION* retRgn = HollowVRightEdgeWipe(left,top,right,bottom,completeness,lines);
  806.    if (lines)
  807.       MirrorVertical(lines,(left + right) / 2);
  808.    return MirrorVertical(retRgn,(left + right) / 2);
  809. }
  810. HXREGION* HollowVBottomEdgeWipe(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  811. {
  812.    HXREGION* retRgn = HollowVEdgeWipe(left,top,right,bottom,completeness,lines);
  813.    if (lines)
  814.       MirrorHorizontal(lines,(top + bottom) / 2);
  815.    return MirrorHorizontal(retRgn,(top + bottom) / 2);
  816. }
  817. HXREGION* VerticalZigZagEdgeWipe(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  818. {
  819.    int width = right - left;
  820.         
  821.    if (!width)
  822.       ++width;
  823.         
  824.    HXxPoint points[13];
  825.    // this is the width of the zigzag portion
  826.    int zigzag = (int) ((float)(bottom - top + 1) / 10.0+.5);
  827.    int tmpCompleteness = (int) ((float)completeness * (float)(right - left + zigzag + 1) / (float)width+.5);
  828.         
  829.    points[0].x = left - zigzag;
  830.    points[0].y = top;
  831.    points[1].x = left + (width * tmpCompleteness) / 1000 - zigzag;
  832.    points[1].y = top;
  833.         
  834.    for(int i = 1; i< 11; i++)
  835.    {
  836.       points[i+1].x = left + (width * tmpCompleteness) / 1000 - !(i & 1) * zigzag;
  837.       points[i+1].y = top + zigzag * i;
  838.    }
  839.         
  840.    points[12].x = left-zigzag;
  841.    points[12].y = bottom;
  842.         
  843.    if (lines)
  844.    {
  845.       lines->m_nLines = 10;
  846.       lines->m_pLines = new LineSegment[10];
  847.       if (!lines->m_pLines)
  848.       {
  849.          lines->m_nLines = 0;
  850.       }
  851.       else
  852.       {
  853.          for(int i = 1; i < 11; i++)
  854.          {
  855.             lines->m_pLines[i-1].start.x = points[i].x;
  856.             lines->m_pLines[i-1].start.y = points[i].y;
  857.             lines->m_pLines[i-1].finish.x = points[i + 1].x;
  858.             lines->m_pLines[i-1].finish.y = points[i + 1].y;
  859.          }
  860.       }
  861.    }
  862.         
  863.    return HXPolygonRegion( points, 13, WindingRule);
  864. }
  865. HXREGION* HorizontalZigZagEdgeWipe(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  866. {
  867.    // this is the height of the zigzag portion
  868.    int height = bottom - top;
  869.         
  870.    if (!height)
  871.       ++height;
  872.         
  873.    int zigzag = (int)(((float)right - (float)left) / 10.0 +.5);
  874.    int tmpCompleteness = completeness * (bottom - top + zigzag + 1) / height;
  875.    int worknow = (int)(((float)height * (float)tmpCompleteness) / 1000.0 +.5);
  876.    
  877.    HXxPoint points[13];
  878.         
  879.    points[0].x = left;
  880.    points[0].y = top - zigzag;
  881.    points[1].x = left;
  882.    points[1].y = top  + worknow - zigzag;
  883.         
  884.    for(int i = 1; i< 11; i++)
  885.    {
  886.       points[i+1].y = top + worknow - !(i & 1) * zigzag;
  887.       points[i+1].x = left + zigzag * i ;
  888.    }
  889.         
  890.    points[12].x = right;
  891.    points[12].y = top  - zigzag;
  892.         
  893.    if (lines)
  894.    {
  895.       lines->m_nLines = 10;
  896.       lines->m_pLines = new LineSegment[10];
  897.       if (!lines->m_pLines)
  898.       {
  899.          lines->m_nLines = 0;
  900.       }
  901.       else
  902.       {
  903.          for(int i = 1; i < 11; i++)
  904.          {
  905.             lines->m_pLines[i-1].start.x = points[i].x;
  906.             lines->m_pLines[i-1].start.y = points[i].y;
  907.             lines->m_pLines[i-1].finish.x = points[i + 1].x;
  908.             lines->m_pLines[i-1].finish.y = points[i + 1].y;
  909.          }
  910.       }
  911.    }
  912.         
  913.    return HXPolygonRegion( points, 13, WindingRule);
  914. }
  915. HXREGION* HorizontalBarnZigZagEdgeWipe(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  916. {
  917.    tranLines* tmp = NULL;
  918.    if (lines)
  919.       tmp = new tranLines;
  920.    HXREGION* retRGN = HorizontalZigZagEdgeWipe(left, top, right, bottom, (int) (500 - (double)completeness/2),lines);
  921.    HXREGION* rgn1 = HorizontalZigZagEdgeWipe(left, top, right, bottom, 500 + completeness/2,tmp);
  922.    HXCombineRgn(retRGN, retRGN, rgn1, HX_RGN_XOR);
  923.    HXDestroyRegion(rgn1);
  924.    if (lines)
  925.    {
  926.       *lines += *tmp;
  927.       delete tmp;
  928.    }
  929.    return retRGN;
  930. }
  931. HXREGION* VerticalBarnZigZagEdgeWipe(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  932. {
  933.    tranLines* tmp = NULL;
  934.    if (lines)
  935.       tmp = new tranLines;
  936.    HXREGION* retRGN = VerticalZigZagEdgeWipe(left, top, right, bottom, (int) (500 - (double)completeness/2),lines);
  937.    HXREGION* rgn1 = VerticalZigZagEdgeWipe(left, top, right, bottom, 500 + completeness/2,tmp);
  938.    HXCombineRgn(retRGN, retRGN, rgn1, HX_RGN_XOR);
  939.    HXDestroyRegion(rgn1);
  940.    if (lines)
  941.    {
  942.       *lines += *tmp;
  943.       delete tmp;
  944.    }
  945.    return retRGN;
  946. }
  947. HXREGION* InternalRotatingTopRadial(int left, int top, int right, int bottom, int completeness = NULL, tranLines* lines = NULL)
  948. {
  949.    HXxPoint points[8];
  950.         
  951.    points[0].x = (left+right)/2;
  952.    points[0].y = (top+bottom)/2;
  953.    points[1].x = points[0].x; //(left+right)/2;
  954.    points[1].y = top;
  955.    int count = 2;
  956.    for(int temp = completeness; temp >= 125; temp-=250)
  957.    {
  958.       points[count].x = count < 4 ? right : left;
  959.       points[count].y = (count>2) && (count<5) ? bottom : top;
  960.       count++;
  961.    }
  962.         
  963.    double r = max(right - left, bottom - top);
  964.    r*=2.0;
  965.         
  966.    double angle = ((double)completeness/1000.0) * PI * 2.0;
  967.    points[count].x = (left+right)/2 + (int) (r * sin(angle));
  968.    points[count].y = (top+bottom)/2 - (int) (r * cos(angle));
  969.    count++;
  970.         
  971.    HXREGION* retRGN  = HXPolygonRegion( points, count, WindingRule);
  972.    if (lines)
  973.    {
  974.       lines->m_nLines = 1;
  975.       lines->m_pLines = new LineSegment[1];
  976.       lines->m_pLines->start.x = points[0].x;
  977.       lines->m_pLines->start.y = points[0].y;
  978.       lines->m_pLines->finish.x = points[count-1].x;
  979.       lines->m_pLines->finish.y = points[count-1].y;
  980.    }
  981.         
  982.    return retRGN;
  983. }
  984. HXREGION* RotatingTopRadial(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  985. {
  986.    HXREGION* retRGN = InternalRotatingTopRadial(left, top, right, bottom, completeness, lines);
  987.    if (lines)
  988.    {
  989.       LineSegment ls;
  990.       ls.start.x = (left + right) / 2;
  991.       ls.start.y = (top + bottom) / 2;
  992.       ls.finish.x = ls.start.x;
  993.       ls.finish.y = top;
  994.       *lines += ls;
  995.    }
  996.    return retRGN;
  997. }
  998. HXREGION* InternalRotatingRightRadial(int left, int top, int right, int bottom, int completeness, tranLines* lines = NULL)
  999. {
  1000.    HXREGION* retRGN = InternalRotatingTopRadial(left, top, right, bottom, (completeness+250)> 1000 ? 1000: completeness+250,lines);
  1001.    HXREGION* rgn1 = InternalRotatingTopRadial(left, top, right, bottom, 250);
  1002.    HXCombineRgn(retRGN, retRGN, rgn1, HX_RGN_DIFF);
  1003.    HXDestroyRegion(rgn1);
  1004.         
  1005.    if (completeness > 750)
  1006.    {
  1007.       if (lines)
  1008.       {
  1009.          lines->Destroy(); // need to remove the ones we put in by the 1st call to IRTR()
  1010.       }
  1011.       HXREGION* rgn1 = InternalRotatingTopRadial(left, top, right, bottom, completeness - 750,  lines);
  1012.       HXCombineRgn(retRGN, retRGN, rgn1, HX_RGN_OR);
  1013.       HXDestroyRegion(rgn1);
  1014.    }
  1015.         
  1016.    return retRGN;
  1017. }
  1018. HXREGION* RotatingRightRadial(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  1019. {
  1020.    HXREGION* retRGN = InternalRotatingRightRadial(left, top, right, bottom, completeness,lines);
  1021.    if (lines)
  1022.    {
  1023.       LineSegment ls;
  1024.       ls.start.x = (left + right) / 2;
  1025.       ls.start.y = (top + bottom) / 2;
  1026.       ls.finish.x = right;
  1027.       ls.finish.y = ls.start.y;
  1028.       *lines += ls;
  1029.    }
  1030.    return retRGN;
  1031. }
  1032. HXREGION* InternalRotatingBottomRadial(int left, int top, int right, int bottom, int completeness, tranLines* lines = NULL)
  1033. {
  1034.    HXREGION* retRGN = InternalRotatingTopRadial(left, top, right, bottom, (completeness+500)> 1000 ? 1000: completeness+500, lines);
  1035.    HXREGION* rgn1 = InternalRotatingTopRadial(left, top, right, bottom, 500);
  1036.    HXCombineRgn(retRGN, retRGN, rgn1, HX_RGN_DIFF);
  1037.    HXDestroyRegion(rgn1);
  1038.         
  1039.    if (completeness > 500)
  1040.    {
  1041.       if (lines)
  1042.       {
  1043.          lines->Destroy(); // need to remove the ones we put in by the 1st call to IRTR()
  1044.       }
  1045.       HXREGION* rgn1 = InternalRotatingTopRadial(left, top, right, bottom, completeness - 500, lines);
  1046.       HXCombineRgn(retRGN, retRGN, rgn1, HX_RGN_OR);
  1047.       HXDestroyRegion(rgn1);
  1048.    }
  1049.         
  1050.    return retRGN;
  1051. }
  1052. HXREGION* RotatingBottomRadial(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  1053. {
  1054.    HXREGION* retRGN = InternalRotatingBottomRadial(left, top, right, bottom, completeness,lines);
  1055.    if (lines)
  1056.    {
  1057.       LineSegment ls;
  1058.       ls.start.x = (left + right) / 2;
  1059.       ls.start.y = (top + bottom) / 2;
  1060.       ls.finish.x = ls.start.x;
  1061.       ls.finish.y = bottom;
  1062.       *lines += ls;
  1063.    }
  1064.    return retRGN;
  1065. }
  1066. HXREGION* InternalRotatingLeftRadial(int left, int top, int right, int bottom, int completeness, tranLines* lines = NULL)
  1067. {
  1068.    HXREGION* retRGN = InternalRotatingTopRadial(left, top, right, bottom, (completeness+750)> 1000 ? 1000: completeness+750, lines);
  1069.    HXREGION* rgn1 = InternalRotatingTopRadial(left, top, right, bottom, 750);
  1070.    HXCombineRgn(retRGN, retRGN, rgn1, HX_RGN_DIFF);
  1071.    HXDestroyRegion(rgn1);
  1072.         
  1073.    if (completeness > 250)
  1074.    {
  1075.       if (lines)
  1076.       {
  1077.          lines->Destroy(); // need to remove the ones we put in by the 1st call to IRTR()
  1078.       }
  1079.       HXREGION* rgn1 = InternalRotatingTopRadial(left, top, right, bottom, completeness - 250, lines);
  1080.       HXCombineRgn(retRGN, retRGN, rgn1, HX_RGN_OR);
  1081.       HXDestroyRegion(rgn1);
  1082.    }
  1083.         
  1084.    return retRGN;
  1085. }
  1086. HXREGION* RotatingLeftRadial(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  1087. {
  1088.    HXREGION* retRGN = InternalRotatingLeftRadial(left, top, right, bottom, completeness,lines);
  1089.    if (lines)
  1090.    {
  1091.       LineSegment ls;
  1092.       ls.start.x = (left + right) / 2;
  1093.       ls.start.y = (top + bottom) / 2;
  1094.       ls.finish.x = left;
  1095.       ls.finish.y = ls.start.y;
  1096.       *lines += ls;
  1097.    }
  1098.    return retRGN;
  1099. }
  1100. HXREGION* RotatingTopBottomRadial(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  1101. {
  1102.    tranLines* tmpLines = NULL;
  1103.    if (lines)
  1104.       tmpLines = new tranLines;
  1105.    HXREGION* rgn1 = InternalRotatingTopRadial(left, top, right, bottom, completeness/2, lines);
  1106.    HXREGION* retRGN = InternalRotatingBottomRadial(left, top, right, bottom, completeness/2, tmpLines);
  1107.    if (lines)
  1108.    {
  1109.       *lines += *tmpLines;
  1110.       delete tmpLines;
  1111.       LineSegment ls;
  1112.       ls.start.x = (left + right) / 2;
  1113.       ls.start.y = top;
  1114.       ls.finish.x = ls.start.x;
  1115.       ls.finish.y = bottom;
  1116.       *lines += ls;
  1117.    }
  1118.         
  1119.    HXCombineRgn(retRGN, retRGN, rgn1, HX_RGN_OR);
  1120.    HXDestroyRegion(rgn1);
  1121.    return retRGN;
  1122. }
  1123. HXREGION* RotatingLeftRightRadial(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  1124. {
  1125.    tranLines* tmpLines = NULL;
  1126.    if (lines)
  1127.       tmpLines = new tranLines;
  1128.    HXREGION* rgn1 = InternalRotatingLeftRadial(left, top, right, bottom, completeness/2,  lines);
  1129.    HXREGION* retRGN = InternalRotatingRightRadial(left, top, right, bottom, completeness/2,  tmpLines);
  1130.         
  1131.    if (lines)
  1132.    {
  1133.       *lines += *tmpLines;
  1134.       delete tmpLines;
  1135.       LineSegment ls;
  1136.       ls.start.x = left;
  1137.       ls.start.y = (top + bottom) / 2;
  1138.       ls.finish.x = right;
  1139.       ls.finish.y = ls.start.y;
  1140.       *lines += ls;
  1141.    }
  1142.         
  1143.    HXCombineRgn(retRGN, retRGN, rgn1, HX_RGN_OR);
  1144.    HXDestroyRegion(rgn1);
  1145.    return retRGN;
  1146. }
  1147. HXREGION* RotatingQuadrantRadial(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  1148. {
  1149.    tranLines* tmpLines = NULL;
  1150.    if (lines)
  1151.       tmpLines = new tranLines;
  1152.    HXREGION* rgn1 = InternalRotatingLeftRadial(left, top, right, bottom, completeness/4,  lines);
  1153.    HXREGION* retRGN = InternalRotatingRightRadial(left, top, right, bottom, completeness/4,  tmpLines);
  1154.    HXCombineRgn(retRGN, retRGN, rgn1, HX_RGN_OR);
  1155.    HXDestroyRegion(rgn1);
  1156.    if (lines)
  1157.    {
  1158.       *lines += *tmpLines;
  1159.       delete tmpLines;
  1160.       tmpLines = new tranLines;
  1161.    }
  1162.         
  1163.    rgn1 = InternalRotatingTopRadial(left, top, right, bottom, completeness/4,  tmpLines);
  1164.    HXCombineRgn(retRGN, retRGN, rgn1, HX_RGN_OR);
  1165.    HXDestroyRegion(rgn1);
  1166.    if (lines)
  1167.    {
  1168.       *lines += *tmpLines;
  1169.       delete tmpLines;
  1170.       tmpLines = new tranLines;
  1171.    }
  1172.         
  1173.    rgn1 = InternalRotatingBottomRadial(left, top, right, bottom, completeness/4,  tmpLines);
  1174.    HXCombineRgn(retRGN, retRGN, rgn1, HX_RGN_OR);
  1175.    HXDestroyRegion(rgn1);
  1176.    if (lines)
  1177.    {
  1178.       *lines += *tmpLines;
  1179.       delete tmpLines;
  1180.       tmpLines = new tranLines;
  1181.       LineSegment ls;
  1182.       ls.start.x = (left + right) / 2;
  1183.       ls.start.y = top;
  1184.       ls.finish.x = ls.start.x;
  1185.       ls.finish.y = bottom;
  1186.       *lines += ls;
  1187.       ls.start.x = left;
  1188.       ls.start.y = (top + bottom) / 2;
  1189.       ls.finish.x = right;
  1190.       ls.finish.y = ls.start.y;
  1191.       *lines += ls;
  1192.    }
  1193.    return retRGN;
  1194. }
  1195. HXREGION* TopBottom180Radial(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  1196. {
  1197.    tranLines* tmpLines = NULL;
  1198.    if (lines)
  1199.       tmpLines = new tranLines;
  1200.    HXREGION* retRGN = HXCreateRectRegion(left, top, right-left, bottom-top);
  1201.    HXREGION* rgn1 = InternalRotatingTopRadial(left, top, right, bottom, 1000 - completeness / 2,  lines);
  1202.    HXCombineRgn(retRGN, retRGN, rgn1, HX_RGN_DIFF);
  1203.    HXDestroyRegion(rgn1);
  1204.    HXREGION* ret1 = InternalRotatingTopRadial(left, top, right, bottom, completeness / 2,  tmpLines);
  1205.    HXCombineRgn(retRGN, retRGN, ret1, HX_RGN_OR);
  1206.    HXDestroyRegion(ret1);
  1207.         
  1208.    if (lines)
  1209.    {
  1210.       *lines += *tmpLines;
  1211.       delete tmpLines;
  1212.    }
  1213.    return retRGN;
  1214. }
  1215. HXREGION* RightToLeft180Radial(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  1216. {
  1217.    tranLines* tmpLines = NULL;
  1218.    if (lines)
  1219.       tmpLines = new tranLines;
  1220.    HXREGION* retRGN = HXCreateRectRegion(left, top, right-left,bottom-top);
  1221.    HXREGION* rgn1 = InternalRotatingRightRadial(left, top, right, bottom, 1000 - completeness / 2,  lines);
  1222.    HXCombineRgn(retRGN, retRGN, rgn1, HX_RGN_DIFF);
  1223.    HXDestroyRegion(rgn1);
  1224.    HXREGION* ret1 = InternalRotatingRightRadial(left, top, right, bottom, completeness / 2,  tmpLines);
  1225.    HXCombineRgn(retRGN, retRGN, ret1, HX_RGN_OR);
  1226.    HXDestroyRegion(ret1);
  1227.         
  1228.    if (lines)
  1229.    {
  1230.       *lines += *tmpLines;
  1231.       delete tmpLines;
  1232.    }
  1233.    return retRGN;
  1234. }
  1235. HXREGION* topBottom90Radial(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  1236. {
  1237.    tranLines* tmpLines = NULL;
  1238.    if (lines)
  1239.       tmpLines = new tranLines;
  1240.    HXREGION* retRGN= InternalRotatingBottomRadial(left, top, right, bottom, 500 - completeness / 4,  lines);
  1241.    HXREGION* rgn1 = InternalRotatingBottomRadial(left, top, right, bottom, 500+ completeness / 4,  tmpLines);
  1242.    HXCombineRgn(retRGN, rgn1, retRGN, HX_RGN_XOR);
  1243.    HXDestroyRegion(rgn1);
  1244.    if (lines)
  1245.    {
  1246.       *lines += *tmpLines;
  1247.       delete tmpLines;
  1248.       tmpLines = new tranLines;
  1249.    }
  1250.         
  1251.    rgn1 = InternalRotatingTopRadial(left, top, right, bottom, 500 - completeness / 4,  tmpLines);
  1252.    HXCombineRgn(retRGN, rgn1, retRGN, HX_RGN_XOR);
  1253.    HXDestroyRegion(rgn1);
  1254.    if (lines)
  1255.    {
  1256.       *lines += *tmpLines;
  1257.       delete tmpLines;
  1258.       tmpLines = new tranLines;
  1259.    }
  1260.         
  1261.    rgn1 = InternalRotatingTopRadial(left, top, right, bottom, 500+ completeness / 4,  tmpLines);
  1262.    HXCombineRgn(retRGN, rgn1, retRGN, HX_RGN_XOR);
  1263.    HXDestroyRegion(rgn1);
  1264.    if (lines)
  1265.    {
  1266.       *lines += *tmpLines;
  1267.       delete tmpLines;
  1268.       tmpLines = new tranLines;
  1269.    }
  1270.         
  1271.    return retRGN;
  1272. }
  1273. HXREGION* RightToLeft90Radial(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  1274. {
  1275.    tranLines* tmpLines = NULL;
  1276.    if (lines)
  1277.       tmpLines = new tranLines;
  1278.    HXREGION* retRGN= InternalRotatingBottomRadial(left, top, right, bottom, 250 - completeness / 4,  lines);
  1279.    HXREGION* rgn1 = InternalRotatingBottomRadial(left, top, right, bottom, 250+ completeness / 4,  tmpLines);
  1280.    HXCombineRgn(retRGN, rgn1, retRGN, HX_RGN_XOR);
  1281.    HXDestroyRegion(rgn1);
  1282.    if (lines)
  1283.    {
  1284.       *lines += *tmpLines;
  1285.       delete tmpLines;
  1286.       tmpLines = new tranLines;
  1287.    }
  1288.         
  1289.    rgn1 = InternalRotatingTopRadial(left, top, right, bottom, 250 - completeness / 4,  tmpLines);
  1290.    HXCombineRgn(retRGN, rgn1, retRGN, HX_RGN_XOR);
  1291.    HXDestroyRegion(rgn1);
  1292.    if (lines)
  1293.    {
  1294.       *lines += *tmpLines;
  1295.       delete tmpLines;
  1296.       tmpLines = new tranLines;
  1297.    }
  1298.         
  1299.    rgn1 = InternalRotatingTopRadial(left, top, right, bottom, 250+ completeness / 4,  tmpLines);
  1300.    HXCombineRgn(retRGN, rgn1, retRGN, HX_RGN_XOR);
  1301.    HXDestroyRegion(rgn1);
  1302.    if (lines)
  1303.    {
  1304.       *lines += *tmpLines;
  1305.       delete tmpLines;
  1306.       tmpLines = new tranLines;
  1307.    }
  1308.         
  1309.    return retRGN;
  1310. }
  1311. HXREGION* InternalTop180Radial(int left, int top, int right, int bottom, int completeness, tranLines* lines = NULL)
  1312. {
  1313.    return InternalRotatingRightRadial(left, top - (bottom-top), right, bottom, completeness / 2,  lines);
  1314. }
  1315. HXREGION* Top180Radial(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  1316. {
  1317.    return InternalTop180Radial(left, top, right, bottom, completeness,  lines);
  1318. }
  1319. HXREGION* InternalRight180Radial(int left, int top, int right, int bottom, int completeness, tranLines* lines = NULL)
  1320. {
  1321.    HXREGION* retRGN = InternalRotatingBottomRadial(left - (right -left), top, right, bottom, completeness / 2,  lines);
  1322.    HXOffsetRegion(retRGN, (right -left), 0);
  1323.    if (lines)
  1324.       lines->Offset(right - left, 0);
  1325.    return retRGN;
  1326. }
  1327. HXREGION* Right180Radial(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  1328. {
  1329.    return InternalRight180Radial(left, top, right, bottom, completeness,  lines);
  1330. }
  1331. HXREGION* InternalBottom180Radial(int left, int top, int right, int bottom, int completeness, tranLines* lines = NULL)
  1332. {
  1333.    HXREGION* retRGN = InternalRotatingLeftRadial(left, top - (bottom-top), right, bottom, completeness / 2,  lines);
  1334.    HXOffsetRegion(retRGN, 0, bottom - top);
  1335.    if (lines)
  1336.       lines->Offset(0, bottom - top);
  1337.    return retRGN;
  1338. }
  1339. HXREGION* Bottom180Radial(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  1340. {
  1341.    return InternalBottom180Radial(left, top, right, bottom, completeness,  lines);
  1342. }
  1343. HXREGION* InternalLeft180Radial(int left, int top, int right, int bottom, int completeness, tranLines* lines = NULL)
  1344. {
  1345.    return InternalRotatingTopRadial(left - (right -left), top, right, bottom, completeness / 2,  lines);
  1346. }
  1347. HXREGION* Left180Radial(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  1348. {
  1349.    return InternalLeft180Radial(left, top, right, bottom, completeness,  lines);
  1350. }
  1351. HXREGION* CounterRotatingTopBottomRadial(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  1352. {
  1353.    tranLines* tmpLines = NULL;
  1354.    if (lines)
  1355.       tmpLines = new tranLines;
  1356.    HXREGION* retRGN = InternalTop180Radial(left, top, right, bottom, completeness / 2,  lines);
  1357.    HXREGION* rgn1 = InternalBottom180Radial(left, top, right, bottom, completeness / 2,  tmpLines);
  1358.    HXCombineRgn(retRGN, retRGN, rgn1, HX_RGN_OR);
  1359.    HXDestroyRegion(rgn1);
  1360.    if (lines)
  1361.    {
  1362.       *lines += *tmpLines;
  1363.       delete tmpLines;
  1364.    }
  1365.    return retRGN;
  1366. }
  1367. HXREGION* CounterRotatingLeftRightRadial(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  1368. {
  1369.    tranLines* tmpLines = NULL;
  1370.    if (lines)
  1371.       tmpLines = new tranLines;
  1372.    HXREGION* retRGN = InternalLeft180Radial(left, top, right, bottom, completeness / 2,  lines);
  1373.    HXREGION* rgn1 = InternalRight180Radial(left, top, right, bottom, completeness / 2,  tmpLines);
  1374.    HXCombineRgn(retRGN, retRGN, rgn1, HX_RGN_OR);
  1375.    HXDestroyRegion(rgn1);
  1376.    if (lines)
  1377.    {
  1378.       *lines += *tmpLines;
  1379.       delete tmpLines;
  1380.    }
  1381.    return retRGN;
  1382. }
  1383. HXREGION* DoubleRotatingTopBottomRadial(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  1384. {
  1385.    tranLines* tmpLines = NULL;
  1386.    if (lines)
  1387.       tmpLines = new tranLines;
  1388.    HXREGION* retRGN       = InternalBottom180Radial(left, top, right, bottom, 1000 - completeness,lines);
  1389.    HXREGION* rgn1 = HXCreateRectRegion(left, top, right-left,bottom-top);
  1390.    HXCombineRgn(retRGN, rgn1, retRGN, HX_RGN_DIFF);
  1391.    HXDestroyRegion(rgn1);
  1392.    rgn1 = InternalTop180Radial(left, top, right, bottom, completeness, tmpLines);
  1393.    if (completeness > 500)
  1394.       HXCombineRgn(retRGN, retRGN, rgn1, HX_RGN_AND);
  1395.    else
  1396.       HXCombineRgn(retRGN, retRGN, rgn1, HX_RGN_OR);
  1397.    HXDestroyRegion(rgn1);
  1398.    if (lines)
  1399.    {
  1400.       lines->Clip(left,(top + bottom) / 2,right,bottom);
  1401.       tmpLines->Clip(left,top,right,(top + bottom) / 2);
  1402.       *lines += *tmpLines;
  1403.       delete tmpLines;
  1404.    }
  1405.    return retRGN;
  1406. }
  1407. HXREGION* DoubleRotatingLeftRightRadial(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  1408. {
  1409.    tranLines* tmpLines = NULL;
  1410.    if (lines)
  1411.       tmpLines = new tranLines;
  1412.    HXREGION* retRGN = InternalRight180Radial(left, top, right, bottom, 1000 - completeness,  lines);
  1413.    HXREGION* rgn1 = HXCreateRectRegion(left, top, right-left,bottom-top);
  1414.    HXCombineRgn(retRGN, rgn1, retRGN, HX_RGN_DIFF);
  1415.    HXDestroyRegion(rgn1);
  1416.    rgn1 = InternalLeft180Radial(left, top, right, bottom, completeness,  tmpLines);
  1417.    if (completeness > 500)
  1418.       HXCombineRgn(retRGN, retRGN, rgn1, HX_RGN_AND);
  1419.    else
  1420.       HXCombineRgn(retRGN, retRGN, rgn1, HX_RGN_OR);
  1421.    HXDestroyRegion(rgn1);
  1422.    if (lines)
  1423.    {
  1424.       lines->Clip((left + right) / 2,top,right,bottom);
  1425.       tmpLines->Clip(left,top,(left + right) / 2,bottom);
  1426.       *lines += *tmpLines;
  1427.       delete tmpLines;
  1428.    }
  1429.    return retRGN;
  1430. }
  1431. HXREGION* OpenVTopRadial(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  1432. {
  1433.    HXREGION* retRgn = MirrorHorizontal(OpenVBottomRadial(left,top,right,bottom,completeness,lines),(top + bottom) / 2);
  1434.    if (lines)
  1435.       MirrorHorizontal(lines,(top + bottom) / 2);
  1436.    return retRgn;
  1437. }
  1438. HXREGION* OpenVRightRadial(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  1439. {
  1440.    HXREGION* retRgn = MirrorVertical(OpenVLeftRadial(left,top,right,bottom,completeness,lines),(left + right) / 2);
  1441.    if (lines)
  1442.       MirrorVertical(lines,(left + right) / 2);
  1443.    return retRgn;
  1444. }
  1445. HXREGION* OpenVBottomRadial(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  1446. {
  1447.    tranLines* tmpLines = NULL;
  1448.    if (lines)
  1449.       tmpLines = new tranLines;
  1450.    HXREGION* retRGN = InternalRotatingLeftRadial(left, top - (bottom - top), right, bottom, 250 - completeness/4,  lines);
  1451.    HXOffsetRegion(retRGN, 0, bottom - top);
  1452.    retRGN       = InvertRGN(retRGN, left, top, left + (right - left)/2, bottom);
  1453.    HXREGION* rgn1 = InternalRotatingTopRadial(left, top - (bottom - top), right, bottom, completeness/4,  tmpLines);
  1454.    HXOffsetRegion(rgn1, 0, bottom - top);
  1455.    HXCombineRgn(retRGN, rgn1, retRGN, HX_RGN_OR);
  1456.    HXDestroyRegion(rgn1);
  1457.    if (lines)
  1458.    {
  1459.       *lines += *tmpLines;
  1460.       delete tmpLines;
  1461.       lines->Offset(0, bottom - top);
  1462.    }
  1463.    return retRGN;
  1464. }
  1465. HXREGION* OpenVLeftRadial(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  1466. {
  1467.    tranLines* tmpLines = NULL;
  1468.    if (lines)
  1469.       tmpLines = new tranLines;
  1470.    HXREGION* retRGN = InternalRotatingRightRadial(left - (right - left), top, right, bottom, completeness/4,  lines);
  1471.    HXREGION* rgn1 = InternalRotatingTopRadial(left - (right - left), top, right, bottom, 250 - completeness/4,  tmpLines);
  1472.    rgn1 = InvertRGN(rgn1, left, top, right, top + (bottom - top) / 2);
  1473.    HXCombineRgn(retRGN, rgn1, retRGN, HX_RGN_OR);
  1474.    HXDestroyRegion(rgn1);
  1475.    if (lines)
  1476.    {
  1477.       *lines += *tmpLines;
  1478.       delete tmpLines;
  1479.    }
  1480.    return retRGN;
  1481. }
  1482. HXREGION* OpenVTopBottomRadial(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  1483. {
  1484.    tranLines* tmpLines = NULL;
  1485.    if (lines)
  1486.       tmpLines = new tranLines;
  1487.    HXREGION* retRGN = OpenVBottomRadial(left, top, right, bottom, completeness,  lines);
  1488.    HXREGION* rgn1  = OpenVTopRadial(left, top, right, bottom, completeness,  tmpLines);
  1489.    HXCombineRgn(retRGN, rgn1, retRGN, HX_RGN_AND);
  1490.    HXDestroyRegion(rgn1);
  1491.    if (lines)
  1492.    {
  1493.       *lines += *tmpLines;
  1494.       delete tmpLines;
  1495.    }
  1496.    return retRGN;
  1497. }
  1498. HXREGION* OpenVLeftRightRadial(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  1499. {
  1500.    tranLines* tmpLines = NULL;
  1501.    if (lines)
  1502.       tmpLines = new tranLines;
  1503.    HXREGION* retRGN = OpenVLeftRadial(left, top, right, bottom, completeness,  lines);
  1504.    HXREGION* rgn1 = OpenVRightRadial(left, top, right, bottom, completeness,  tmpLines);
  1505.    HXCombineRgn(retRGN, rgn1, retRGN, HX_RGN_AND);
  1506.    HXDestroyRegion(rgn1);
  1507.    if (lines)
  1508.    {
  1509.       *lines += *tmpLines;
  1510.       delete tmpLines;
  1511.    }
  1512.    return retRGN;
  1513. }
  1514. HXREGION* RotatingTopLeftRadial(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  1515. {
  1516.    HXREGION* retRGN = RotatingRightRadial(left - (right - left), top - (bottom - top), right, bottom, completeness / 4,  lines);
  1517.    if (lines)
  1518.    {
  1519.       //XXXSMJ This is cheap!  Changes to RotatingRightRadial() might break this
  1520.       lines->m_nLines = 1;
  1521.    }
  1522.    return retRGN;
  1523. }
  1524. HXREGION* RotatingBottomLeftRadial(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  1525. {
  1526.    HXREGION* retRGN = InvertRGN(RotatingRightRadial(left - (right - left), top, right, bottom +  (bottom - top), 1000 - completeness / 4,  lines), left, top, right, bottom);
  1527.    if (lines)
  1528.    {
  1529.       //XXXSMJ This is cheap!  Changes to RotatingRightRadial() might break this
  1530.       lines->m_nLines = 1;
  1531.    }
  1532.    return retRGN;
  1533. }
  1534. HXREGION* RotatingBottomRightRadial(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  1535. {
  1536.    HXREGION* retRGN = RotatingLeftRadial(left, top, right + (right - left), bottom  + (bottom - top), completeness / 4,  lines);
  1537.    if (lines)
  1538.    {
  1539.       //XXXSMJ This is cheap!  Changes to RotatingLeftRadial() might break this
  1540.       lines->m_nLines = 1;
  1541.    }
  1542.    return retRGN;
  1543. }
  1544. HXREGION* RotatingTopRightRadial(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  1545. {
  1546.    HXREGION* retRGN = InvertRGN(RotatingLeftRadial(left, top - (bottom - top), right + (right - left), bottom, 1000 - completeness / 4,  lines), left, top, right, bottom);
  1547.    if (lines)
  1548.    {
  1549.       //XXXSMJ This is cheap!  Changes to RotatingLeftRadial() might break this
  1550.       lines->m_nLines = 1;
  1551.    }
  1552.    return retRGN;
  1553. }
  1554. HXREGION* RotatingTopLeftBottomRightRadial(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  1555. {
  1556.    LineSegment ls;
  1557.    HXxPoint points[3];
  1558.         
  1559.    points[0].x = left;
  1560.    points[0].y = top;
  1561.    points[1].x = right;
  1562.    points[1].y = (int) (bottom - ((double)(bottom - top)) * ( 1.0 - (double)completeness/ 1000.0));
  1563.    points[2].x = right;
  1564.    points[2].y = top;
  1565.         
  1566.    HXREGION* retRGN = HXPolygonRegion( points, 3, WindingRule);
  1567.    if (lines)
  1568.    {
  1569.       ls.start.x = points[0].x;
  1570.       ls.start.y = points[0].y;
  1571.       ls.finish.x = points[1].x;
  1572.       ls.finish.y = points[1].y;
  1573.       *lines += ls;
  1574.    }
  1575.     
  1576.    points[0].x = right;
  1577.    points[0].y = bottom;
  1578.    points[1].x = left;
  1579.    points[1].y = (int) (bottom - ((double)(bottom - top)) * ((double)completeness/ 1000.0));
  1580.    points[2].x = left;
  1581.    points[2].y = bottom;
  1582.         
  1583.    HXREGION* tempRGN = HXPolygonRegion( points, 3, WindingRule);
  1584.    if (lines)
  1585.    {
  1586.       ls.start.x = points[0].x;
  1587.       ls.start.y = points[0].y;
  1588.       ls.finish.x = points[1].x;
  1589.       ls.finish.y = points[1].y;
  1590.       *lines += ls;
  1591.    }
  1592.    HXCombineRgn(retRGN, retRGN, tempRGN, HX_RGN_OR);
  1593.    HXDestroyRegion(tempRGN);
  1594.         
  1595.    return retRGN;
  1596. }
  1597. HXREGION* RotatingBottomLeftTopRightRadial(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  1598. {
  1599.    LineSegment ls;
  1600.    HXxPoint points[3];
  1601.         
  1602.    points[0].x = left;
  1603.    points[0].y = bottom;
  1604.    points[1].x = int(left + double(right - left) * double(completeness) / 1000.0);
  1605.    points[1].y = top;
  1606.    points[2].x = left;
  1607.    points[2].y = top;
  1608.         
  1609.    HXREGION* retRGN = HXPolygonRegion( points, 3, WindingRule);
  1610.    if (lines)
  1611.    {
  1612.       ls.start.x = points[0].x;
  1613.       ls.start.y = points[0].y;
  1614.       ls.finish.x = points[1].x;
  1615.       ls.finish.y = points[1].y;
  1616.       *lines += ls;
  1617.    }
  1618.     
  1619.    points[0].x = right;
  1620.    points[0].y = top;
  1621.    points[1].x = int(right - double(right - left) * double(completeness) / 1000.0);
  1622.    points[1].y = bottom;
  1623.    points[2].x = right;
  1624.    points[2].y = bottom;
  1625.         
  1626.    HXREGION* tempRGN = HXPolygonRegion( points, 3, WindingRule);
  1627.    if (lines)
  1628.    {
  1629.       ls.start.x = points[0].x;
  1630.       ls.start.y = points[0].y;
  1631.       ls.finish.x = points[1].x;
  1632.       ls.finish.y = points[1].y;
  1633.       *lines += ls;
  1634.    }
  1635.    HXCombineRgn(retRGN, retRGN, tempRGN, HX_RGN_OR);
  1636.    HXDestroyRegion(tempRGN);
  1637.         
  1638.    return retRGN;
  1639. }
  1640. HXREGION* RotatingTopLeftRightRadial(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  1641. {
  1642.    tranLines* tmpLines = NULL;
  1643.    if (lines)
  1644.       tmpLines = new tranLines;
  1645.    HXREGION* retRGN = RotatingTopLeftRadial(left, top, right, bottom, completeness,  lines);
  1646.    HXREGION* rgn1 = RotatingTopRightRadial(left, top, right, bottom, completeness,  tmpLines);
  1647.    HXCombineRgn(retRGN, retRGN, rgn1, HX_RGN_AND);
  1648.    HXDestroyRegion(rgn1);
  1649.    if (lines)
  1650.    {
  1651.       *lines += *tmpLines;
  1652.       delete tmpLines;
  1653.    }
  1654.    return retRGN;
  1655. }
  1656. HXREGION* RotatingLeftTopBottomRadial(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  1657. {
  1658.    tranLines* tmpLines = NULL;
  1659.    if (lines)
  1660.       tmpLines = new tranLines;
  1661.    HXREGION* retRGN = RotatingTopLeftRadial(left, top, right, bottom, 1000 - completeness,  lines);
  1662.    HXREGION* rgn1 = RotatingBottomLeftRadial(left, top, right, bottom, 1000 - completeness,  tmpLines);
  1663.    HXCombineRgn(retRGN, retRGN, rgn1, HX_RGN_OR);
  1664.    HXDestroyRegion(rgn1);
  1665.    if (lines)
  1666.    {
  1667.       *lines += *tmpLines;
  1668.       delete tmpLines;
  1669.    }
  1670.    return InvertRGN(retRGN, left, top, right, bottom);
  1671. }
  1672. HXREGION* RotatingBottomLeftRightRadial(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  1673. {
  1674.    HXREGION* retRGN = MirrorHorizontal(RotatingTopLeftRightRadial(left, top, right, bottom, completeness,  lines),(top + bottom) / 2);
  1675.    if (lines)
  1676.       MirrorHorizontal(lines,(top + bottom) / 2);
  1677.    return retRGN;
  1678. }
  1679. HXREGION* RotatingRightTopBottomRadial(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  1680. {
  1681.    HXREGION* retRGN = MirrorVertical(RotatingLeftTopBottomRadial(left, top, right, bottom, completeness,  lines),(left + right) / 2);
  1682.    if (lines)
  1683.       MirrorVertical(lines,(left + right) / 2);
  1684.    return retRGN;
  1685. }
  1686. HXREGION* RotatingDoubleCenterRightRadial(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  1687. {
  1688.    tranLines* tmpLines = NULL;
  1689.    if (lines)
  1690.       tmpLines = new tranLines;
  1691.    HXREGION* retRGN = RotatingBottomRadial(left, top, right, bottom, 1000 - completeness,  lines);
  1692.    HXREGION* rgn1 = RotatingTopRadial(left, top, right, bottom, completeness,  tmpLines);
  1693.    rgn1 = InvertRGN(rgn1, left, top, right, bottom);
  1694.    HXOffsetRegion(retRGN,0,-(bottom - top) / 4);
  1695.    HXOffsetRegion(rgn1,0,(bottom - top) / 4);
  1696.    if (completeness > 750)
  1697.       HXCombineRgn(retRGN, retRGN, rgn1, HX_RGN_AND);
  1698.    else
  1699.       HXCombineRgn(retRGN, retRGN, rgn1, HX_RGN_OR);
  1700.    HXDestroyRegion(rgn1);
  1701.    if (lines)
  1702.    {
  1703.       lines->Offset(0,-(bottom - top) / 4);
  1704.       lines->Clip(left,top,right,(top + bottom) / 2);
  1705.       tmpLines->Offset(0,(bottom - top) / 4);
  1706.       tmpLines->Clip(left,(top + bottom) / 2,right,bottom);
  1707.       *lines += *tmpLines;
  1708.       delete tmpLines;
  1709.    }
  1710.    return InvertRGN(retRGN, left, top, right, bottom);
  1711. }
  1712. HXREGION* RotatingDoubleCenterTopRadial(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  1713. {
  1714.    tranLines* tmpLines = NULL;
  1715.    if (lines)
  1716.       tmpLines = new tranLines;
  1717.    HXREGION* retRGN = RotatingLeftRadial(left, top, right, bottom, completeness,lines);
  1718.    retRGN  = InvertRGN(retRGN, left, top, right, bottom);
  1719.    HXREGION* rgn1 = RotatingRightRadial(left, top, right, bottom, 1000 - completeness,  tmpLines);
  1720.    HXOffsetRegion(retRGN,(right - left) / 4, 0);
  1721.    HXOffsetRegion(rgn1,-(right - left) / 4, 0);
  1722.    if (completeness > 750)
  1723.       HXCombineRgn(retRGN, retRGN, rgn1, HX_RGN_AND);
  1724.    else
  1725.       HXCombineRgn(retRGN, retRGN, rgn1, HX_RGN_OR);
  1726.    HXDestroyRegion(rgn1);
  1727.    if (lines)
  1728.    {
  1729.       lines->Offset((right - left) / 4, 0);
  1730.       lines->Clip((right + left) / 2,top,right,bottom);
  1731.       tmpLines->Offset(-(right - left) / 4, 0);
  1732.       tmpLines->Clip(left,top,(right + left) / 2,bottom);
  1733.       *lines += *tmpLines;
  1734.       delete tmpLines;
  1735.    }
  1736.    return InvertRGN(retRGN, left, top, right, bottom);
  1737. }
  1738. HXREGION* RotatingDoubleCenterTopBottomRadial(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  1739. {
  1740.    tranLines* tmpLines = NULL;
  1741.    if (lines)
  1742.       tmpLines = new tranLines;
  1743.    HXREGION* retRGN = InternalRotatingTopRadial(left, top, right, bottom, completeness / 2,  lines);
  1744.    HXOffsetRegion(retRGN,0,-(bottom - top) / 4);
  1745.    HXREGION* rgn1 = HXCreateRegion();
  1746.    CopyRegion(rgn1,retRGN);
  1747.    MirrorHorizontal(rgn1,(bottom + top) / 2);
  1748.    if (lines)
  1749.    {
  1750.       lines->Offset(0,-(bottom - top) / 4);
  1751.       lines->Clip(left,top,right,(top + bottom) / 2);
  1752.       *tmpLines += *lines;
  1753.       MirrorHorizontal(tmpLines,(bottom + top) / 2);
  1754.       *lines += *tmpLines;
  1755.       tmpLines->Destroy();
  1756.    }
  1757.    HXCombineRgn(retRGN, retRGN, rgn1, HX_RGN_OR);
  1758.    CopyRegion(rgn1,retRGN);
  1759.    MirrorVertical(rgn1,(left + right) / 2);
  1760.    HXCombineRgn(retRGN, retRGN, rgn1, HX_RGN_OR);
  1761.    HXDestroyRegion(rgn1);
  1762.    if (lines)
  1763.    {
  1764.       *tmpLines += *lines;
  1765.       MirrorVertical(tmpLines,(left + right) / 2);
  1766.       *lines += *tmpLines;
  1767.       delete tmpLines;
  1768.    }
  1769.    return retRGN;
  1770. }
  1771. HXREGION* RotatingDoubleCenterLeftRightRadial(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  1772. {
  1773.    tranLines* tmpLines = NULL;
  1774.    if (lines)
  1775.       tmpLines = new tranLines;
  1776.    HXREGION* retRGN = InternalRotatingLeftRadial(left, top, right, bottom, completeness / 2,  lines);
  1777.    HXOffsetRegion(retRGN,-(right + left) / 4, 0);
  1778.    HXREGION* rgn1 = HXCreateRegion();
  1779.    CopyRegion(rgn1,retRGN);
  1780.    MirrorHorizontal(rgn1,(bottom + top) / 2);
  1781.    if (lines)
  1782.    {
  1783.       lines->Offset(-(right + left) / 4, 0);
  1784.       lines->Clip(left,top,(left + right) / 2,bottom);
  1785.       *tmpLines += *lines;
  1786.       MirrorHorizontal(tmpLines,(bottom + top) / 2);
  1787.       *lines += *tmpLines;
  1788.       tmpLines->Destroy();
  1789.    }
  1790.    HXCombineRgn(retRGN, retRGN, rgn1, HX_RGN_OR);
  1791.    CopyRegion(rgn1,retRGN);
  1792.    MirrorVertical(rgn1,(left + right) / 2);
  1793.    HXCombineRgn(retRGN, retRGN, rgn1, HX_RGN_OR);
  1794.    HXDestroyRegion(rgn1);
  1795.    if (lines)
  1796.    {
  1797.       *tmpLines += *lines;
  1798.       MirrorVertical(tmpLines,(left + right) / 2);
  1799.       *lines += *tmpLines;
  1800.       delete tmpLines;
  1801.    }
  1802.    return retRGN;
  1803. }
  1804. HXREGION* DoubleDiagonalBottom(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  1805. {
  1806.    if (completeness <= 0)
  1807.       return HXCreateRegion();
  1808.     
  1809.    HXxPoint p[7];
  1810.    tranLines* tmpLines = NULL;
  1811.    GetTopLeftDiagonalCoords(left,top,right,bottom,500 + completeness / 2,p,lines);
  1812.    HXREGION* retRGN = HXPolygonRegion(p, 7, WindingRule);
  1813.    HXREGION* rgn1 = MirrorHorizontal(MirrorVertical(HXPolygonRegion(p, 7, WindingRule),(left + right) / 2),top + (bottom - top) / 2);
  1814.    HXCombineRgn(retRGN, retRGN, rgn1, HX_RGN_AND);
  1815.    if (lines)
  1816.    {
  1817.       tmpLines = new tranLines;
  1818.       *tmpLines += *lines;
  1819.       MirrorVertical(tmpLines,(left + right) / 2);
  1820.       MirrorHorizontal(tmpLines,top + (bottom - top) / 2);
  1821.       *lines += *tmpLines;
  1822.    }
  1823.    if (completeness < 120) // deal with slight overlap until the two snakes meet
  1824.    {
  1825.       HXREGION* blank1 = InvertRGN(HXCreateRectRegion(left,bottom - p[3].y,right,p[3].y),left,top,right-left,bottom-top);
  1826.       HXCombineRgn(retRGN, retRGN, blank1, HX_RGN_AND);
  1827.       HXDestroyRegion(blank1);
  1828.    }
  1829.    HXDestroyRegion(rgn1);
  1830.     
  1831.    return retRGN;
  1832. }
  1833. HXREGION* DoubleDiagonalTop(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  1834. {
  1835.    HXREGION* retRGN = MirrorVertical(DoubleDiagonalBottom(left, top, right, bottom, completeness,lines),(left + right) / 2);
  1836.    if (lines)
  1837.       MirrorVertical(lines,(left + right) / 2);
  1838.    return retRGN;
  1839. }
  1840. HXREGION* SlideFromLeft(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  1841. {
  1842.    if (lines)
  1843.    {
  1844.       lines->m_nLines = 0;
  1845.       HX_VECTOR_DELETE( lines->m_pLines );
  1846.    }
  1847.    return HXCreateRectRegion(left, top, right - left, bottom - top);
  1848. }
  1849. HXREGION* SlideFromTop(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  1850. {
  1851.    if (lines)
  1852.    {
  1853.       lines->m_nLines = 0;
  1854.       HX_VECTOR_DELETE( lines->m_pLines );
  1855.    }
  1856.    return HXCreateRectRegion(left, top, right - left, bottom - top);
  1857. }
  1858. HXREGION* SlideFromRight(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  1859. {
  1860.    if (lines)
  1861.    {
  1862.       lines->m_nLines = 0;
  1863.       HX_VECTOR_DELETE( lines->m_pLines );
  1864.    }
  1865.    return HXCreateRectRegion(left, top, right - left, bottom - top);
  1866. }
  1867. HXREGION* SlideFromBottom(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  1868. {
  1869.    if (lines)
  1870.    {
  1871.       lines->m_nLines = 0;
  1872.       HX_VECTOR_DELETE( lines->m_pLines );
  1873.    }
  1874.    return HXCreateRectRegion(left, top, right - left, bottom - top);
  1875. }
  1876. HXREGION* Crossfade(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  1877. {
  1878.    if(lines)
  1879.    {
  1880.       lines->m_nLines = 0;
  1881.       HX_VECTOR_DELETE(lines->m_pLines);
  1882.    }
  1883.    return HXCreateRectRegion(left, top, right - left, bottom - top);
  1884. }
  1885. HXREGION* FadeToColor(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  1886. {
  1887.    if (lines)
  1888.    {
  1889.       lines->m_nLines = 0;
  1890.       HX_VECTOR_DELETE( lines->m_pLines );
  1891.    }
  1892.    return HXCreateRectRegion(left, top, right - left, bottom - top);
  1893. }
  1894. HXREGION* FadeFromColor(int left, int top, int right, int bottom, int completeness, tranLines* lines)
  1895. {
  1896.    if (lines)
  1897.    {
  1898.       lines->m_nLines = 0;
  1899.       HX_VECTOR_DELETE( lines->m_pLines );
  1900.    }
  1901.    return HXCreateRectRegion(left, top, right - left, bottom - top);
  1902. }
  1903. #endif //_TRANSITIONS_ON_
  1904. #ifdef _TESTING_TRANITIONS_
  1905. #define FORWARD
  1906. // sloppy, but cheap for this test program
  1907. int z_PaneWidth = 280;
  1908. int z_PaneHeight = 250;
  1909. struct tranMap
  1910. {
  1911.    int in;
  1912.    int type;
  1913.    int subType;
  1914. };
  1915. tranMap theTranMap[200];
  1916. extern tranType     z_TransitionTable[];
  1917. extern int          z_nNumberTransitions;
  1918. HWND    zm_hwnd;
  1919. HWND    zm_comboHWND;
  1920. HWND    zm_displayOuter;
  1921. HWND    zm_displayInner;
  1922. char*   zm_pszWindowClassName = "TestRGNClass";
  1923. char*   zm_pszWindowName = "TestRGNWindow";
  1924. HFONT   zm_theFONT = 0;
  1925. HFONT   zm_theSmallFONT = 0;
  1926. HBITMAP zm_hBitmapOLD= 0;
  1927. HBITMAP zm_hBitmapNEW= 0;
  1928. HBITMAP zm_hScratchSurface= 0;
  1929. HBITMAP zm_oldSurface = 0;
  1930. HBITMAP zm_oldSurface2 = 0;
  1931. HDC     zm_memDC = 0;
  1932. HDC     zm_memDC2 = 0;
  1933. int currentPosition = 0;
  1934. int CurrentTransition = 1;
  1935. int CurrentSubType = 0;
  1936. int zm_maxRects = 0;
  1937. int zm_numFrames = 0;
  1938. double zm_startTime;
  1939. double zm_totalCPUTime;
  1940. int     zm_bRegionEffect = 1;
  1941. int     z_pPixelValues[300][300];
  1942. double GetAngle(int x, int y, int x1, int y1)
  1943. {
  1944.    int dx = x- x1;
  1945.    int dy = y - y1;
  1946.         
  1947.    return atan2(dx, dy);
  1948. }
  1949. int GetRange(int x, int y, int x1, int y1)
  1950. {
  1951.    return (int) sqrt( (double) ((x1 - x) * (x1 - x) + (y1 - y) * (y1 - y)));
  1952. }
  1953. void DoPixelTransition(HBITMAP back, HBITMAP front, HBITMAP scratch, int completeness, tranLines* lines)
  1954. {
  1955.    if (!zm_memDC2)
  1956.    {
  1957.       HDC hdc = GetDC(0);
  1958.       zm_memDC2 = CreateCompatibleDC(hdc);
  1959.       ReleaseDC(0, hdc);
  1960.    }
  1961.         
  1962.    zm_oldSurface = (HBITMAP)SelectObject(zm_memDC, back);
  1963.    zm_oldSurface2 = (HBITMAP)SelectObject(zm_memDC2, zm_hScratchSurface);
  1964.    SelectObject(zm_memDC, front);
  1965.         
  1966.    if (!z_pPixelValues[0][0])
  1967.    {
  1968.       for(int y = 0; y<z_PaneWidth; y++)
  1969.       {
  1970.          for(int x = 0; x< z_PaneWidth; x++)
  1971.          {
  1972.             z_pPixelValues[x][y]= GetPixel(zm_memDC, x, y);
  1973.             if (!x && !y && !z_pPixelValues[x][y])
  1974.             {   
  1975.                z_pPixelValues[x][y] = 1;
  1976.             }
  1977.          }
  1978.       }
  1979.    }
  1980.         
  1981.    int implodex = 140;
  1982.    int implodey = 140;
  1983.         
  1984.    for(int y = 0; y<z_PaneWidth; y++)
  1985.    {
  1986.       for(int x = 0; x< z_PaneWidth; x++)
  1987.       {
  1988.          int color = z_pPixelValues[x][y];
  1989.          double  angle= GetAngle(x,y,implodex, implodey);
  1990.          int range = GetRange(x,y,implodex, implodey);
  1991.          range = (range * (1000 - completeness)) / 1000;
  1992.          double mess = (double)completeness/500.0  * PI;
  1993.          double scaleFactor = sin(angle*3 + mess)*cos(angle*2 + mess);
  1994.          scaleFactor = (1.0 - scaleFactor)* (1000.0 - completeness) / 1000.0 + scaleFactor;
  1995.          range = (int) (range * scaleFactor + 0.5);
  1996.          int newx = (int) ((double) range * sin (angle + mess / 4) + implodex + 0.5);
  1997.          int newy = (int) ((double) range * cos (angle + mess / 4)  + implodey + 0.5);
  1998.          SetPixel(zm_memDC2, newx, newy, color);
  1999.       }
  2000.    }
  2001.    SelectObject(zm_memDC, zm_oldSurface);
  2002.    SelectObject(zm_memDC2, zm_oldSurface2);
  2003. }
  2004. double currentTime()
  2005. {
  2006.    static LARGE_INTEGER QueryPerformanceCounterResult = {0,0};
  2007.    static LARGE_INTEGER QueryPerformanceFrequencyResult = {0,0};
  2008.         
  2009.    QueryPerformanceFrequency(&QueryPerformanceFrequencyResult);
  2010.         
  2011.    double frequency = ((double)QueryPerformanceFrequencyResult.LowPart + 4294967296.0*QueryPerformanceFrequencyResult.HighPart);
  2012.    QueryPerformanceCounter(&QueryPerformanceCounterResult);
  2013.         
  2014.    return ((double)QueryPerformanceCounterResult.LowPart + 4294967296.0*QueryPerformanceCounterResult.HighPart)/frequency;
  2015. }
  2016. void PrintStat(int x, int y, char* pszStatName, int stat)
  2017. {
  2018.    LOGBRUSH logBrush;
  2019.    logBrush.lbStyle = BS_SOLID;
  2020.    logBrush.lbColor = 0x00000000;
  2021.    logBrush.lbHatch = 0;
  2022.    HBRUSH brush = CreateBrushIndirect(&logBrush);
  2023.         
  2024.     
  2025.    HDC hdc = GetDC(zm_hwnd);
  2026.    char buffer[20]; /* Flawfinder: ignore */
  2027.    SetTextColor(hdc, 0x00FFFFFF);
  2028.    SetBkColor(hdc, 0x00000000);
  2029.    SetBkMode(hdc, OPAQUE);
  2030.    HBRUSH oldBrush = (HBRUSH) SelectObject(hdc, brush);
  2031.         
  2032.    TextOut(hdc, x, y, pszStatName, strlen(pszStatName));
  2033.    Rectangle(hdc, x+90, y, x+230, y+20);
  2034.    sprintf(buffer, "%d", stat); /* Flawfinder: ignore */
  2035.    TextOut(hdc, x+90, y, buffer, strlen(buffer));
  2036.    SelectObject(hdc, oldBrush);
  2037.    DeleteObject(brush);
  2038.    ReleaseDC(zm_hwnd, hdc);
  2039. }
  2040. #ifdef NO_GRAPHICS
  2041. void DoTransition(int currentPosition)
  2042. {
  2043.    RECT rect;
  2044.         
  2045.    rect.left    = 0;
  2046.    rect.top     = 0;
  2047.    rect.right   = z_PaneWidth;
  2048.    rect.bottom = z_PaneHeight;
  2049.         
  2050.    HXDestroyRegion(z_TransitionTable[CurrentTransition].m_pSubTypes[CurrentSubType].m_fpTranFunction(rect.left, rect.top, rect.right, rect.bottom, currentPosition));
  2051. }
  2052. #endif
  2053. LRESULT __declspec(dllexport) __stdcall CWindowProc
  2054. (
  2055.    HWND hWnd,
  2056.    UINT message,
  2057.    WPARAM wParam,
  2058.    LPARAM lParam
  2059.    )
  2060. {
  2061.    switch (message)
  2062.    {
  2063.       case WM_TIMER:
  2064.       {
  2065.          /*  The following commented out code is for determing which 
  2066.           *     region is supposed to be old and which is supposed to be new.
  2067.           */
  2068.                         
  2069.          /*
  2070.            {
  2071.            RECT rect;
  2072.            GetClientRect(zm_displayInner, &rect);
  2073.            HRGN rgn = CreateRectRgn(rect.left, rect.top, rect.right, rect.bottom);
  2074.            SetWindowRgn(zm_displayInner, rgn, FALSE);
  2075.            HDC hdc = GetDC(zm_displayInner);
  2076.            FillRect(hdc, &rect, (HBRUSH)GetStockObject(BLACK_BRUSH));
  2077.            GdiFlush();
  2078.            ReleaseDC(zm_displayInner, hdc);
  2079.            }
  2080.          */
  2081.                         
  2082.          double startTime = currentTime();
  2083.                         
  2084.          RECT rect;
  2085.                         
  2086.          rect.left      = 0;
  2087.          rect.top       = 0;
  2088.          rect.right     = z_PaneWidth;// - 1;
  2089.          rect.bottom = z_PaneHeight;// - 1;
  2090.                         
  2091. #ifdef FORWARD
  2092.          currentPosition += 5;
  2093.          if (currentPosition > 1000) currentPosition = 1000;
  2094. #else
  2095.          currentPosition -= 5;
  2096.          if (currentPosition < 0) currentPosition = 0;
  2097. #endif
  2098.                         
  2099.          HXREGION* XclipRgn = InvertRGN(z_TransitionTable[CurrentTransition].m_pSubTypes[CurrentSubType].m_fpTranFunction(rect.left, rect.top, rect.right, rect.bottom, currentPosition),rect.left, rect.top, rect.right, rect.bottom);
  2100.                         
  2101.          HRGN clipRgn = CreateRectRgn(0,0,0,0);
  2102.          for(int i=0 ; i<XclipRgn->numRects ; i++ )
  2103.          {
  2104.             HRGN tmp = CreateRectRgn(
  2105.                XclipRgn->rects[i].x1,
  2106.                XclipRgn->rects[i].y1,
  2107.                XclipRgn->rects[i].x2,
  2108.                XclipRgn->rects[i].y2
  2109.                );       
  2110.             CombineRgn( clipRgn, clipRgn, tmp, RGN_OR );
  2111.             DeleteObject( tmp );
  2112.          }
  2113.          HXDestroyRegion(XclipRgn);
  2114.          if (!zm_theSmallFONT)
  2115.          {
  2116.             zm_theSmallFONT = CreateFont(15, 0, 0, 0, 700, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, "Ariel");
  2117.          }
  2118.                         
  2119.          if (!zm_theFONT)
  2120.          {
  2121.             zm_theFONT = CreateFont(115, 0, 0, 0, 700, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, "Ariel");
  2122.          }
  2123.          int totalrects;
  2124.          totalrects = 0;
  2125.                         
  2126.          {
  2127.             LPRGNDATA   lpRgnData;
  2128.             DWORD sizeNeeed = GetRegionData(clipRgn, 0, NULL); 
  2129.             lpRgnData = (LPRGNDATA) new char[sizeNeeed];
  2130.             GetRegionData(clipRgn, sizeNeeed, lpRgnData); 
  2131.             PrintStat(z_PaneWidth + 20, 50, "Old Rects:", lpRgnData->rdh.nCount);
  2132.             totalrects += lpRgnData->rdh.nCount;
  2133.             delete lpRgnData;
  2134.          }
  2135.                         
  2136.          //  Create Initial Objects.
  2137.                         
  2138.          if (!zm_memDC)
  2139.          {
  2140.             HDC hdc = GetDC(0);
  2141.             zm_memDC = CreateCompatibleDC(hdc);
  2142.             ReleaseDC(0, hdc);
  2143.          }
  2144.                         
  2145.          if (!zm_hBitmapNEW)
  2146.          {
  2147.             HDC hdc = GetDC(0);
  2148.             zm_hBitmapNEW = CreateCompatibleBitmap(hdc, z_PaneWidth, z_PaneHeight);
  2149.             ReleaseDC(0, hdc);
  2150.                                 
  2151.             zm_oldSurface = (HBITMAP)SelectObject(zm_memDC, zm_hBitmapNEW);
  2152.             LOGBRUSH logBrush;
  2153.             logBrush.lbStyle = BS_SOLID;
  2154.             logBrush.lbColor = 0x000000FF;
  2155.             logBrush.lbHatch = 0;
  2156.             HBRUSH brush = CreateBrushIndirect(&logBrush);
  2157.                                 
  2158.             HFONT   oldfont             = (HFONT)SelectObject(zm_memDC, zm_theFONT);
  2159.             HBRUSH  oldBrush    = (HBRUSH)SelectObject(zm_memDC, brush);
  2160.             Rectangle(zm_memDC, 0,0,z_PaneWidth, z_PaneHeight);
  2161.             SetBkMode(zm_memDC, TRANSPARENT);
  2162.             SIZE stringSize;
  2163.             GetTextExtentPoint32(zm_memDC,"NEW",3,&stringSize);
  2164.             TextOut(zm_memDC, (z_PaneWidth - stringSize.cx) / 2, (z_PaneHeight - stringSize.cy) / 2, "NEW", 3);
  2165.             GdiFlush();
  2166.             SelectObject(zm_memDC, oldBrush);
  2167.             DeleteObject(brush);
  2168.             SelectObject(zm_memDC, oldfont);
  2169.             SelectObject(zm_memDC, zm_oldSurface);
  2170.          }
  2171.                         
  2172.          if (!zm_hBitmapOLD)
  2173.          {
  2174.             HDC hdc = GetDC(0);
  2175.             zm_hBitmapOLD = CreateCompatibleBitmap(hdc, z_PaneWidth, z_PaneHeight);
  2176.             ReleaseDC(0, hdc);
  2177.                                 
  2178.             zm_oldSurface = (HBITMAP)SelectObject(zm_memDC, zm_hBitmapOLD);
  2179.             LOGBRUSH logBrush;
  2180.             logBrush.lbStyle = BS_SOLID;
  2181.             logBrush.lbColor = 0x0000FFFF;
  2182.             logBrush.lbHatch = 0;
  2183.             HBRUSH brush = CreateBrushIndirect(&logBrush);
  2184.                                 
  2185.             HFONT   oldfont             = (HFONT)SelectObject(zm_memDC, zm_theFONT);
  2186.             HBRUSH  oldBrush    = (HBRUSH)SelectObject(zm_memDC, brush);
  2187.             Rectangle(zm_memDC, 0,0,z_PaneWidth, z_PaneHeight);
  2188.             SetBkMode(zm_memDC, TRANSPARENT);
  2189.             SIZE stringSize;
  2190.             GetTextExtentPoint32(zm_memDC,"OLD",3,&stringSize);
  2191.             TextOut(zm_memDC, (z_PaneWidth - stringSize.cx) / 2, (z_PaneHeight - stringSize.cy) / 2, "OLD", 3);
  2192.             GdiFlush();
  2193.             SelectObject(zm_memDC, oldBrush);
  2194.             DeleteObject(brush);
  2195.             SelectObject(zm_memDC, oldfont);
  2196.             SelectObject(zm_memDC, zm_oldSurface);
  2197.          }
  2198.                         
  2199.          if (zm_bRegionEffect)
  2200.          {
  2201.             HRGN oldRGN;
  2202.             oldRGN = CreateRectRgn(0,0,0,0);
  2203.             GetWindowRgn(zm_displayInner, oldRGN);
  2204.                                 
  2205.             SetWindowRgn(zm_displayInner, clipRgn, FALSE);
  2206.             HDC hdc = GetDC(zm_displayInner);
  2207.             zm_oldSurface = (HBITMAP)SelectObject(zm_memDC, zm_hBitmapOLD);
  2208.             BitBlt(hdc, 0,0,z_PaneWidth, z_PaneHeight, zm_memDC, 0,0, SRCCOPY);
  2209.                                 
  2210.             HXREGION* ZclipRgn =  InvertRGN(z_TransitionTable[CurrentTransition].m_pSubTypes[CurrentSubType].m_fpTranFunction(rect.left, rect.top, rect.right, rect.bottom, currentPosition),rect.left, rect.top, rect.right, rect.bottom);
  2211.             static LARGE_INTEGER QueryPerformanceCounterResult = {0,0};
  2212.             static LARGE_INTEGER QueryPerformanceFrequencyResult = {0,0};
  2213.                                 
  2214.             QueryPerformanceFrequency(&QueryPerformanceFrequencyResult);
  2215.                                 
  2216.             double frequency = ((double)QueryPerformanceFrequencyResult.LowPart + 4294967296.0*QueryPerformanceFrequencyResult.HighPart);
  2217.             QueryPerformanceCounter(&QueryPerformanceCounterResult);
  2218.                                 
  2219.             double startTime = ((double)QueryPerformanceCounterResult.LowPart + 4294967296.0*QueryPerformanceCounterResult.HighPart)/frequency;
  2220.                                 
  2221.             clipRgn = CreateRectRgn(0,0,0,0);
  2222.             for(int i=0 ; i<ZclipRgn->numRects ; i++ )
  2223.             {
  2224.                HRGN tmp = CreateRectRgn(
  2225.                   ZclipRgn->rects[i].x1,
  2226.                   ZclipRgn->rects[i].y1,
  2227.                   ZclipRgn->rects[i].x2,
  2228.                   ZclipRgn->rects[i].y2
  2229.                   );    
  2230.                CombineRgn( clipRgn, clipRgn, tmp, RGN_OR);
  2231.                DeleteObject( tmp );
  2232.             }
  2233.                                 
  2234.             HXDestroyRegion(ZclipRgn);
  2235.                                 
  2236.                                 
  2237.             QueryPerformanceCounter(&QueryPerformanceCounterResult);
  2238.             double endTime = ((double)QueryPerformanceCounterResult.LowPart + 4294967296.0*QueryPerformanceCounterResult.HighPart)/frequency;
  2239.                                 
  2240.             static UINT32 z_nNumTimes = 0;
  2241.             static double z_fTotalTime;
  2242.             static double z_fAverageTime;
  2243.                                 
  2244.             z_nNumTimes++;
  2245.             z_fTotalTime += endTime - startTime;
  2246.             z_fAverageTime = z_fTotalTime / (double) z_nNumTimes;
  2247.                                 /*
  2248.                                   if (! (z_nNumTimes % 25))
  2249.                                   {
  2250.                                   FILE* f1 = ::fopen("c:\performance.txt", "a+"); 
  2251.                                   ::fprintf(f1, "WINDRAW2 - BltToPrimary: %d blts. Total CPU time: %f, CPU/Blt: %f -- Blt/s Second Max: %fn", z_nNumTimes, z_fTotalTime, z_fAverageTime, 1.0/z_fAverageTime);
  2252.                                   fclose(f1);
  2253.                                   }
  2254.                                 
  2255.                                 */
  2256.                                 
  2257.             HRGN tempRgn = CreateRectRgn(rect.left, rect.top, rect.right, rect.bottom);
  2258.             CombineRgn(tempRgn, tempRgn, clipRgn, RGN_XOR);
  2259.                                 
  2260.                                 
  2261.                                 //  Print Region Stats
  2262.                                 
  2263.             {
  2264.                LPRGNDATA        lpRgnData;
  2265.                DWORD sizeNeeed = GetRegionData(tempRgn, 0, NULL); 
  2266.                lpRgnData = (LPRGNDATA) new char[sizeNeeed];
  2267.                GetRegionData(tempRgn, sizeNeeed, lpRgnData); 
  2268.                PrintStat(z_PaneWidth + 20, 70, "New Rects:", lpRgnData->rdh.nCount);
  2269.                totalrects += lpRgnData->rdh.nCount;
  2270.                delete lpRgnData;
  2271.             }
  2272.                                 
  2273.             SetWindowRgn(zm_displayInner, tempRgn, FALSE);
  2274.             SelectObject(zm_memDC, zm_hBitmapNEW);
  2275.             BitBlt(hdc, 0,0,z_PaneWidth, z_PaneHeight, zm_memDC, 0,0, SRCCOPY);
  2276.             ReleaseDC(zm_displayInner, hdc);
  2277.             DeleteObject(clipRgn);
  2278.             SelectObject(zm_memDC, zm_oldSurface);
  2279.             SetWindowRgn(zm_displayInner, oldRGN, 0);
  2280.          }
  2281.          else
  2282.          {
  2283.                                 //  Pixel based effects.
  2284.                                 
  2285.             if (!zm_hScratchSurface)
  2286.             {
  2287.                HDC hdc = GetDC(0);
  2288.                zm_hScratchSurface = CreateCompatibleBitmap(hdc, 300,300);
  2289.                ReleaseDC(0, hdc);
  2290.             }
  2291.                                 
  2292.             DoPixelTransition(zm_hBitmapNEW, zm_hBitmapOLD, zm_hScratchSurface, currentPosition);
  2293.             HDC hdc = GetDC(zm_displayInner);
  2294.             zm_oldSurface = (HBITMAP)SelectObject(zm_memDC, zm_hScratchSurface);
  2295.             BitBlt(hdc, 0,0,z_PaneWidth, z_PaneHeight, zm_memDC, 0,0, SRCCOPY);
  2296.             ReleaseDC(zm_displayInner, hdc);
  2297.             SelectObject(zm_memDC, zm_oldSurface);
  2298.             PrintStat(z_PaneWidth + 20, 170, "Frames:", zm_numFrames);
  2299.          }
  2300.                         
  2301.          //      Print More Stats
  2302.          PrintStat(z_PaneWidth + 20, 90, "Sum Rects:", totalrects);
  2303.          if (totalrects > zm_maxRects)
  2304.          {
  2305.             zm_maxRects = totalrects;
  2306.          }
  2307.          PrintStat(z_PaneWidth + 20, 110, "Max Rects:", zm_maxRects);
  2308.          zm_totalCPUTime = zm_totalCPUTime + (currentTime() - startTime);
  2309.          PrintStat(z_PaneWidth + 20, 130, "% CPU:", (int) (zm_totalCPUTime*100.0 / (currentTime() - zm_startTime)));
  2310.                         
  2311.          zm_numFrames++;
  2312.          PrintStat(z_PaneWidth + 20, 150, "FPS:", (int) (zm_numFrames/ (currentTime() - zm_startTime)));
  2313.                         
  2314.          PrintStat(z_PaneWidth + 20, 170, "Complete:", currentPosition);
  2315.          break;
  2316.       }
  2317.       case WM_COMMAND:
  2318.       {
  2319.          int wNotifyCode = HIWORD(wParam);
  2320.          if (wNotifyCode == CBN_SELCHANGE)
  2321.          {
  2322. #ifdef FORWARD
  2323.             currentPosition = -5;
  2324. #else
  2325.             currentPosition = 1005;
  2326. #endif
  2327.             int currentSel = SendMessage(zm_comboHWND, CB_GETCURSEL , 0, 0);
  2328.                                 
  2329.                                 // clear out the previous transitions memory
  2330.             HXDestroyRegion(z_TransitionTable[CurrentTransition].m_pSubTypes[CurrentSubType].m_fpTranFunction(0, 0, 0, 0, MATRIX_TRANSITION_DELETE));
  2331.                                 
  2332.             CurrentTransition = theTranMap[currentSel].type;
  2333.             CurrentSubType = theTranMap[currentSel].subType;
  2334.             zm_maxRects = 0;
  2335.             zm_startTime = currentTime();
  2336.             zm_totalCPUTime = 0;
  2337.             zm_numFrames = 0;
  2338. #ifdef NO_GRAPHICS
  2339.             double startTime = currentTime();
  2340.                                 
  2341.             for (int i = 0; i <= 1000; i += 5)
  2342.             {
  2343.                DoTransition(i);
  2344.             }
  2345.                                   
  2346.             double endTime = currentTime();
  2347.             PrintStat(z_PaneWidth + 20, 130, "Time (mu):", (int) ((endTime - startTime) * 1000000));
  2348. #endif
  2349.          }
  2350.          break;
  2351.       }
  2352.       case WM_DESTROY:
  2353.       {
  2354.          // clear out the previous transitions memory
  2355.          HXDestroyRegion(z_TransitionTable[CurrentTransition].m_pSubTypes[CurrentSubType].m_fpTranFunction(0, 0, 0, 0, MATRIX_TRANSITION_DELETE));
  2356.                         
  2357.          PostQuitMessage(0);
  2358.          break;
  2359.       }
  2360.    }
  2361.     
  2362.    return (DefWindowProc(hWnd, message, wParam, lParam));
  2363. }
  2364. int WINAPI WinMain( HINSTANCE hInstance, 
  2365.                     HINSTANCE hPrevInstance, 
  2366.                     LPSTR lpCmdLine, 
  2367.                     int nCmdShow 
  2368.                     )
  2369. {
  2370.    // get the size of the window from command line
  2371.    char* pCLine = strstr(lpCmdLine,"Width");
  2372.    if (pCLine)
  2373.    {
  2374.       pCLine = strchr(pCLine,'=');
  2375.       if (pCLine)
  2376.       {
  2377.          pCLine++;
  2378.          z_PaneWidth = atoi(pCLine);
  2379.       }
  2380.    }
  2381.    pCLine = strstr(lpCmdLine,"Height");
  2382.    if (pCLine)
  2383.    {
  2384.       pCLine = strchr(pCLine,'=');
  2385.       if (pCLine)
  2386.       {
  2387.          pCLine++;
  2388.          z_PaneHeight = atoi(pCLine);
  2389.       }
  2390.    }
  2391.         
  2392.    WNDCLASS wndClass;
  2393.         
  2394.    wndClass.style               = 0; 
  2395.    wndClass.lpfnWndProc = CWindowProc;
  2396.    wndClass.cbClsExtra          = 0;    
  2397.    wndClass.cbWndExtra          = 0; 
  2398.    wndClass.hInstance           = hInstance;
  2399.    wndClass.hIcon               = NULL; 
  2400.    wndClass.hCursor             = LoadCursor(NULL, IDC_ARROW); 
  2401.    wndClass.hbrBackground       = (HBRUSH)GetStockObject(BLACK_BRUSH);
  2402.    wndClass.lpszMenuName        = NULL; 
  2403.    wndClass.lpszClassName       = zm_pszWindowClassName; 
  2404.         
  2405.    ::RegisterClass(&wndClass);
  2406.         
  2407.    wndClass.lpfnWndProc = DefWindowProc;
  2408.    wndClass.lpszClassName       = "DefWindowProc"; 
  2409.    ::RegisterClass(&wndClass);
  2410.         
  2411.    ::RegisterClass(&wndClass);
  2412.     
  2413.    zm_hwnd = CreateWindow(
  2414.       zm_pszWindowClassName, 
  2415.       zm_pszWindowName, 
  2416.       WS_BORDER | WS_CAPTION | WS_CLIPCHILDREN | WS_VISIBLE | WS_SYSMENU, 
  2417.       100, 
  2418.       100,
  2419.       z_PaneWidth + 200,
  2420.       z_PaneHeight + 70,
  2421.       NULL, 
  2422.       NULL, 
  2423.       hInstance, 
  2424.       NULL);
  2425.         
  2426.    zm_comboHWND= CreateWindow(
  2427.       "COMBOBOX", 
  2428.       "combo", 
  2429.       WS_VISIBLE | WS_CHILD | CBS_DROPDOWN | WS_VSCROLL, 
  2430.       10, 
  2431.       10,
  2432.       400,
  2433.       300,
  2434.       zm_hwnd, 
  2435.       NULL, 
  2436.       hInstance, 
  2437.       NULL);
  2438.         
  2439.    zm_displayOuter = CreateWindow(
  2440.       "DefWindowProc", 
  2441.       "combo", 
  2442.       WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN, 
  2443.       10, 
  2444.       40,
  2445.       z_PaneWidth,
  2446.       z_PaneHeight,
  2447.       zm_hwnd, 
  2448.       NULL, 
  2449.       hInstance, 
  2450.       NULL);
  2451.         
  2452.    zm_displayInner = CreateWindow(
  2453.       "DefWindowProc", 
  2454.       "combo", 
  2455.       WS_VISIBLE | WS_CHILD, 
  2456.       0, 
  2457.       0,
  2458.       z_PaneWidth,
  2459.       z_PaneHeight,
  2460.       zm_displayOuter, 
  2461.       NULL, 
  2462.       hInstance, 
  2463.       NULL);
  2464.         
  2465.    int count = 0;
  2466.    char name[200]; /* Flawfinder: ignore */
  2467.    for(int j = 0; j < z_nNumberTransitionTypes; ++j)
  2468.    {
  2469.       for(int i = 0; i< z_TransitionTable[j].m_nNum; ++i)
  2470.       {
  2471.          if (count < 200)
  2472.          {
  2473.             if (z_TransitionTable[j].m_pSubTypes[i].m_pTranName)
  2474.             {
  2475.                SafeSprintf(name,200, "%s - %s (%d)",z_TransitionTable[j].m_pName,z_TransitionTable[j].m_pSubTypes[i].m_pTranName,z_TransitionTable[j].m_pSubTypes[i].m_SMPTE);
  2476.                SendMessage(zm_comboHWND, CB_ADDSTRING, 0, (long)name);
  2477.                theTranMap[count].in = count;
  2478.                theTranMap[count].type = j;
  2479.                theTranMap[count].subType = i;
  2480.                count++;
  2481.             }
  2482.          }
  2483.       }
  2484.    }
  2485.         
  2486.    int number = SendMessage(zm_comboHWND, CB_GETCOUNT, 0, 0);
  2487.    SendMessage(zm_comboHWND, CB_SETCURSEL, CurrentTransition, 0);
  2488. #ifndef NO_GRAPHICS
  2489.    SetTimer(zm_hwnd, 1, 1, NULL);
  2490. #endif
  2491.    MSG msg;
  2492.    while (GetMessage(&msg,NULL,0,0))
  2493.    {
  2494.       if (msg.message == WM_QUIT)
  2495.          break;
  2496.                 
  2497.       TranslateMessage(&msg);
  2498.       // Dispatches message to window
  2499.       DispatchMessage(&msg);
  2500.    }
  2501.         
  2502.    return msg.wParam ;
  2503. }
  2504. #endif