drawline.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:17k
源码类别:

Symbian

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Source last modified: $Id: drawline.cpp,v 1.1.1.1.42.1 2004/07/09 01:59:28 hubbe Exp $
  3.  * 
  4.  * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
  5.  * 
  6.  * The contents of this file, and the files included with this file,
  7.  * are subject to the current version of the RealNetworks Public
  8.  * Source License (the "RPSL") available at
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed
  10.  * the file under the current version of the RealNetworks Community
  11.  * Source License (the "RCSL") available at
  12.  * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
  13.  * will apply. You may also obtain the license terms directly from
  14.  * RealNetworks.  You may not use this file except in compliance with
  15.  * the RPSL or, if you have a valid RCSL with RealNetworks applicable
  16.  * to this file, the RCSL.  Please see the applicable RPSL or RCSL for
  17.  * the rights, obligations and limitations governing use of the
  18.  * contents of the file.
  19.  * 
  20.  * Alternatively, the contents of this file may be used under the
  21.  * terms of the GNU General Public License Version 2 or later (the
  22.  * "GPL") in which case the provisions of the GPL are applicable
  23.  * instead of those above. If you wish to allow use of your version of
  24.  * this file only under the terms of the GPL, and not to allow others
  25.  * to use your version of this file under the terms of either the RPSL
  26.  * or RCSL, indicate your decision by deleting the provisions above
  27.  * and replace them with the notice and other provisions required by
  28.  * the GPL. If you do not delete the provisions above, a recipient may
  29.  * use your version of this file under the terms of any one of the
  30.  * RPSL, the RCSL or the GPL.
  31.  * 
  32.  * This file is part of the Helix DNA Technology. RealNetworks is the
  33.  * developer of the Original Code and owns the copyrights in the
  34.  * portions it created.
  35.  * 
  36.  * This file, and the files included with this file, is distributed
  37.  * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
  38.  * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
  39.  * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
  40.  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
  41.  * ENJOYMENT OR NON-INFRINGEMENT.
  42.  * 
  43.  * Technology Compatibility Kit Test Suite(s) Location:
  44.  *    http://www.helixcommunity.org/content/tck
  45.  * 
  46.  * Contributor(s):
  47.  * 
  48.  * ***** END LICENSE BLOCK ***** */
  49. #include <stdlib.h>
  50. #include <math.h>
  51. #include "hxtypes.h"
  52. #include "drawline.h"
  53. #ifdef _DEBUG
  54. #include "region.h" //just for _DumpString
  55. #include <stdio.h>
  56. #endif
  57. #define BLURALPHA(x,color) 
  58.            {
  59.               int   alphap = 255-(((x)&0xff000000)>>24);
  60.               int     alpha  = 255-(((color)&0xff000000)>>24);
  61.               ULONG32 newalp = (255-((alphap*alpha)/255))<<24;
  62.               (x) = ((x)&0x00ffffff)|newalp;
  63.            }
  64. void WriteBits(UCHAR *pBuffer, UINT8 bpp, UINT8 red, UINT8 green, UINT8 blue);
  65. BOOL DrawOffColor(UINT32 ulStyle, UINT32 nPixelCount);
  66. //color is now interpreted as a color if it is has no alpha channel.
  67. //if the color does have an alpha channel value(non-zero) then we
  68. //are blending borders and will only write the alphavalue into the
  69. //destination pixels. If the destination has alpha values then we
  70. //will 
  71. void DrawLine( int* bits,
  72.                int  width,
  73.                int  x0,
  74.                int  y0,
  75.                int  x1,
  76.                int  y1,
  77.                ULONG32 color
  78.                )
  79. {
  80.     int temp, adjUp, adjDown, errorTerm, xAdvance, xDelta, yDelta,
  81.         wholeStep, initialPixelCount, finalPixelCount, i, j;
  82.     BOOL bBlended = FALSE;
  83.     
  84.     if( color & 0xff000000)
  85.     {
  86.        //This is a blended border line. Just mess with the alpha channel.
  87.        bBlended = TRUE;
  88.     }
  89.     
  90.     // We'll always draw top to bottom to reduce the number of cases we have to
  91.     // handle, and to make lines between the same endpoints draw the same pixels
  92.     if (y0 > y1)
  93.     {
  94.         temp = y0;
  95.         y0 = y1;
  96.         y1 = temp;
  97.         temp = x0;
  98.         x0 = x1;
  99.         x1 = temp;
  100.     }
  101.     int* p = bits + x0 + y0 * width;
  102.     // Figure out if we're going left or right, and how far we're going horizontally
  103.     if ((xDelta = x1 - x0) < 0)
  104.     {
  105.         xAdvance = -1;
  106.         xDelta = -xDelta;
  107.     }
  108.     else
  109.     {
  110.         xAdvance = 1;
  111.     }
  112.     // Figure out how far we're going vertically
  113.     yDelta = y1 - y0;
  114.     // Special-case horizontal, vertical and diagonal lines, for speed and to avoid
  115.     // boundary conditions and divide by 0
  116.     if (!xDelta)
  117.     {
  118.         // vertical line
  119.         for (i = 0; i <= yDelta; ++i)
  120.         {
  121.            if( !bBlended )
  122.               *p = color;
  123.            else
  124.               BLURALPHA(*p, color);
  125.            
  126.            p += width;
  127.         }
  128.         return;
  129.     }
  130.     if (!yDelta)
  131.     {
  132.         // horizontal line
  133.         for (i = 0; i <= xDelta; ++i)
  134.         {
  135.            if( !bBlended )
  136.               *p = color;
  137.            else
  138.               BLURALPHA(*p, color);
  139.            p += xAdvance;
  140.         }
  141.         return;
  142.     }
  143.     if (xDelta == yDelta)
  144.     {
  145.         // diagonal line
  146.         for (i = 0; i <= xDelta; ++i)
  147.         {
  148.            if( !bBlended )
  149.               *p = color;
  150.            else
  151.               BLURALPHA(*p, color);
  152.            p += width + xAdvance;
  153.         }
  154.         return;
  155.     }
  156.     // determins whether line is X or Y major
  157.     if (xDelta > yDelta)
  158.     {
  159.         // X major line
  160.         // minimum number of pixels in a run
  161.         wholeStep = xDelta / yDelta;
  162.         // Error term adjust each time Y steps by 1; used to tell when
  163.         // one extra pixel should be drawn as part of a run, to account for
  164.         // fractional steps along the X axis per 1 pixel steps along Y
  165.         adjUp = (xDelta % yDelta) * 2;
  166.         // Error term adjust when the error term turns over, used to factor
  167.         // out the X step made at that time
  168.         adjDown = yDelta * 2;
  169.         // Initial error term reflects an initial step of 0.5 along the Y axis
  170.         errorTerm = (xDelta % yDelta) - (yDelta * 2);
  171.         // The initial and last runs are partial, because Y advances only 0.5
  172.         // for these runs, rather than 1.  Divide one full run, plus the
  173.         // initial pixel, between the initail and last runs
  174.         initialPixelCount = (wholeStep / 2) + 1;
  175.         finalPixelCount = initialPixelCount;
  176.         // If the basic run length is even and there's no fractional
  177.         // advance, we have one pixel that could go to either the initial
  178.         // or last partial run, which we'll arbitrarily allocate to the last run
  179.         if ((!adjUp) && ((wholeStep & 1) == 0))
  180.         {
  181.             --initialPixelCount;
  182.         }
  183.         // If ther are an odd number of pixels per run, we have 1 pixel that can't
  184.         // be allocated to either the initial or last partial run, so we'll add 0.5
  185.         // to the error term so this pixel will be handled by the normal full-run loop
  186.         if (wholeStep & 1)
  187.         {
  188.             errorTerm += yDelta;
  189.         }
  190.         // Draw the first partial run of pixels
  191.         for (j = 0; j < initialPixelCount; ++j)
  192.         {
  193.             if( !bBlended )
  194.                *p = color;
  195.             else
  196.                BLURALPHA(*p, color);
  197.             p += xAdvance;
  198.         }
  199.         p += width;
  200.         // Draw all full runs
  201.         for (i = 0; i < yDelta - 1; ++i)
  202.         {
  203.             // advance the error term and add an extra pixel if indicated
  204.             if ((errorTerm += adjUp) > 0)
  205.             {
  206.                 errorTerm -= adjDown;
  207.                 // Draw this scan lines run
  208.                 for (j = 0; j < wholeStep + 1; ++j)
  209.                 {
  210.                    if( !bBlended )
  211.                       *p = color;
  212.                    else
  213.                       BLURALPHA(*p, color);
  214.                    p += xAdvance;
  215.                 }
  216.             }
  217.             else
  218.             {
  219.                 // Draw this scan lines run
  220.                 for (j = 0; j < wholeStep; ++j)
  221.                 {
  222.                    if( !bBlended )
  223.                       *p = color;
  224.                    else
  225.                       BLURALPHA(*p, color);
  226.                    p += xAdvance;
  227.                 }
  228.             }
  229.             p += width;
  230.         }
  231.         // Draw final run
  232.         for (j = 0; j < finalPixelCount; ++j)
  233.         {
  234.            if( !bBlended )
  235.               *p = color;
  236.            else
  237.               BLURALPHA(*p, color);
  238.            p += xAdvance;
  239.         }
  240.         return;
  241.     }
  242.     else
  243.     {
  244.         // Y major line 
  245.         // for comments see above section
  246.         wholeStep = yDelta / xDelta;
  247.         adjUp = (yDelta % xDelta) * 2;
  248.         adjDown = xDelta * 2;
  249.         errorTerm = (yDelta % xDelta) - (xDelta * 2);
  250.         initialPixelCount = (wholeStep / 2) + 1;
  251.         finalPixelCount = initialPixelCount;
  252.         if ((!adjUp) && ((wholeStep & 1) == 0))
  253.         {
  254.             --initialPixelCount;
  255.         }
  256.         if (wholeStep & 1)
  257.         {
  258.             errorTerm += xDelta;
  259.         }
  260.         for (j = 0; j < initialPixelCount; ++j)
  261.         {
  262.            if( !bBlended )
  263.               *p = color;
  264.            else
  265.               BLURALPHA(*p, color);
  266.            p += width;
  267.         }
  268.         p += xAdvance;
  269.         for (i = 0; i < xDelta - 1; ++i)
  270.         {
  271.             if ((errorTerm += adjUp) > 0)
  272.             {
  273.                 errorTerm -= adjDown;
  274.                 for (j = 0; j < wholeStep + 1; ++j)
  275.                 {
  276.                    if( !bBlended )
  277.                       *p = color;
  278.                    else
  279.                       BLURALPHA(*p, color);
  280.                    p += width;
  281.                 }
  282.             }
  283.             else
  284.             {
  285.                 for (j = 0; j < wholeStep; ++j)
  286.                 {
  287.                    if( !bBlended )
  288.                       *p = color;
  289.                    else
  290.                       BLURALPHA(*p, color);
  291.                    p += width;
  292.                 }
  293.             }
  294.             p += xAdvance;
  295.         }
  296.         for (j = 0; j < finalPixelCount; ++j)
  297.         {
  298.            if( !bBlended )
  299.               *p = color;
  300.            else
  301.               BLURALPHA(*p, color);
  302.            p += width;
  303.         }
  304.         return;
  305.     }
  306. }
  307. BOOL DrawOffColor(INT32 *pPattern,
  308.                   INT32 nEntries,
  309.                   INT32 nPixelsInPattern,
  310.                   UINT32 nPixelCount)
  311. {
  312.     BOOL bRet = FALSE;
  313.     INT32 nMod = nPixelCount % nPixelsInPattern;
  314.     INT32 nPixelSum = 0;
  315.     for (int i=0; i<nEntries; i++)
  316.     {
  317.         nPixelSum += pPattern[i];
  318.         if (nPixelSum > nMod)
  319.         {
  320.             bRet = i % 2;
  321.             break;
  322.         }
  323.     }
  324.     return bRet;
  325. }
  326. void WriteBits(UCHAR *pBuffer, UINT8 bpp, UINT8 red, UINT8 green, UINT8 blue)
  327. {
  328.     if (bpp == 32)
  329.     {
  330.         pBuffer[0] = blue;
  331.         pBuffer[1] = green;
  332.         pBuffer[2] = red;
  333.         pBuffer[3] = 0;
  334.     }
  335.     else if (bpp == 24)
  336.     {
  337.         pBuffer[0] = blue;
  338.         pBuffer[1] = green;
  339.         pBuffer[2] = red;
  340.     }
  341.     // Use most significant bits when "dithering" to RGB565
  342.     else if (bpp == 16)
  343.     {
  344.         pBuffer[0] = 0;
  345.         pBuffer[1] = 0;
  346.         pBuffer[0] |= blue & 0xF8;
  347.         pBuffer[0] |= red>>5;
  348.         pBuffer[1] |= (red & 0x1C)<<3;
  349.         pBuffer[1] |= green>>3;
  350.     }
  351.     // Use most significant bits when "dithering" to RGB555 (NEED TO TEST!!!)
  352.     else if (bpp == 15)
  353.     {
  354.         pBuffer[0] = 0;
  355.         pBuffer[1] = 0;
  356.         pBuffer[0] |= blue & 0xF8;
  357.         pBuffer[0] |= red>>5;
  358.         pBuffer[1] |= (red & 0x18)<<3;
  359.         pBuffer[1] |= (green & 0xF8)>>3;
  360.     }
  361. }
  362. void StraightLine(void *pImage,
  363.                   INT32 nPitch,
  364.                   INT32 bpp,
  365.                   INT32 nImageWidth, INT32 nImageHeight,
  366.                   INT32 x0, INT32 y0,
  367.                   INT32 x1, INT32 y1,
  368.                   UINT8 lineWidth,
  369.                   PixelProps *pPrimaryPixels,
  370.                   PixelProps *pSecondaryPixels,
  371.                   INT32 ulLineSytle,
  372.                   INT32 *pCustomPattern, INT32 nCustomEntries)
  373. {
  374.     // Assume image is alwas draw top-down - cross platform??? yikes
  375.     if (nPitch < 0)
  376.         nPitch *= -1;
  377.     UINT8 *pBuffer = (UINT8*)pImage;
  378.     INT32 aPattern[2];
  379.     PixelProps *pColor = pPrimaryPixels;
  380.     if (ulLineSytle != CUSTOM_LINE)
  381.     {
  382.         // Build our own custom pattern list
  383.         if (ulLineSytle == SOLID_LINE)
  384.         {
  385.             aPattern[0] = 2;
  386.             aPattern[1] = 0;
  387.         }
  388.         else if (ulLineSytle == DOTTED_LINE)
  389.         {
  390.             aPattern[0] = 2;
  391.             aPattern[1] = 2;
  392.         }
  393.         else if (ulLineSytle == DASHED_LINE)
  394.         {
  395.             aPattern[0] = 16;
  396.             aPattern[1] = 8;
  397.         }
  398.         pCustomPattern = aPattern;
  399.         nCustomEntries = 2;
  400.     }
  401.     INT32 nPatternPixelSum = 0;
  402.     for (int i=0; i<nCustomEntries; i++)
  403.         nPatternPixelSum += pCustomPattern[i];
  404.         
  405.     INT32 x0orig = x0;
  406.     INT32 y0orig = y0;
  407.     INT32 x1orig = x1;
  408.     INT32 y1orig = y1;
  409.     // Draw a line for each pixel width
  410.     for (int j=0; j<lineWidth; j++)
  411.     {        
  412.         INT32 nPixelCount = 0;
  413.         // Line length for x and y line components
  414.         INT32 yDelta = y1 - y0;
  415.         INT32 xDelta = x1 - x0;
  416.     
  417.         // Bytes to move for the next xy pixel
  418.         INT32 nNextXPixel = bpp>>3,
  419.               nNextYPixel = nPitch;
  420.     
  421.         // Handle negative xy deltas
  422.         if (yDelta < 0)
  423.         { 
  424.             yDelta = -yDelta;
  425.             nNextYPixel = -nNextYPixel;
  426.         }
  427.     
  428.         if (xDelta < 0)
  429.         {
  430.             xDelta = -xDelta;
  431.             nNextXPixel = -nNextXPixel;
  432.         }
  433.         // Move x and y points to their corresponding byte offset in the image
  434.         y0 *= nPitch;
  435.         y1 *= nPitch;
  436.         x0 *= abs(nNextXPixel);
  437.         x1 *= abs(nNextXPixel);
  438.         pColor = pPrimaryPixels;
  439.         // Write the first pixel in the line
  440.         if (DrawOffColor(pCustomPattern,
  441.                          nCustomEntries,
  442.                          nPatternPixelSum,
  443.                          nPixelCount))
  444.         {
  445.             pColor = pSecondaryPixels;
  446.         }
  447.         
  448.         if (pColor->bHasColors)
  449.         {
  450.             WriteBits(&pBuffer[x0+y0], (UINT8)bpp, 
  451.                       pColor->red,
  452.                       pColor->green,
  453.                       pColor->blue);
  454.         }
  455.         ++nPixelCount;
  456.         if (xDelta > yDelta)
  457.         {
  458.             // Slope more horizontal, so incrment the x value by 1 and 
  459.             // calculate a new y value.
  460.             float slope = (float)(yDelta / xDelta * nNextYPixel);
  461.             float newY = (float)(.5 + slope + y0);
  462.         
  463.             // Set points for next line
  464.             ++y0orig;
  465.             ++y1orig;
  466.         
  467.             while (x0 != x1)
  468.             {
  469.                 x0 += nNextXPixel;
  470.                 newY += slope;
  471.             
  472.                 pColor = pPrimaryPixels;
  473.                 if (DrawOffColor(pCustomPattern,
  474.                                  nCustomEntries,
  475.                                  nPatternPixelSum,
  476.                                  nPixelCount))
  477.                 {
  478.                     pColor = pSecondaryPixels;
  479.                 }
  480.         
  481.                 if (pColor->bHasColors)
  482.                 {
  483.                     WriteBits(&pBuffer[x0+(INT32)newY], (UINT8)bpp, 
  484.                               pColor->red,
  485.                               pColor->green,
  486.                               pColor->blue);
  487.                 }
  488.             
  489.                 ++nPixelCount;
  490.             }
  491.         }
  492.         else
  493.         {
  494.             // Slope more vertical, so incrment the y value by 1 and 
  495.             // calculate a new x value.
  496.             float slope = (float)(xDelta / yDelta * nNextXPixel);
  497.             float newX = (float)(.5 + slope + x0);
  498.             // Set points for next line
  499.             ++x0orig;
  500.             ++x1orig;
  501.         
  502.             while (y0 != y1)
  503.             {
  504.                 y0 += nNextYPixel;
  505.                 newX += slope;
  506.                 pColor = pPrimaryPixels;
  507.                 if (DrawOffColor(pCustomPattern,
  508.                                  nCustomEntries,
  509.                                  nPatternPixelSum,
  510.                                  nPixelCount))
  511.                 {
  512.                     pColor = pSecondaryPixels;
  513.                 }
  514.         
  515.                 if (pColor->bHasColors)
  516.                 {
  517.                     WriteBits(&pBuffer[(INT32)newX+y0], (UINT8)bpp, 
  518.                               pColor->red,
  519.                               pColor->green,
  520.                               pColor->blue);
  521.                 }
  522.             
  523.                 ++nPixelCount;
  524.             }
  525.         }
  526.         // Reset points to pixels instead of byte offsets
  527.         x0 = x0orig;
  528.         x1 = x1orig;
  529.         y0 = y0orig;
  530.         y1 = y1orig;
  531.     }
  532. }