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

Symbian

开发平台:

C/C++

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