HMG Graph based on Bos Taurus

HMG Samples and Enhancements

Moderator: Rathinagiri

User avatar
Rathinagiri
Posts: 5471
Joined: Tue Jul 29, 2008 6:30 pm
DBs Used: MariaDB, SQLite, SQLCipher and MySQL
Location: Sivakasi, India
Contact:

HMG Graph based on Bos Taurus

Post by Rathinagiri »

Hi friends,

Now, we can save/show HMG Graphs (BARS/LINES/POINTS/PIE with 3D also) in bitmap format. I have reused the h_graph.prg and c_graph.c code according to Bas Taurus. I think this can be included ( after rigorous testing ) in our HMG Code.

Claudio, this code contains code for drawing polygons, Polybeziers, arcs and pie. I think you can use them in the next version of Bas Taurus.
Clipboard01.jpg
Clipboard01.jpg (59.52 KiB) Viewed 12294 times

Code: Select all

#include <hmg.ch>

Function Main


   define window graph at 0, 0 width 1000 height 700 main 
      define label selecttype
         row 10
         col 10
         width 150
         value 'Select Graph Type'
      end label
      define combobox graphtype
         row 10
         col 160
         width 100
         items { 'Bar', 'Lines', 'Points', 'Pie' }
         onchange drawgraph()
      end combobox   
      define checkbox enable3d
         row 10
         col 280
         width 100
         caption 'Enable 3D'
         onchange drawgraph()
      end checkbox   
      define image grapharea
         row 50
         col 50
         width 600
         height 600
      end image
   end window
   graph.graphtype.value := 1
   graph.center
   graph.activate
Return


function drawgraph
   local cImage := 'graph.bmp'
   local nImageWidth := 600
   local nImageHeight := 600
   local cTitle := 'Sample Graph'
   local aYValues := {"Jan","Feb","Mar","Apr","May"}
   local aData := { {14280,20420,12870,25347, 7640},;
           { 8350,10315,15870, 5347,12340},;
           {12345, -8945,10560,15600,17610} }
   local nBarDepth := 15
   local nBarWidth := 15   
   local nHValues := 5
   local l3D := graph.enable3D.value
   local lGrid := .t.
   local lXGrid := .t.
   local lYGrid := .t.
   local lXVal := .t.
   local lYVal := .t.
   local nGraphType := graph.graphtype.value
   local lViewVal := .t.
   local lLegends := .t.
   local cPicture := '99,999.99'
   local aSeries := {"Serie 1","Serie 2","Serie 3"}
   local aColors := { {128,128,255}, {255,102, 10}, {55,201, 48} }
   local lNoBorder := .f.
   local nLegendWidth := 50
   if graph.graphtype.value == 0
      return nil
   endif
   if graph.graphtype.value == 4 // pie
      drawpiegraphinBitMap( cImage, nImageWidth, nImageHeight, {1500,1800,200,500,800}, {"Product 1","Product 2","Product 3","Product 4","Product 5"}, {{255,0,0},{0,0,255},{255,255,0},{0,255,0},{255,128,64},{128,0,128}}, "Sales", 25, l3D, lxval, lLegends, lnoborder )   
   else      
      graphsave( cImage, nImageWidth, nImageHeight, aData,  cTitle, aYValues, nBarDepth, nBarWidth, nil, nHValues, l3d, lGrid, lXGrid, lYGrid, ;
               lXVal, lYVal, lLegends, aSeries, aColors, nGraphType, lViewVal, cPicture, nLegendWidth ,lNoBorder ) 
   endif               
   graph.grapharea.picture := 'graph.bmp'
   return nil
   
function graphsave( cImageFileName, nWidth, nHeight, aData, cTitle, aYVals, nBarD, nWideB, nSep, nXRanges, ;
	              l3D, lGrid, lxGrid, lyGrid, lxVal, lyVal, lLegends, aSeries, aColors, nType, lViewVal, cPicture , nLegendWindth , lNoborder )
                 
   LOCAL nI, nJ, nPos, nMax, nMin, nMaxBar, nDeep
   LOCAL nRange, nResH, nResV,  nWide, aPoint, cName
   LOCAL nXMax, nXMin, nHigh, nRel, nZero, nRPos, nRNeg
   local hBitMap, hDC, BTStruct
   local nTop := 0
   local nLeft := 0
   local nBottom := nHeight
   local nRight := nWidth

	DEFAULT cTitle   := ""
	DEFAULT nSep     := 0
	DEFAULT cPicture := "999,999.99"
	DEFAULT nLegendWindth := 50
   private nPenWidth := 1

	If ( HMG_LEN (aSeries) != HMG_LEN ( aData ) ) .or. ;
		( HMG_LEN ( aSeries ) != HMG_LEN ( aColors ) ) 
		MsgHMGError("DRAW GRAPH: 'Series' / 'SerieNames' / 'Colors' arrays size mismatch. Program terminated", "HMG Error" )
	EndIf

   hBitMap := BT_BitmapCreateNew ( nWidth, nHeight, { 255, 255, 255 } )
   hDC := BT_CreateDC( hBitMap, BT_HDC_BITMAP, @BTStruct )

   IF lGrid
      lxGrid := lyGrid := .T.
   ENDIF
   
   IF nBottom <> NIL .AND. nRight <> NIL
      nHeight := nBottom - nTop / 2
      nWidth  := nRight - nLeft / 2
      nBottom -= IF( lyVal, 42, 32)
      nRight  -= IF( lLegends, 32 + nLegendWindth , 32 )
   ENDIF
   nTop    += 1 + IF( Empty( cTitle ), 30, 44 )             // Top gap
   nLeft   += 1 + IF( lxVal, 80 + nBarD, 30 + nBarD )     // LEFT
   DEFAULT nBottom := nHeight - 2 - IF( lyVal, 40, 30 )    // Bottom
   DEFAULT nRight  := nWidth - 2 - IF( lLegends, 30 + nLegendWindth , 30 ) // RIGHT

   l3D     := IF( nType == POINTS, .F., l3D )
   nDeep   := IF( l3D, nBarD, 1 )
   nMaxBar := nBottom - nTop - nDeep - 5
   nResH   := nResV := 1
   nWide   := ( nRight - nLeft )* nResH / ( nMax( aData ) + 1 ) * nResH

   // Graph area
   //
   IF ! lNoborder
	   DrawWindowBoxInBitMap( hDC, Max( 1, nTop - 44 ), Max( 1, nLeft - 80 - nBarD ), nHeight - 1, nWidth - 1 )
   ENDIF	

   // Back area
   //
   IF l3D
      drawrectinbitmap( hDC, nTop+1, nLeft, nBottom - nDeep, nRight, { 255, 255, 255 } )
   ELSE
      drawrectinbitmap( hDC, nTop-5, nLeft, nBottom, nRight, { 255, 255, 255 } )
   ENDIF

   IF l3D
      // Bottom area
      FOR nI := 1 TO nDeep+1
          DrawLineinbitmap( hDC, nBottom-nI, nLeft-nDeep+nI, nBottom-nI, nRight-nDeep+nI, { 255, 255, 255 } )
      NEXT nI

      // Lateral
      FOR nI := 1 TO nDeep
          DrawLineinbitmap( hDC, nTop+nI, nLeft-nI, nBottom-nDeep+nI, nLeft-nI, {192, 192, 192} )
      NEXT nI

      // Graph borders
      FOR nI := 1 TO nDeep+1
          DrawLineinbitmap( hDC, nBottom-nI     ,nLeft-nDeep+nI-1 ,nBottom-nI     ,nLeft-nDeep+nI  ,GRAY )
          DrawLineinbitmap( hDC, nBottom-nI     ,nRight-nDeep+nI-1,nBottom-nI     ,nRight-nDeep+nI ,BLACK )
          DrawLineinbitmap( hDC, nTop+nDeep-nI+1,nLeft-nDeep+nI-1 ,nTop+nDeep-nI+1,nLeft-nDeep+nI  ,BLACK )
          DrawLineinbitmap( hDC, nTop+nDeep-nI+1,nLeft-nDeep+nI-3 ,nTop+nDeep-nI+1,nLeft-nDeep+nI-2,BLACK )
      NEXT nI

      FOR nI=1 TO nDeep+2
          DrawLineinbitmap( hDC, nTop+nDeep-nI+1,nLeft-nDeep+nI-3,nTop+nDeep-nI+1,nLeft-nDeep+nI-2 ,BLACK )
          DrawLineinbitmap( hDC, nBottom+ 2-nI+1,nRight-nDeep+nI ,nBottom+ 2-nI+1,nRight-nDeep+nI-2,BLACK )
      NEXT nI

      DrawLineinbitmap( hDC, nTop         ,nLeft        ,nTop           ,nRight       ,BLACK )
      DrawLineinbitmap( hDC, nTop- 2      ,nLeft        ,nTop- 2        ,nRight+ 2    ,BLACK )
      DrawLineinbitmap( hDC, nTop         ,nLeft        ,nBottom-nDeep  ,nLeft        ,GRAY  )
      DrawLineinbitmap( hDC, nTop+nDeep   ,nLeft-nDeep  ,nBottom        ,nLeft-nDeep  ,BLACK )
      DrawLineinbitmap( hDC, nTop+nDeep   ,nLeft-nDeep-2,nBottom+ 2     ,nLeft-nDeep-2,BLACK )
      DrawLineinbitmap( hDC, nTop         ,nRight       ,nBottom-nDeep  ,nRight       ,BLACK )
      DrawLineinbitmap( hDC, nTop- 2      ,nRight+ 2    ,nBottom-nDeep+2,nRight+ 2    ,BLACK )
      DrawLineinbitmap( hDC, nBottom-nDeep,nLeft        ,nBottom-nDeep  ,nRight       ,GRAY  )
      DrawLineinbitmap( hDC, nBottom      ,nLeft-nDeep  ,nBottom        ,nRight-nDeep ,BLACK )
      DrawLineinbitmap( hDC, nBottom+ 2   ,nLeft-nDeep-2,nBottom+ 2     ,nRight-nDeep ,BLACK )
   ENDIF


   // Graph info
   //

   IF !Empty(cTitle)
      DrawTextInBitmap( hDC, nTop - 30 * nResV, nLeft, cTitle, 'Arial', 12, RED, 2 )
   ENDIF


   // Legends
   //
   IF lLegends
      nPos := nTop
      FOR nI := 1 TO HMG_LEN( aSeries )
         DrawBarinbitmap( hDC, nRight+(8*nResH), nPos+(9*nResV), 8*nResH, 7*nResV, l3D, 1, aColors[nI] )
         DrawTextInBitmap( hDC, nPos, nRight+(20*nResH), aSeries[nI], 'Arial', 8, BLACK, 0 )
         nPos += 18*nResV
      NEXT nI
   ENDIF

   // Max, Min values
   nMax := 0
   FOR nJ := 1 TO HMG_LEN(aSeries)
      FOR nI :=1 TO HMG_LEN(aData[nJ])
         nMax := Max( aData[nJ][nI], nMax )
      NEXT nI
   NEXT nJ
   nMin := 0
   FOR nJ := 1 TO HMG_LEN(aSeries)
      FOR nI :=1 TO HMG_LEN(aData[nJ])
         nMin := Min( aData[nJ][nI], nMin )
      NEXT nI
   NEXT nJ

   nXMax := IF( nMax > 0, DetMaxVal( nMax ), 0 )
   nXMin := IF( nMin < 0, DetMaxVal( nMin ), 0 )
   nHigh := nXMax + nXMin
   nMax  := Max( nXMax, nXMin )
   
   nRel  := ( nMaxBar / nHigh )
   nMaxBar := nMax * nRel



   nZero := nTop + (nMax*nRel) + nDeep + 5    // Zero pos
   IF l3D
      FOR nI := 1 TO nDeep+1
          DrawLineinbitmap( hDC, nZero-nI+1, nLeft-nDeep+nI   , nZero-nI+1, nRight-nDeep+nI, {192, 192, 192} )
      NEXT nI
      FOR nI := 1 TO nDeep+1
          DrawLineinbitmap( hDC, nZero-nI+1, nLeft-nDeep+nI-1 , nZero-nI+1, nLeft -nDeep+nI, GRAY )
          DrawLineinbitmap( hDC, nZero-nI+1, nRight-nDeep+nI-1, nZero-nI+1, nRight-nDeep+nI, BLACK )
      NEXT nI
      DrawLineinbitmap( hDC, nZero-nDeep, nLeft, nZero-nDeep, nRight, GRAY )
   ENDIF

   aPoint := Array( HMG_LEN( aSeries ), HMG_LEN( aData[1] ), 2 )
   nRange := nMax / nXRanges

   // xLabels
   nRPos := nRNeg := nZero - nDeep
   FOR nI := 0 TO nXRanges
      IF lxVal
         IF nRange*nI <= nXMax
            DrawTextInBitmap( hDC, nRPos, nLeft-nDeep-70, Transform(nRange*nI, cPicture), 'Arial', 8, BLUE )
         ENDIF
         IF nRange*(-nI) >= nXMin*(-1)
            DrawTextInBitmap( hDC, nRNeg, nLeft-nDeep-70, Transform(nRange*-nI, cPicture), 'Arial', 8, BLUE )
         ENDIF
      ENDIF

      IF lxGrid
         IF nRange*nI <= nXMax
            IF l3D
               FOR nJ := 0 TO nDeep + 1
                  DrawLineinbitmap( hDC, nRPos + nJ, nLeft - nJ - 1, nRPos + nJ, nLeft - nJ, BLACK )
               NEXT nJ
            ENDIF
            DrawLineinbitmap( hDC, nRPos, nLeft, nRPos, nRight, BLACK )
         ENDIF
         IF nRange*-nI >= nXMin*-1
            IF l3D
               FOR nJ := 0 TO nDeep + 1
                  DrawLineinbitmap( hDC, nRNeg + nJ, nLeft - nJ - 1, nRNeg + nJ, nLeft - nJ, BLACK )
               NEXT nJ
            ENDIF
            DrawLineinbitmap( hDC, nRNeg, nLeft, nRNeg, nRight, BLACK )
         ENDIF
      ENDIF
      nRPos -= ( nMaxBar / nXRanges )
      nRNeg += ( nMaxBar / nXRanges )
   NEXT nI

   IF lYGrid
      nPos:=IF(l3D, nTop, nTop-5 )
      nI  := nLeft + nWide
      FOR nJ := 1 TO nMax(aData)
         DrawlineinBitmap( hDC, nBottom-nDeep, nI, nPos, nI, {100,100,100} )
         DrawlineinBitmap( hDC, nBottom, nI-nDeep, nBottom-nDeep, nI, {100,100,100} )
         nI += nWide
      NEXT
   ENDIF

   DO WHILE .T.    // Bar adjust
      nPos = nLeft + ( nWide / 2 )
      nPos += ( nWide + nSep ) * ( HMG_LEN(aSeries) + 1 ) * HMG_LEN(aData[1])
      IF nPos > nRight
         nWide--
      ELSE
         EXIT
      ENDIF
   ENDDO

   nMin := nMax / nMaxBar

   nPos := nLeft + ( ( nWide + nSep ) / 2 )            // first point graph
   nRange := ( ( nWide + nSep ) * HMG_LEN(aSeries) ) / 2

   IF lyVal .AND. HMG_LEN( aYVals ) > 0                // Show yLabels
      nWideB  := ( nRight - nLeft ) / ( nMax(aData) + 1 )
      nI := nLeft + nWideB
      FOR nJ := 1 TO nMax(aData)
         cName := "yVal_Name_"+LTRIM(STR(nJ))
         DrawTextInBitmap( hDC, nBottom + 8, nI - nDeep - IF(l3D, 0, 8), aYVals[nJ], 'Arial', 8, BLUE )
         nI += nWideB
      NEXT
   ENDIF



   // Bars
   //
	
	IF nType == BARS
		if nMin <> 0
			nPos := nLeft + ( ( nWide + nSep ) / 2 )
			FOR nI=1 TO HMG_LEN(aData[1])
				FOR nJ=1 TO HMG_LEN(aSeries)
					DrawBarinbitmap( hDC, nPos, nZero, aData[nJ,nI] / nMin + nDeep, nWide, l3D, nDeep, aColors[nJ] )
					nPos += nWide+nSep
				NEXT nJ
				nPos += nWide+nSep
			NEXT nI
		endif
	ENDIF

   // Lines
   //
   IF nType == LINES
      if nMin <> 0
         nWideB  := ( nRight - nLeft ) / ( nMax(aData) + 1 )
         nPos := nLeft + nWideB
         FOR nI := 1 TO HMG_LEN(aData[1])
            FOR nJ=1 TO HMG_LEN(aSeries)
               IF !l3D
                  DrawPointinBitmap( hDC, nType, nPos, nZero, aData[nJ,nI] / nMin + nDeep, aColors[nJ] )
               ENDIF
               aPoint[nJ,nI,2] := nPos
               aPoint[nJ,nI,1] := nZero - ( aData[nJ,nI] / nMin + nDeep )
            NEXT nJ
            nPos += nWideB
         NEXT nI

         FOR nI := 1 TO HMG_LEN(aData[1])-1
            FOR nJ := 1 TO HMG_LEN(aSeries)
               IF l3D
                  drawpolygoninbitmap(hDC,{{aPoint[nJ,nI,1],aPoint[nJ,nI,2]},{aPoint[nJ,nI+1,1],aPoint[nJ,nI+1,2]}, ;
                              {aPoint[nJ,nI+1,1]-nDeep,aPoint[nJ,nI+1,2]+nDeep},{aPoint[nJ,nI,1]-nDeep,aPoint[nJ,nI,2]+nDeep}, ;
                              {aPoint[nJ,nI,1],aPoint[nJ,nI,2]}},,,aColors[nJ])
               ELSE
                  DrawLineinbitmap( hDC, aPoint[ nJ, nI, 1 ], aPoint[ nJ, nI, 2 ], aPoint[ nJ, nI+1, 1 ], aPoint[ nJ, nI + 1, 2 ], aColors[ nJ ] )
               ENDIF
            NEXT nJ
         NEXT nI

      endif
   ENDIF

   // Points
   //
   IF nType == POINTS
		if nMin <> 0
         nWideB := ( nRight - nLeft ) / ( nMax(aData) + 1 )
         nPos := nLeft + nWideB
         FOR nI := 1 TO HMG_LEN(aData[1])
            FOR nJ=1 TO HMG_LEN(aSeries)
               DrawPointinBitmap( hDC, nType, nPos, nZero, aData[nJ,nI] / nMin + nDeep, aColors[nJ] )
               aPoint[nJ,nI,2] := nPos
               aPoint[nJ,nI,1] := nZero - aData[nJ,nI] / nMin
            NEXT nJ
            nPos += nWideB
         NEXT nI
      ENDIF
   endif   

   IF lViewVal
      IF nType == BARS
         nPos := nLeft + nWide + ( (nWide+nSep) * ( HMG_LEN(aSeries) / 2 ) )
      ELSE
         nWideB := ( nRight - nLeft ) / ( nMax(aData) + 1 )
         nPos := nLeft + nWideB
      ENDIF
      FOR nI := 1 TO HMG_LEN(aData[1])
         FOR nJ := 1 TO HMG_LEN(aSeries)
            DrawTextInBitmap( hDC, nZero - ( aData[nJ,nI] / nMin + nDeep ), IF(nType == BARS, nPos - IF(l3D, 8, 10), nPos + 10), Transform(aData[nJ,nI], cPicture), 'Arial', 8 )
            nPos+=IF( nType == BARS, nWide + nSep, 0)
         NEXT nJ
         IF nType == BARS
            nPos += nWide + nSep
         ELSE
            nPos += nWideB
         ENDIF
      NEXT nI
   ENDIF

   IF l3D
      DrawLineinbitmap( hDC, nZero, nLeft-nDeep, nZero, nRight-nDeep, BLACK )
   ELSE
      IF nXMax<>0 .AND. nXMin<>0
         DrawLineinbitmap( hDC, nZero-1, nLeft-2, nZero-1, nRight, RED )
      ENDIF

   endif

   BT_BitmapSaveFile(hBitmap, cImageFileName )
   BT_DeleteDC( BTstruct )
   BT_BitmapRelease( hBitmap )

RETURN



function DrawWindowBoxInBitMap( hDC, row, col, rowr, colr )
   BT_DrawRectangle ( hDC, Row, Col, Colr - col, rowr - row, { 0, 0, 0 }, nPenWidth )
return nil
		

   

function drawrectinbitmap( hDC, row, col, row1, col1, aColor )

   BT_DrawFillRectangle (hDC, Row, Col, col1 - col, row1 - row, aColor, aColor, nPenWidth )
return nil   

function DrawLineinbitmap( hDC, Row1, Col1, Row2, Col2, aColor )
   BT_DrawLine ( hDC, Row1, Col1, Row2, Col2, aColor, nPenWidth )
return nil   

function DrawTextInBitmap( hDC, Row, Col, cText, cFontName, nFontSize, aColor, nAlign )
   default nAlign := 0
   do case
   case nAlign == 0
      BT_DrawText ( hDC, Row, Col, cText, cFontName, nFontSize, aColor, )
   case nAlign == 1
      BT_DrawText ( hDC, Row, Col, cText, cFontName, nFontSize, aColor, , BT_TEXT_RIGHT )
   case nAlign == 2
      BT_DrawText ( hDC, Row, Col, cText, cFontName, nFontSize, aColor, , BT_TEXT_CENTER )
   endcase   
return nil   

function DrawBarinbitmap( hDC, nY, nX, nHigh, nWidth, l3D, nDeep, aColor )
   LOCAL nI, nColTop, nShadow, nH := nHigh

   nColTop := ClrShadow( RGB(aColor[1],aColor[2],aColor[3]), 15 )
   nShadow := ClrShadow( nColTop, 15 )
   nColTop := {GetRed(nColTop),GetGreen(nColTop),GetBlue(nColTop)}
   nShadow := {GetRed(nShadow),GetGreen(nShadow),GetBlue(nShadow)}

   FOR nI=1 TO nWidth
      DrawLineinbitmap( hDC, nX, nY+nI, nX+nDeep-nHigh, nY+nI, aColor )  // front
   NEXT nI

   IF l3D
      // Lateral
      drawpolygoninBitmap( hDC,{{nX-1,nY+nWidth+1},{nX+nDeep-nHigh,nY+nWidth+1},;
                   {nX-nHigh+1,nY+nWidth+nDeep},{nX-nDeep,nY+nWidth+nDeep},;
                   {nX-1,nY+nWidth+1}},nShadow,,nShadow )
      // Superior
      nHigh   := Max( nHigh, nDeep )
      drawpolygoninBitmap( hDC,{{nX-nHigh+nDeep,nY+1},{nX-nHigh+nDeep,nY+nWidth+1},;
                   {nX-nHigh+1,nY+nWidth+nDeep},{nX-nHigh+1,nY+nDeep},;
                   {nX-nHigh+nDeep,nY+1}},nColTop,,nColTop )
      // Border
      DrawBoxinBitmap( hDC, nY, nX, nH, nWidth, l3D, nDeep )
   ENDIF

RETURN

STATIC FUNCTION ClrShadow( nColor, nFactor )
   LOCAL aHSL, aRGB

   aHSL := RGB2HSL( GetRed(nColor), GetGreen(nColor), GetBlue(nColor) )
   aHSL[3] -= nFactor
   aRGB := HSL2RGB( aHSL[1], aHSL[2], aHSL[3] )

RETURN RGB( aRGB[1], aRGB[2], aRGB[3] )


STATIC FUNCTION nMax(aData)
   LOCAL nI, nMax := 0

   FOR nI :=1 TO HMG_LEN( aData )
      nMax := Max( HMG_LEN(aData[nI]), nMax )
   NEXT nI

RETURN( nMax )


STATIC FUNCTION DetMaxVal(nNum)
   LOCAL nE, nMax, nMan, nVal, nOffset

   nE:=9
   nVal:=0
   nNum:=Abs(nNum)

   DO WHILE .T.

      nMax := 10**nE

      IF Int(nNum/nMax)>0

         nMan:=(nNum/nMax)-Int(nNum/nMax)
         nOffset:=1
         nOffset:=IF(nMan<=.75,.75,nOffset)
         nOffset:=IF(nMan<=.50,.50,nOffset)
         nOffset:=IF(nMan<=.25,.25,nOffset)
         nOffset:=IF(nMan<=.00,.00,nOffset)
         nVal := (Int(nNum/nMax)+nOffset)*nMax
         EXIT

      ENDIF

      nE--

   ENDDO

RETURN (nVal)


function DrawPointinBitmap( hDC, nType, nY, nX, nHigh, aColor )

   IF nType == POINTS

         DrawCircleinBitmap( hDC, nX - nHigh - 3, nY - 3, 8, aColor )

   ELSEIF nType == LINES

      DrawCircleinBitmap( hDC, nX - nHigh - 2, nY - 2, 6, aColor )

   ENDIF

RETURN

function DrawCircleinBitmap( hDC, nCol, nRow, nWidth, aColor )
   BT_DrawFillEllipse( hDC, nCol, nRow, nWidth, nWidth, aColor, aColor, nPenWidth)
RETURN



function drawpiegraphinBitMap( cImageFileName, nWidth, nHeight, series, aname, colors, ctitle, depth, l3d, lxval, lsleg, lnoborder )
   local fromrow := 0
   local fromcol := 0
   local torow := nHeight
   local tocol := nWidth
   local topleftrow := fromrow
   local topleftcol := fromcol
   local toprightrow := fromrow
   local toprightcol := tocol
   local bottomrightrow := torow
   local bottomrightcol := tocol
   local bottomleftrow := torow
   local bottomleftcol := fromcol
   local middletoprow := fromrow
   local middletopcol := fromcol + int(tocol - fromcol) / 2
   local middleleftrow := fromrow + int(torow - fromrow) / 2
   local middleleftcol := fromcol
   local middlebottomrow := torow
   local middlebottomcol := fromcol + int(tocol - fromcol) / 2
   local middlerightrow := fromrow + int(torow - fromrow) / 2
   local middlerightcol := tocol
   local fromradialrow := 0
   local fromradialcol := 0
   local toradialrow := 0
   local toradialcol := 0
   local degrees := {}
   local cumulative := {}
   local j,i,sum := 0
   local cname := ""
   local shadowcolor := {}
   local previos_cumulative
   local hDC, hBitMap, BTStruct
   
   private nPenWidth := 1


   hBitMap := BT_BitmapCreateNew ( nWidth, nHeight, { 255, 255, 255 } )
   hDC := BT_CreateDC( hBitMap, BT_HDC_BITMAP, @BTStruct )

   if ! lnoborder

      DrawLineinbitmap( hDC, torow  ,fromcol  ,torow  ,tocol  ,WHITE)
      DrawLineinbitmap( hDC, torow-1,fromcol+1,torow-1,tocol-1,GRAY )
      DrawLineinbitmap( hDC, torow-1,fromcol  ,fromrow  ,fromcol  ,GRAY )
      DrawLineinbitmap( hDC, torow-2,fromcol+1,fromrow+1,fromcol+1,GRAY )
      DrawLineinbitmap( hDC, fromrow  ,fromcol  ,fromrow  ,tocol-1,GRAY )
      DrawLineinbitmap( hDC, fromrow+1,fromcol+1,fromrow+1,tocol-2,GRAY )
      DrawLineinbitmap( hDC, fromrow  ,tocol  ,torow  ,tocol  ,WHITE)
      DrawLineinbitmap( hDC, fromrow  ,tocol-1,torow-1,tocol-1,GRAY )
      
   endif

   if HMG_LEN(ALLTRIM(ctitle)) > 0
      DrawTextInBitmap( hDC, fromrow + 10, iif(HMG_LEN(ALLTRIM(ctitle)) * 12 > (tocol - fromcol),fromcol,int(((tocol - fromcol) - (HMG_LEN(ALLTRIM(ctitle)) * 12))/2) + fromcol), ALLTRIM(ctitle), 'Arial', 12, {0,0,255} )
      fromrow := fromrow + 40
   endif   

   if lsleg
      if HMG_LEN(aname) * 20 > (torow - fromrow)
         msginfo("No space for showing legends")
      else
         torow := torow - (HMG_LEN(aname) * 20)
      endif
   endif

   drawrectinbitmap( hDC, fromrow + 10, fromcol + 10, torow - 10, tocol - 10, { 255, 255, 255 } )

   if l3d
      torow := torow - depth
   endif

   fromcol := fromcol + 25
   tocol := tocol - 25
   torow := torow - 25
   fromrow := fromrow + 25


   topleftrow := fromrow
   topleftcol := fromcol
   toprightrow := fromrow
   toprightcol := tocol
   bottomrightrow := torow
   bottomrightcol := tocol
   bottomleftrow := torow
   bottomleftcol := fromcol
   middletoprow := fromrow
   middletopcol := fromcol + int(tocol - fromcol) / 2
   middleleftrow := fromrow + int(torow - fromrow) / 2
   middleleftcol := fromcol
   middlebottomrow := torow
   middlebottomcol := fromcol + int(tocol - fromcol) / 2
   middlerightrow := fromrow + int(torow - fromrow) / 2
   middlerightcol := tocol






   torow := torow + 1
   tocol := tocol + 1

   for i := 1 to HMG_LEN(series)
      sum := sum + series[i]
   next i
   for i := 1 to HMG_LEN(series)
      aadd(degrees,round(series[i]/sum * 360,0))
   next i
   sum := 0
   for i := 1 to HMG_LEN(degrees)
      sum := sum + degrees[i]
   next i
   if sum <> 360
      degrees[HMG_LEN(degrees)] := degrees[HMG_LEN(degrees)] + (360 - sum)
   endif

   sum := 0
   for i := 1 to HMG_LEN(degrees)
      sum := sum + degrees[i]
      aadd(cumulative,sum)
   next i

   previos_cumulative := -1

   fromradialrow := middlerightrow
   fromradialcol := middlerightcol
   for i := 1 to HMG_LEN(cumulative)

      if cumulative[i] == previos_cumulative
         loop
      endif

      previos_cumulative := cumulative[i]

      shadowcolor := {iif(colors[i,1] > 50,colors[i,1] - 50,0),iif(colors[i,2] > 50,colors[i,2] - 50,0),iif(colors[i,3] > 50,colors[i,3] - 50,0)}

      do case
         case cumulative[i] <= 45
            toradialcol := middlerightcol
            toradialrow := middlerightrow - round(cumulative[i] / 45 * (middlerightrow - toprightrow),0)
            drawpieinbitmap(hDC,fromrow,fromcol,torow,tocol,fromradialrow,fromradialcol,toradialrow,toradialcol,,,colors[i])
            fromradialrow := toradialrow
            fromradialcol := toradialcol
         case cumulative[i] <= 90 .and. cumulative[i] > 45
            toradialrow := toprightrow
            toradialcol := toprightcol - round((cumulative[i] - 45) / 45 * (toprightcol - middletopcol),0)
            drawpieinbitmap(hDC,fromrow,fromcol,torow,tocol,fromradialrow,fromradialcol,toradialrow,toradialcol,,,colors[i])
            fromradialrow := toradialrow
            fromradialcol := toradialcol
         case cumulative[i] <= 135 .and. cumulative[i] > 90          
            toradialrow := topleftrow
            toradialcol := middletopcol - round((cumulative[i] - 90) / 45 * (middletopcol - topleftcol),0)
            drawpieinbitmap(hDC,fromrow,fromcol,torow,tocol,fromradialrow,fromradialcol,toradialrow,toradialcol,,,colors[i])
            fromradialrow := toradialrow
            fromradialcol := toradialcol
         case cumulative[i] <= 180 .and. cumulative[i] > 135          
            toradialcol := topleftcol
            toradialrow := topleftrow + round((cumulative[i] - 135) / 45 * (middleleftrow - topleftrow),0)
            drawpieinbitmap(hDC,fromrow,fromcol,torow,tocol,fromradialrow,fromradialcol,toradialrow,toradialcol,,,colors[i])
            fromradialrow := toradialrow
            fromradialcol := toradialcol
         case cumulative[i] <= 225 .and. cumulative[i] > 180          
            toradialcol := topleftcol
            toradialrow := middleleftrow + round((cumulative[i] - 180) / 45 * (bottomleftrow - middleleftrow),0)
            if l3d
               for j := 1 to depth
                  drawarcinBitMap(hDC,fromrow + j,fromcol,torow+j,tocol,fromradialrow+j,fromradialcol,toradialrow+j,toradialcol,shadowcolor)
               next j
            endif   
            drawpieinbitmap(hDC,fromrow,fromcol,torow,tocol,fromradialrow,fromradialcol,toradialrow,toradialcol,,,colors[i])
            fromradialrow := toradialrow
            fromradialcol := toradialcol
         case cumulative[i] <= 270 .and. cumulative[i] > 225          
            toradialrow := bottomleftrow
            toradialcol := bottomleftcol + round((cumulative[i] - 225) / 45 * (middlebottomcol - bottomleftcol),0)
            if l3d
               for j := 1 to depth
                  drawarcinbitmap(hDC,fromrow + j,fromcol,torow+j,tocol,fromradialrow+j,fromradialcol,toradialrow+j,toradialcol,shadowcolor)
               next j
            endif   
            drawpieinbitmap(hDC,fromrow,fromcol,torow,tocol,fromradialrow,fromradialcol,toradialrow,toradialcol,,,colors[i])
            fromradialrow := toradialrow
            fromradialcol := toradialcol
         case cumulative[i] <= 315 .and. cumulative[i] > 270          
            toradialrow := bottomleftrow
            toradialcol := middlebottomcol + round((cumulative[i] - 270) / 45 * (bottomrightcol - middlebottomcol),0)
            if l3d
               for j := 1 to depth
                  drawarcinBitMap(hDC,fromrow + j,fromcol,torow+j,tocol,fromradialrow+j,fromradialcol,toradialrow+j,toradialcol,shadowcolor)
               next j
            endif   
            drawpieinbitmap(hDC,fromrow,fromcol,torow,tocol,fromradialrow,fromradialcol,toradialrow,toradialcol,,,colors[i])
            fromradialrow := toradialrow
            fromradialcol := toradialcol
         case cumulative[i] <= 360 .and. cumulative[i] > 315
            toradialcol := bottomrightcol
            toradialrow := bottomrightrow - round((cumulative[i] - 315) / 45 * (bottomrightrow - middlerightrow),0)
            if l3d
               for j := 1 to depth
                  drawarcinBitMap(hDC,fromrow + j,fromcol,torow+j,tocol,fromradialrow+j,fromradialcol,toradialrow+j,toradialcol,shadowcolor)
               next j
            endif
            drawpieinbitmap(hDC,fromrow,fromcol,torow,tocol,fromradialrow,fromradialcol,toradialrow,toradialcol,,,colors[i])
            fromradialrow := toradialrow
            fromradialcol := toradialcol
         endcase
      if l3d            
         drawlineinbitmap(hDC, middleleftrow, middleleftcol, middleleftrow+depth, middleleftcol, { 0, 0, 0 } )
         drawlineinbitmap(hDC, middlerightrow, middlerightcol, middlerightrow+depth, middlerightcol, { 0, 0, 0 } )
         drawarcinBitMap(hDC,fromrow + depth,fromcol,torow + depth,tocol,middleleftrow+depth,middleleftcol,middlerightrow+depth,middlerightcol )
      endif
   next i
   if lsleg
      fromrow := torow + 20 + iif(l3d,depth,0)
      for i := 1 to HMG_LEN(aname)
         drawrectinbitmap(hDC, fromrow, fromcol, fromrow + 15, fromcol + 15, colors[ i ] )
         drawtextinbitmap( hDC, fromrow, fromcol + 20, aname[i]+iif(lxval," - "+ALLTRIM(STR(series[i],19,2))+" ("+ALLTRIM(STR(degrees[i] / 360 * 100,6,2))+" %)",""), 'Arial', 8, colors[i] )
         fromrow := fromrow + 20
      next i
   endif   
   BT_BitmapSaveFile(hBitmap, cImageFileName )
   BT_DeleteDC( BTstruct )
   BT_BitmapRelease( hBitmap )
return nil

function drawarcinBitMap(hDC,row,col,row1,col1,rowr,colr,rowr1,colr1,penrgb,penwidth)
   if valtype(penrgb) == "U"
      penrgb = {0,0,0}
   endif
   if valtype(penwidth) == "U"
      penwidth = 1
   endif
   arcdrawbitmap( hDC ,row,col,row1,col1,rowr,colr,rowr1,colr1,penrgb,penwidth)

return nil

function drawpieinbitmap(hDC,row,col,row1,col1,rowr,colr,rowr1,colr1,penrgb,penwidth,fillrgb)

   if valtype(penrgb) == "U"
      penrgb = {0,0,0}
   endif
   if valtype(penwidth) == "U"
      penwidth = 1
   endif
   if valtype(fillrgb) == "U"
      fillrgb := {255,255,255}
      fill := .f.
   else
      fill := .t.   
   endif
   piedrawbitmap( hDC,row,col,row1,col1,rowr,colr,rowr1,colr1,penrgb,penwidth,fillrgb,fill)

return nil

function drawpolygoninbitmap( hDC, apoints, penrgb, penwidth, fillrgb )
   local xarr := {}
   local yarr := {}
   local x := 0
   if valtype(penrgb) == "U"
      penrgb = {0,0,0}
   endif
   if valtype(penwidth) == "U"
      penwidth = 1
   endif
   if valtype(fillrgb) == "U"
      fillrgb := {255,255,255}
      fill := .f.
   else
      fill := .t.   
   endif
   for x := 1 to HMG_LEN(apoints)
       aadd(xarr,apoints[x,2])
       aadd(yarr,apoints[x,1])
   next x
   polygondrawbitmap( hDC, xarr, yarr, penrgb, penwidth, fillrgb, fill )
return nil

STATIC FUNCTION RGB2HSL( nR, nG, nB )
   LOCAL nMax, nMin
   LOCAL nH, nS, nL

   IF nR < 0
      nR := Abs( nR )
      nG := GetGreen( nR )
      nB := GetBlue( nR )
      nR := GetRed( nR )
   ENDIF

   nR := nR / 255
   nG := nG / 255
   nB := nB / 255
   nMax := Max( nR, Max( nG, nB ) )
   nMin := Min( nR, Min( nG, nB ) )
   nL := ( nMax + nMin ) / 2

   IF nMax = nMin
      nH := 0
      nS := 0
   ELSE
      IF nL < 0.5
         nS := ( nMax - nMin ) / ( nMax + nMin )
      ELSE
         nS := ( nMax - nMin ) / ( 2.0 - nMax - nMin )
      ENDIF
      DO CASE
         CASE nR = nMax
            nH := ( nG - nB ) / ( nMax - nMin )
         CASE nG = nMax
            nH := 2.0 + ( nB - nR ) / ( nMax - nMin )
         CASE nB = nMax
            nH := 4.0 + ( nR - nG ) / ( nMax - nMin )
      ENDCASE
   ENDIF

   nH := Int( (nH * 239) / 6 )
   IF nH < 0 ; nH += 240 ; ENDIF
   nS := Int( nS * 239 )
   nL := Int( nL * 239 )

RETURN { nH, nS, nL }


STATIC FUNCTION HSL2RGB( nH, nS, nL )
   LOCAL nFor
   LOCAL nR, nG, nB
   LOCAL nTmp1, nTmp2, aTmp3 := { 0, 0, 0 }

   nH /= 239
   nS /= 239
   nL /= 239
   IF nS == 0
      nR := nL
      nG := nL
      nB := nL
   ELSE
      IF nL < 0.5
         nTmp2 := nL * ( 1 + nS )
      ELSE
         nTmp2 := nL + nS - ( nL * nS )
      ENDIF
      nTmp1 := 2 * nL - nTmp2
      aTmp3[1] := nH + 1 / 3
      aTmp3[2] := nH
      aTmp3[3] := nH - 1 / 3
      FOR nFor := 1 TO 3
         IF aTmp3[nFor] < 0
            aTmp3[nFor] += 1
         ENDIF
         IF aTmp3[nFor] > 1
            aTmp3[nFor] -= 1
         ENDIF
         IF 6 * aTmp3[nFor] < 1
            aTmp3[nFor] := nTmp1 + ( nTmp2 - nTmp1 ) * 6 * aTmp3[nFor]
         ELSE
            IF 2 * aTmp3[nFor] < 1
               aTmp3[nFor] := nTmp2
            ELSE
               IF 3 * aTmp3[nFor] < 2
                  aTmp3[nFor] := nTmp1 + ( nTmp2 - nTmp1 ) * ( ( 2 / 3 ) - aTmp3[nFor] ) * 6
               ELSE
                  aTmp3[nFor] := nTmp1
               ENDIF
            ENDIF
         ENDIF
      NEXT nFor
      nR := aTmp3[1]
      nG := aTmp3[2]
      nB := aTmp3[3]
   ENDIF

RETURN { Int( nR * 255 ), Int( nG * 255 ), Int( nB * 255 ) }


STATIC PROC DrawBoxinBitmap( hDC, nY, nX, nHigh, nWidth, l3D, nDeep )

   // Set Border
   DrawLineinbitmap( hDC, nX, nY        , nX-nHigh+nDeep    , nY       , BLACK )  // LEFT
   DrawLineinbitmap( hDC, nX, nY+nWidth , nX-nHigh+nDeep    , nY+nWidth, BLACK )  // RIGHT
   DrawLineinbitmap( hDC, nX-nHigh+nDeep, nY, nX-nHigh+nDeep, nY+nWidth, BLACK )  // Top
   DrawLineinbitmap( hDC, nX, nY, nX, nY+nWidth, BLACK )                          // Bottom
   IF l3D
      // Set shadow
      DrawLineinbitmap( hDC, nX-nHigh+nDeep, nY+nWidth, nX-nHigh, nY+nDeep+nWidth, BLACK )
      DrawLineinbitmap( hDC, nX, nY+nWidth, nX-nDeep, nY+nWidth+nDeep, BLACK )
      IF nHigh > 0
         DrawLineinbitmap( hDC, nX-nDeep, nY+nWidth+nDeep, nX-nHigh, nY+nWidth+nDeep, BLACK )
         DrawLineinbitmap( hDC, nX-nHigh, nY+nDeep, nX-nHigh , nY+nWidth+nDeep, BLACK )
         DrawLineinbitmap( hDC, nX-nHigh+nDeep, nY, nX-nHigh, nY+nDeep, BLACK )
      ELSE
         DrawLineinbitmap( hDC, nX-nDeep, nY+nWidth+nDeep, nX-nHigh+1, nY+nWidth+nDeep, BLACK )
         DrawLineinbitmap( hDC, nX, nY, nX-nDeep, nY+nDeep, BLACK )
      ENDIF
   ENDIF

RETURN



#pragma BEGINDUMP

#include "SET_COMPILE_HMG_UNICODE.ch"
#include "HMG_UNICODE.h"


#include <windows.h>
#include <commctrl.h>
#include "hbapi.h"
#include <wingdi.h>
#include <winuser.h>

HB_FUNC ( PIEDRAWBITMAP )
{
   HDC hdc1;
   HGDIOBJ hgdiobj1,hgdiobj2;
   HPEN hpen;
   HBRUSH hbrush;
   hdc1 = (HDC) HMG_parnl (1);
   hpen = CreatePen( (int) PS_SOLID, (int) hb_parni(11), (COLORREF) RGB( (int) hb_parvni(10,1), (int) hb_parvni(10,2), (int) hb_parvni(10,3) ) );
   hgdiobj1 = SelectObject((HDC) hdc1, hpen);
   if (hb_parl(13))
   {
      hbrush = CreateSolidBrush((COLORREF) RGB((int) hb_parvni(12,1),(int) hb_parvni(12,2),(int) hb_parvni(12,3)));    
      hgdiobj2 = SelectObject((HDC) hdc1, hbrush);
   }   
   else
   {
      hbrush = GetSysColorBrush((int) COLOR_WINDOW);    
      hgdiobj2 = SelectObject((HDC) hdc1, hbrush);
   }      
   Pie((HDC) hdc1,(int) hb_parni(3),(int) hb_parni(2),(int) hb_parni(5),(int) hb_parni(4),(int) hb_parni(7),(int) hb_parni(6),(int) hb_parni(9),(int) hb_parni(8));
   SelectObject((HDC) hdc1,(HGDIOBJ) hgdiobj1);
   SelectObject((HDC) hdc1,(HGDIOBJ) hgdiobj2);
   DeleteObject( hpen );
   DeleteObject( hbrush );
}
   
HB_FUNC( POLYGONDRAWBITMAP )
{
   HDC hdc1;
   HGDIOBJ hgdiobj1,hgdiobj2;
   HPEN hpen;
   HBRUSH hbrush;
   POINT apoints[1024];
   int number=hb_parinfa(2,0);
   int i;
   hdc1 = (HDC) HMG_parnl (1);
   hpen = CreatePen( (int) PS_SOLID, (int) hb_parni(5), (COLORREF) RGB( (int) hb_parvni(4,1), (int) hb_parvni(4,2), (int) hb_parvni(4,3) ) );
   hgdiobj1 = SelectObject((HDC) hdc1, hpen);
   if (hb_parl(7))
   {
      hbrush = CreateSolidBrush((COLORREF) RGB((int) hb_parvni(6,1),(int) hb_parvni(6,2),(int) hb_parvni(6,3)));    
      hgdiobj2 = SelectObject((HDC) hdc1, hbrush);
   }   
   else
   {
      hbrush = GetSysColorBrush((int) COLOR_WINDOW);    
      hgdiobj2 = SelectObject((HDC) hdc1, hbrush);
   }      
   for(i = 0; i <= number-1; i++)
   {
   apoints[i].x=hb_parvni(2,i+1);
   apoints[i].y=hb_parvni(3,i+1);
   }
   Polygon((HDC) hdc1,apoints,number);
   SelectObject((HDC) hdc1,(HGDIOBJ) hgdiobj1);
   SelectObject((HDC) hdc1,(HGDIOBJ) hgdiobj2);
   DeleteObject( hpen );
   DeleteObject( hbrush );
}

HB_FUNC ( ARCDRAWBITMAP )
{
   HDC hdc1;
   HGDIOBJ hgdiobj1;
   HPEN hpen;
   hdc1 = (HDC) HMG_parnl (1);
   hpen = CreatePen( PS_SOLID, (int) hb_parni(11), (COLORREF) RGB( (int) hb_parvni(10,1), (int) hb_parvni(10,2), (int) hb_parvni(10,3) ) );
   hgdiobj1 = SelectObject( hdc1, hpen );
   Arc( hdc1,(int) hb_parni(3),(int) hb_parni(2),(int) hb_parni(5),(int) hb_parni(4),(int) hb_parni(7),(int) hb_parni(6),(int) hb_parni(9),(int) hb_parni(8));
   SelectObject( hdc1, hgdiobj1);
   DeleteObject( hpen );
}

HB_FUNC( POLYBEZIERDRAWBITMAP )
{
   HDC hdc1;
   HGDIOBJ hgdiobj1;
   HPEN hpen;
   POINT apoints[1024];
   DWORD number=(DWORD) hb_parinfa(2,0);
   DWORD i;
   hdc1 = (HDC) HMG_parnl (1);
   hpen = CreatePen( (int) PS_SOLID, (int) hb_parni(5), (COLORREF) RGB( (int) hb_parvni(4,1), (int) hb_parvni(4,2), (int) hb_parvni(4,3) ) );
   hgdiobj1 = SelectObject((HDC) hdc1, hpen);
   for(i = 0; i <= number-1; i++)
   {
   apoints[i].x=hb_parvni(2,i+1);
   apoints[i].y=hb_parvni(3,i+1);
   }
   PolyBezier((HDC) hdc1,apoints,number);
   SelectObject((HDC) hdc1,(HGDIOBJ) hgdiobj1);
   DeleteObject( hpen );
}   

#pragma ENDDUMP
East or West HMG is the Best.
South or North HMG is worth.
...the possibilities are endless.
User avatar
serge_girard
Posts: 3161
Joined: Sun Nov 25, 2012 2:44 pm
DBs Used: 1 MySQL - MariaDB
2 DBF
Location: Belgium
Contact:

Re: HMG Graph based on Bas Taurus

Post by serge_girard »

Thanks Rathi (and Andy + others) !

Serge
There's nothing you can do that can't be done...
User avatar
esgici
Posts: 4543
Joined: Wed Jul 30, 2008 9:17 pm
DBs Used: DBF
Location: iskenderun / Turkiye
Contact:

Re: HMG Graph based on Bas Taurus

Post by esgici »

serge_girard wrote:Thanks Rathi (and Andy + others) !

Serge
+1
Viva INTERNATIONAL HMG :D
User avatar
bpd2000
Posts: 1207
Joined: Sat Sep 10, 2011 4:07 am
Location: India

Re: HMG Graph based on Bas Taurus

Post by bpd2000 »

Excellent contribution
Thank you Rathi
BPD
Convert Dream into Reality through HMG
User avatar
andyglezl
Posts: 1461
Joined: Fri Oct 26, 2012 7:58 pm
Location: Guadalajara Jalisco, MX
Contact:

Re: HMG Graph based on Bas Taurus

Post by andyglezl »

Excelente Rathi, sigamos creciendo, viva HMG !.
----------------------------------------------------------
Excellent Rathi, we grow, live HMG!.
Andrés González López
Desde Guadalajara, Jalisco. México.
User avatar
andyglezl
Posts: 1461
Joined: Fri Oct 26, 2012 7:58 pm
Location: Guadalajara Jalisco, MX
Contact:

Re: HMG Graph based on Bas Taurus

Post by andyglezl »

Cambiando la linea que dice:
BT_BitmapSaveFile(hBitmap, cImageFileName )
por:
BT_BitmapSaveFile(hBitmap, cImageFileName, BT_FILEFORMAT_JPG )

lo guardamos como .jpg
-------------------------------------------------------------------------------------------
Changing the line that says:
BT_BitmapSaveFile (hBitmap, cImageFileName)
by:
BT_BitmapSaveFile (hBitmap, cImageFileName, BT_FILEFORMAT_JPG)

we save as .jpg
bmp2jpg.jpg
bmp2jpg.jpg (58.68 KiB) Viewed 12249 times
Andrés González López
Desde Guadalajara, Jalisco. México.
User avatar
Rathinagiri
Posts: 5471
Joined: Tue Jul 29, 2008 6:30 pm
DBs Used: MariaDB, SQLite, SQLCipher and MySQL
Location: Sivakasi, India
Contact:

Re: HMG Graph based on Bas Taurus

Post by Rathinagiri »

Thank you Andy. Sometimes, compression spoils the image quality. We can use jpg as default.
East or West HMG is the Best.
South or North HMG is worth.
...the possibilities are endless.
User avatar
andyglezl
Posts: 1461
Joined: Fri Oct 26, 2012 7:58 pm
Location: Guadalajara Jalisco, MX
Contact:

Re: HMG Graph based on Bas Taurus

Post by andyglezl »

Hola Rathinagiri

Cual linea se modifica, para las lineas que separan los titulos de meses,
creo que deberian de estar donde pongo la linea roja...
--------------------------------------------------------------------------------------------------
Hello Rathinagiri

Which line is changed to the lines that separate the titles of months,
I think they should be put where the red line ...
graph.jpg
graph.jpg (124.29 KiB) Viewed 12229 times
Andrés González López
Desde Guadalajara, Jalisco. México.
User avatar
andyglezl
Posts: 1461
Joined: Fri Oct 26, 2012 7:58 pm
Location: Guadalajara Jalisco, MX
Contact:

Re: HMG Graph based on Bas Taurus

Post by andyglezl »

Fabuloso Rathinagiri !

Solo me falta ver como ajusto mas a la izquierda las etiquetas de valores
para que queden sobre la barra correspondiente.
--------------------------------------------------------------------------------------
Fabulous Rathinagiri !

I only need to see how I adjust the leftmost value labels
so that they are on the corresponding bar.
graph.jpg
graph.jpg (190.54 KiB) Viewed 12218 times
Andrés González López
Desde Guadalajara, Jalisco. México.
User avatar
srvet_claudio
Posts: 2193
Joined: Thu Feb 25, 2010 8:43 pm
Location: Uruguay
Contact:

Re: HMG Graph based on Bas Taurus

Post by srvet_claudio »

Rathinagiri wrote:Hi friends,

Now, we can save/show HMG Graphs (BARS/LINES/POINTS/PIE with 3D also) in bitmap format. I have reused the h_graph.prg and c_graph.c code according to Bas Taurus. I think this can be included ( after rigorous testing ) in our HMG Code.

Claudio, this code contains code for drawing polygons, Polybeziers, arcs and pie. I think you can use them in the next version of Bas Taurus.
Clipboard01.jpg

Code: Select all

#include <hmg.ch>

Function Main


   define window graph at 0, 0 width 1000 height 700 main 
      define label selecttype
         row 10
         col 10
         width 150
         value 'Select Graph Type'
      end label
      define combobox graphtype
         row 10
         col 160
         width 100
         items { 'Bar', 'Lines', 'Points', 'Pie' }
         onchange drawgraph()
      end combobox   
      define checkbox enable3d
         row 10
         col 280
         width 100
         caption 'Enable 3D'
         onchange drawgraph()
      end checkbox   
      define image grapharea
         row 50
         col 50
         width 600
         height 600
      end image
   end window
   graph.graphtype.value := 1
   graph.center
   graph.activate
Return


function drawgraph
   local cImage := 'graph.bmp'
   local nImageWidth := 600
   local nImageHeight := 600
   local cTitle := 'Sample Graph'
   local aYValues := {"Jan","Feb","Mar","Apr","May"}
   local aData := { {14280,20420,12870,25347, 7640},;
           { 8350,10315,15870, 5347,12340},;
           {12345, -8945,10560,15600,17610} }
   local nBarDepth := 15
   local nBarWidth := 15   
   local nHValues := 5
   local l3D := graph.enable3D.value
   local lGrid := .t.
   local lXGrid := .t.
   local lYGrid := .t.
   local lXVal := .t.
   local lYVal := .t.
   local nGraphType := graph.graphtype.value
   local lViewVal := .t.
   local lLegends := .t.
   local cPicture := '99,999.99'
   local aSeries := {"Serie 1","Serie 2","Serie 3"}
   local aColors := { {128,128,255}, {255,102, 10}, {55,201, 48} }
   local lNoBorder := .f.
   local nLegendWidth := 50
   if graph.graphtype.value == 0
      return nil
   endif
   if graph.graphtype.value == 4 // pie
      drawpiegraphinBitMap( cImage, nImageWidth, nImageHeight, {1500,1800,200,500,800}, {"Product 1","Product 2","Product 3","Product 4","Product 5"}, {{255,0,0},{0,0,255},{255,255,0},{0,255,0},{255,128,64},{128,0,128}}, "Sales", 25, l3D, lxval, lLegends, lnoborder )   
   else      
      graphsave( cImage, nImageWidth, nImageHeight, aData,  cTitle, aYValues, nBarDepth, nBarWidth, nil, nHValues, l3d, lGrid, lXGrid, lYGrid, ;
               lXVal, lYVal, lLegends, aSeries, aColors, nGraphType, lViewVal, cPicture, nLegendWidth ,lNoBorder ) 
   endif               
   graph.grapharea.picture := 'graph.bmp'
   return nil
   
function graphsave( cImageFileName, nWidth, nHeight, aData, cTitle, aYVals, nBarD, nWideB, nSep, nXRanges, ;
	              l3D, lGrid, lxGrid, lyGrid, lxVal, lyVal, lLegends, aSeries, aColors, nType, lViewVal, cPicture , nLegendWindth , lNoborder )
                 
   LOCAL nI, nJ, nPos, nMax, nMin, nMaxBar, nDeep
   LOCAL nRange, nResH, nResV,  nWide, aPoint, cName
   LOCAL nXMax, nXMin, nHigh, nRel, nZero, nRPos, nRNeg
   local hBitMap, hDC, BTStruct
   local nTop := 0
   local nLeft := 0
   local nBottom := nHeight
   local nRight := nWidth

	DEFAULT cTitle   := ""
	DEFAULT nSep     := 0
	DEFAULT cPicture := "999,999.99"
	DEFAULT nLegendWindth := 50
   private nPenWidth := 1

	If ( HMG_LEN (aSeries) != HMG_LEN ( aData ) ) .or. ;
		( HMG_LEN ( aSeries ) != HMG_LEN ( aColors ) ) 
		MsgHMGError("DRAW GRAPH: 'Series' / 'SerieNames' / 'Colors' arrays size mismatch. Program terminated", "HMG Error" )
	EndIf

   hBitMap := BT_BitmapCreateNew ( nWidth, nHeight, { 255, 255, 255 } )
   hDC := BT_CreateDC( hBitMap, BT_HDC_BITMAP, @BTStruct )

   IF lGrid
      lxGrid := lyGrid := .T.
   ENDIF
   
   IF nBottom <> NIL .AND. nRight <> NIL
      nHeight := nBottom - nTop / 2
      nWidth  := nRight - nLeft / 2
      nBottom -= IF( lyVal, 42, 32)
      nRight  -= IF( lLegends, 32 + nLegendWindth , 32 )
   ENDIF
   nTop    += 1 + IF( Empty( cTitle ), 30, 44 )             // Top gap
   nLeft   += 1 + IF( lxVal, 80 + nBarD, 30 + nBarD )     // LEFT
   DEFAULT nBottom := nHeight - 2 - IF( lyVal, 40, 30 )    // Bottom
   DEFAULT nRight  := nWidth - 2 - IF( lLegends, 30 + nLegendWindth , 30 ) // RIGHT

   l3D     := IF( nType == POINTS, .F., l3D )
   nDeep   := IF( l3D, nBarD, 1 )
   nMaxBar := nBottom - nTop - nDeep - 5
   nResH   := nResV := 1
   nWide   := ( nRight - nLeft )* nResH / ( nMax( aData ) + 1 ) * nResH

   // Graph area
   //
   IF ! lNoborder
	   DrawWindowBoxInBitMap( hDC, Max( 1, nTop - 44 ), Max( 1, nLeft - 80 - nBarD ), nHeight - 1, nWidth - 1 )
   ENDIF	

   // Back area
   //
   IF l3D
      drawrectinbitmap( hDC, nTop+1, nLeft, nBottom - nDeep, nRight, { 255, 255, 255 } )
   ELSE
      drawrectinbitmap( hDC, nTop-5, nLeft, nBottom, nRight, { 255, 255, 255 } )
   ENDIF

   IF l3D
      // Bottom area
      FOR nI := 1 TO nDeep+1
          DrawLineinbitmap( hDC, nBottom-nI, nLeft-nDeep+nI, nBottom-nI, nRight-nDeep+nI, { 255, 255, 255 } )
      NEXT nI

      // Lateral
      FOR nI := 1 TO nDeep
          DrawLineinbitmap( hDC, nTop+nI, nLeft-nI, nBottom-nDeep+nI, nLeft-nI, {192, 192, 192} )
      NEXT nI

      // Graph borders
      FOR nI := 1 TO nDeep+1
          DrawLineinbitmap( hDC, nBottom-nI     ,nLeft-nDeep+nI-1 ,nBottom-nI     ,nLeft-nDeep+nI  ,GRAY )
          DrawLineinbitmap( hDC, nBottom-nI     ,nRight-nDeep+nI-1,nBottom-nI     ,nRight-nDeep+nI ,BLACK )
          DrawLineinbitmap( hDC, nTop+nDeep-nI+1,nLeft-nDeep+nI-1 ,nTop+nDeep-nI+1,nLeft-nDeep+nI  ,BLACK )
          DrawLineinbitmap( hDC, nTop+nDeep-nI+1,nLeft-nDeep+nI-3 ,nTop+nDeep-nI+1,nLeft-nDeep+nI-2,BLACK )
      NEXT nI

      FOR nI=1 TO nDeep+2
          DrawLineinbitmap( hDC, nTop+nDeep-nI+1,nLeft-nDeep+nI-3,nTop+nDeep-nI+1,nLeft-nDeep+nI-2 ,BLACK )
          DrawLineinbitmap( hDC, nBottom+ 2-nI+1,nRight-nDeep+nI ,nBottom+ 2-nI+1,nRight-nDeep+nI-2,BLACK )
      NEXT nI

      DrawLineinbitmap( hDC, nTop         ,nLeft        ,nTop           ,nRight       ,BLACK )
      DrawLineinbitmap( hDC, nTop- 2      ,nLeft        ,nTop- 2        ,nRight+ 2    ,BLACK )
      DrawLineinbitmap( hDC, nTop         ,nLeft        ,nBottom-nDeep  ,nLeft        ,GRAY  )
      DrawLineinbitmap( hDC, nTop+nDeep   ,nLeft-nDeep  ,nBottom        ,nLeft-nDeep  ,BLACK )
      DrawLineinbitmap( hDC, nTop+nDeep   ,nLeft-nDeep-2,nBottom+ 2     ,nLeft-nDeep-2,BLACK )
      DrawLineinbitmap( hDC, nTop         ,nRight       ,nBottom-nDeep  ,nRight       ,BLACK )
      DrawLineinbitmap( hDC, nTop- 2      ,nRight+ 2    ,nBottom-nDeep+2,nRight+ 2    ,BLACK )
      DrawLineinbitmap( hDC, nBottom-nDeep,nLeft        ,nBottom-nDeep  ,nRight       ,GRAY  )
      DrawLineinbitmap( hDC, nBottom      ,nLeft-nDeep  ,nBottom        ,nRight-nDeep ,BLACK )
      DrawLineinbitmap( hDC, nBottom+ 2   ,nLeft-nDeep-2,nBottom+ 2     ,nRight-nDeep ,BLACK )
   ENDIF


   // Graph info
   //

   IF !Empty(cTitle)
      DrawTextInBitmap( hDC, nTop - 30 * nResV, nLeft, cTitle, 'Arial', 12, RED, 2 )
   ENDIF


   // Legends
   //
   IF lLegends
      nPos := nTop
      FOR nI := 1 TO HMG_LEN( aSeries )
         DrawBarinbitmap( hDC, nRight+(8*nResH), nPos+(9*nResV), 8*nResH, 7*nResV, l3D, 1, aColors[nI] )
         DrawTextInBitmap( hDC, nPos, nRight+(20*nResH), aSeries[nI], 'Arial', 8, BLACK, 0 )
         nPos += 18*nResV
      NEXT nI
   ENDIF

   // Max, Min values
   nMax := 0
   FOR nJ := 1 TO HMG_LEN(aSeries)
      FOR nI :=1 TO HMG_LEN(aData[nJ])
         nMax := Max( aData[nJ][nI], nMax )
      NEXT nI
   NEXT nJ
   nMin := 0
   FOR nJ := 1 TO HMG_LEN(aSeries)
      FOR nI :=1 TO HMG_LEN(aData[nJ])
         nMin := Min( aData[nJ][nI], nMin )
      NEXT nI
   NEXT nJ

   nXMax := IF( nMax > 0, DetMaxVal( nMax ), 0 )
   nXMin := IF( nMin < 0, DetMaxVal( nMin ), 0 )
   nHigh := nXMax + nXMin
   nMax  := Max( nXMax, nXMin )
   
   nRel  := ( nMaxBar / nHigh )
   nMaxBar := nMax * nRel



   nZero := nTop + (nMax*nRel) + nDeep + 5    // Zero pos
   IF l3D
      FOR nI := 1 TO nDeep+1
          DrawLineinbitmap( hDC, nZero-nI+1, nLeft-nDeep+nI   , nZero-nI+1, nRight-nDeep+nI, {192, 192, 192} )
      NEXT nI
      FOR nI := 1 TO nDeep+1
          DrawLineinbitmap( hDC, nZero-nI+1, nLeft-nDeep+nI-1 , nZero-nI+1, nLeft -nDeep+nI, GRAY )
          DrawLineinbitmap( hDC, nZero-nI+1, nRight-nDeep+nI-1, nZero-nI+1, nRight-nDeep+nI, BLACK )
      NEXT nI
      DrawLineinbitmap( hDC, nZero-nDeep, nLeft, nZero-nDeep, nRight, GRAY )
   ENDIF

   aPoint := Array( HMG_LEN( aSeries ), HMG_LEN( aData[1] ), 2 )
   nRange := nMax / nXRanges

   // xLabels
   nRPos := nRNeg := nZero - nDeep
   FOR nI := 0 TO nXRanges
      IF lxVal
         IF nRange*nI <= nXMax
            DrawTextInBitmap( hDC, nRPos, nLeft-nDeep-70, Transform(nRange*nI, cPicture), 'Arial', 8, BLUE )
         ENDIF
         IF nRange*(-nI) >= nXMin*(-1)
            DrawTextInBitmap( hDC, nRNeg, nLeft-nDeep-70, Transform(nRange*-nI, cPicture), 'Arial', 8, BLUE )
         ENDIF
      ENDIF

      IF lxGrid
         IF nRange*nI <= nXMax
            IF l3D
               FOR nJ := 0 TO nDeep + 1
                  DrawLineinbitmap( hDC, nRPos + nJ, nLeft - nJ - 1, nRPos + nJ, nLeft - nJ, BLACK )
               NEXT nJ
            ENDIF
            DrawLineinbitmap( hDC, nRPos, nLeft, nRPos, nRight, BLACK )
         ENDIF
         IF nRange*-nI >= nXMin*-1
            IF l3D
               FOR nJ := 0 TO nDeep + 1
                  DrawLineinbitmap( hDC, nRNeg + nJ, nLeft - nJ - 1, nRNeg + nJ, nLeft - nJ, BLACK )
               NEXT nJ
            ENDIF
            DrawLineinbitmap( hDC, nRNeg, nLeft, nRNeg, nRight, BLACK )
         ENDIF
      ENDIF
      nRPos -= ( nMaxBar / nXRanges )
      nRNeg += ( nMaxBar / nXRanges )
   NEXT nI

   IF lYGrid
      nPos:=IF(l3D, nTop, nTop-5 )
      nI  := nLeft + nWide
      FOR nJ := 1 TO nMax(aData)
         DrawlineinBitmap( hDC, nBottom-nDeep, nI, nPos, nI, {100,100,100} )
         DrawlineinBitmap( hDC, nBottom, nI-nDeep, nBottom-nDeep, nI, {100,100,100} )
         nI += nWide
      NEXT
   ENDIF

   DO WHILE .T.    // Bar adjust
      nPos = nLeft + ( nWide / 2 )
      nPos += ( nWide + nSep ) * ( HMG_LEN(aSeries) + 1 ) * HMG_LEN(aData[1])
      IF nPos > nRight
         nWide--
      ELSE
         EXIT
      ENDIF
   ENDDO

   nMin := nMax / nMaxBar

   nPos := nLeft + ( ( nWide + nSep ) / 2 )            // first point graph
   nRange := ( ( nWide + nSep ) * HMG_LEN(aSeries) ) / 2

   IF lyVal .AND. HMG_LEN( aYVals ) > 0                // Show yLabels
      nWideB  := ( nRight - nLeft ) / ( nMax(aData) + 1 )
      nI := nLeft + nWideB
      FOR nJ := 1 TO nMax(aData)
         cName := "yVal_Name_"+LTRIM(STR(nJ))
         DrawTextInBitmap( hDC, nBottom + 8, nI - nDeep - IF(l3D, 0, 8), aYVals[nJ], 'Arial', 8, BLUE )
         nI += nWideB
      NEXT
   ENDIF



   // Bars
   //
	
	IF nType == BARS
		if nMin <> 0
			nPos := nLeft + ( ( nWide + nSep ) / 2 )
			FOR nI=1 TO HMG_LEN(aData[1])
				FOR nJ=1 TO HMG_LEN(aSeries)
					DrawBarinbitmap( hDC, nPos, nZero, aData[nJ,nI] / nMin + nDeep, nWide, l3D, nDeep, aColors[nJ] )
					nPos += nWide+nSep
				NEXT nJ
				nPos += nWide+nSep
			NEXT nI
		endif
	ENDIF

   // Lines
   //
   IF nType == LINES
      if nMin <> 0
         nWideB  := ( nRight - nLeft ) / ( nMax(aData) + 1 )
         nPos := nLeft + nWideB
         FOR nI := 1 TO HMG_LEN(aData[1])
            FOR nJ=1 TO HMG_LEN(aSeries)
               IF !l3D
                  DrawPointinBitmap( hDC, nType, nPos, nZero, aData[nJ,nI] / nMin + nDeep, aColors[nJ] )
               ENDIF
               aPoint[nJ,nI,2] := nPos
               aPoint[nJ,nI,1] := nZero - ( aData[nJ,nI] / nMin + nDeep )
            NEXT nJ
            nPos += nWideB
         NEXT nI

         FOR nI := 1 TO HMG_LEN(aData[1])-1
            FOR nJ := 1 TO HMG_LEN(aSeries)
               IF l3D
                  drawpolygoninbitmap(hDC,{{aPoint[nJ,nI,1],aPoint[nJ,nI,2]},{aPoint[nJ,nI+1,1],aPoint[nJ,nI+1,2]}, ;
                              {aPoint[nJ,nI+1,1]-nDeep,aPoint[nJ,nI+1,2]+nDeep},{aPoint[nJ,nI,1]-nDeep,aPoint[nJ,nI,2]+nDeep}, ;
                              {aPoint[nJ,nI,1],aPoint[nJ,nI,2]}},,,aColors[nJ])
               ELSE
                  DrawLineinbitmap( hDC, aPoint[ nJ, nI, 1 ], aPoint[ nJ, nI, 2 ], aPoint[ nJ, nI+1, 1 ], aPoint[ nJ, nI + 1, 2 ], aColors[ nJ ] )
               ENDIF
            NEXT nJ
         NEXT nI

      endif
   ENDIF

   // Points
   //
   IF nType == POINTS
		if nMin <> 0
         nWideB := ( nRight - nLeft ) / ( nMax(aData) + 1 )
         nPos := nLeft + nWideB
         FOR nI := 1 TO HMG_LEN(aData[1])
            FOR nJ=1 TO HMG_LEN(aSeries)
               DrawPointinBitmap( hDC, nType, nPos, nZero, aData[nJ,nI] / nMin + nDeep, aColors[nJ] )
               aPoint[nJ,nI,2] := nPos
               aPoint[nJ,nI,1] := nZero - aData[nJ,nI] / nMin
            NEXT nJ
            nPos += nWideB
         NEXT nI
      ENDIF
   endif   

   IF lViewVal
      IF nType == BARS
         nPos := nLeft + nWide + ( (nWide+nSep) * ( HMG_LEN(aSeries) / 2 ) )
      ELSE
         nWideB := ( nRight - nLeft ) / ( nMax(aData) + 1 )
         nPos := nLeft + nWideB
      ENDIF
      FOR nI := 1 TO HMG_LEN(aData[1])
         FOR nJ := 1 TO HMG_LEN(aSeries)
            DrawTextInBitmap( hDC, nZero - ( aData[nJ,nI] / nMin + nDeep ), IF(nType == BARS, nPos - IF(l3D, 8, 10), nPos + 10), Transform(aData[nJ,nI], cPicture), 'Arial', 8 )
            nPos+=IF( nType == BARS, nWide + nSep, 0)
         NEXT nJ
         IF nType == BARS
            nPos += nWide + nSep
         ELSE
            nPos += nWideB
         ENDIF
      NEXT nI
   ENDIF

   IF l3D
      DrawLineinbitmap( hDC, nZero, nLeft-nDeep, nZero, nRight-nDeep, BLACK )
   ELSE
      IF nXMax<>0 .AND. nXMin<>0
         DrawLineinbitmap( hDC, nZero-1, nLeft-2, nZero-1, nRight, RED )
      ENDIF

   endif

   BT_BitmapSaveFile(hBitmap, cImageFileName )
   BT_DeleteDC( BTstruct )
   BT_BitmapRelease( hBitmap )

RETURN



function DrawWindowBoxInBitMap( hDC, row, col, rowr, colr )
   BT_DrawRectangle ( hDC, Row, Col, Colr - col, rowr - row, { 0, 0, 0 }, nPenWidth )
return nil
		

   

function drawrectinbitmap( hDC, row, col, row1, col1, aColor )

   BT_DrawFillRectangle (hDC, Row, Col, col1 - col, row1 - row, aColor, aColor, nPenWidth )
return nil   

function DrawLineinbitmap( hDC, Row1, Col1, Row2, Col2, aColor )
   BT_DrawLine ( hDC, Row1, Col1, Row2, Col2, aColor, nPenWidth )
return nil   

function DrawTextInBitmap( hDC, Row, Col, cText, cFontName, nFontSize, aColor, nAlign )
   default nAlign := 0
   do case
   case nAlign == 0
      BT_DrawText ( hDC, Row, Col, cText, cFontName, nFontSize, aColor, )
   case nAlign == 1
      BT_DrawText ( hDC, Row, Col, cText, cFontName, nFontSize, aColor, , BT_TEXT_RIGHT )
   case nAlign == 2
      BT_DrawText ( hDC, Row, Col, cText, cFontName, nFontSize, aColor, , BT_TEXT_CENTER )
   endcase   
return nil   

function DrawBarinbitmap( hDC, nY, nX, nHigh, nWidth, l3D, nDeep, aColor )
   LOCAL nI, nColTop, nShadow, nH := nHigh

   nColTop := ClrShadow( RGB(aColor[1],aColor[2],aColor[3]), 15 )
   nShadow := ClrShadow( nColTop, 15 )
   nColTop := {GetRed(nColTop),GetGreen(nColTop),GetBlue(nColTop)}
   nShadow := {GetRed(nShadow),GetGreen(nShadow),GetBlue(nShadow)}

   FOR nI=1 TO nWidth
      DrawLineinbitmap( hDC, nX, nY+nI, nX+nDeep-nHigh, nY+nI, aColor )  // front
   NEXT nI

   IF l3D
      // Lateral
      drawpolygoninBitmap( hDC,{{nX-1,nY+nWidth+1},{nX+nDeep-nHigh,nY+nWidth+1},;
                   {nX-nHigh+1,nY+nWidth+nDeep},{nX-nDeep,nY+nWidth+nDeep},;
                   {nX-1,nY+nWidth+1}},nShadow,,nShadow )
      // Superior
      nHigh   := Max( nHigh, nDeep )
      drawpolygoninBitmap( hDC,{{nX-nHigh+nDeep,nY+1},{nX-nHigh+nDeep,nY+nWidth+1},;
                   {nX-nHigh+1,nY+nWidth+nDeep},{nX-nHigh+1,nY+nDeep},;
                   {nX-nHigh+nDeep,nY+1}},nColTop,,nColTop )
      // Border
      DrawBoxinBitmap( hDC, nY, nX, nH, nWidth, l3D, nDeep )
   ENDIF

RETURN

STATIC FUNCTION ClrShadow( nColor, nFactor )
   LOCAL aHSL, aRGB

   aHSL := RGB2HSL( GetRed(nColor), GetGreen(nColor), GetBlue(nColor) )
   aHSL[3] -= nFactor
   aRGB := HSL2RGB( aHSL[1], aHSL[2], aHSL[3] )

RETURN RGB( aRGB[1], aRGB[2], aRGB[3] )


STATIC FUNCTION nMax(aData)
   LOCAL nI, nMax := 0

   FOR nI :=1 TO HMG_LEN( aData )
      nMax := Max( HMG_LEN(aData[nI]), nMax )
   NEXT nI

RETURN( nMax )


STATIC FUNCTION DetMaxVal(nNum)
   LOCAL nE, nMax, nMan, nVal, nOffset

   nE:=9
   nVal:=0
   nNum:=Abs(nNum)

   DO WHILE .T.

      nMax := 10**nE

      IF Int(nNum/nMax)>0

         nMan:=(nNum/nMax)-Int(nNum/nMax)
         nOffset:=1
         nOffset:=IF(nMan<=.75,.75,nOffset)
         nOffset:=IF(nMan<=.50,.50,nOffset)
         nOffset:=IF(nMan<=.25,.25,nOffset)
         nOffset:=IF(nMan<=.00,.00,nOffset)
         nVal := (Int(nNum/nMax)+nOffset)*nMax
         EXIT

      ENDIF

      nE--

   ENDDO

RETURN (nVal)


function DrawPointinBitmap( hDC, nType, nY, nX, nHigh, aColor )

   IF nType == POINTS

         DrawCircleinBitmap( hDC, nX - nHigh - 3, nY - 3, 8, aColor )

   ELSEIF nType == LINES

      DrawCircleinBitmap( hDC, nX - nHigh - 2, nY - 2, 6, aColor )

   ENDIF

RETURN

function DrawCircleinBitmap( hDC, nCol, nRow, nWidth, aColor )
   BT_DrawFillEllipse( hDC, nCol, nRow, nWidth, nWidth, aColor, aColor, nPenWidth)
RETURN



function drawpiegraphinBitMap( cImageFileName, nWidth, nHeight, series, aname, colors, ctitle, depth, l3d, lxval, lsleg, lnoborder )
   local fromrow := 0
   local fromcol := 0
   local torow := nHeight
   local tocol := nWidth
   local topleftrow := fromrow
   local topleftcol := fromcol
   local toprightrow := fromrow
   local toprightcol := tocol
   local bottomrightrow := torow
   local bottomrightcol := tocol
   local bottomleftrow := torow
   local bottomleftcol := fromcol
   local middletoprow := fromrow
   local middletopcol := fromcol + int(tocol - fromcol) / 2
   local middleleftrow := fromrow + int(torow - fromrow) / 2
   local middleleftcol := fromcol
   local middlebottomrow := torow
   local middlebottomcol := fromcol + int(tocol - fromcol) / 2
   local middlerightrow := fromrow + int(torow - fromrow) / 2
   local middlerightcol := tocol
   local fromradialrow := 0
   local fromradialcol := 0
   local toradialrow := 0
   local toradialcol := 0
   local degrees := {}
   local cumulative := {}
   local j,i,sum := 0
   local cname := ""
   local shadowcolor := {}
   local previos_cumulative
   local hDC, hBitMap, BTStruct
   
   private nPenWidth := 1


   hBitMap := BT_BitmapCreateNew ( nWidth, nHeight, { 255, 255, 255 } )
   hDC := BT_CreateDC( hBitMap, BT_HDC_BITMAP, @BTStruct )

   if ! lnoborder

      DrawLineinbitmap( hDC, torow  ,fromcol  ,torow  ,tocol  ,WHITE)
      DrawLineinbitmap( hDC, torow-1,fromcol+1,torow-1,tocol-1,GRAY )
      DrawLineinbitmap( hDC, torow-1,fromcol  ,fromrow  ,fromcol  ,GRAY )
      DrawLineinbitmap( hDC, torow-2,fromcol+1,fromrow+1,fromcol+1,GRAY )
      DrawLineinbitmap( hDC, fromrow  ,fromcol  ,fromrow  ,tocol-1,GRAY )
      DrawLineinbitmap( hDC, fromrow+1,fromcol+1,fromrow+1,tocol-2,GRAY )
      DrawLineinbitmap( hDC, fromrow  ,tocol  ,torow  ,tocol  ,WHITE)
      DrawLineinbitmap( hDC, fromrow  ,tocol-1,torow-1,tocol-1,GRAY )
      
   endif

   if HMG_LEN(ALLTRIM(ctitle)) > 0
      DrawTextInBitmap( hDC, fromrow + 10, iif(HMG_LEN(ALLTRIM(ctitle)) * 12 > (tocol - fromcol),fromcol,int(((tocol - fromcol) - (HMG_LEN(ALLTRIM(ctitle)) * 12))/2) + fromcol), ALLTRIM(ctitle), 'Arial', 12, {0,0,255} )
      fromrow := fromrow + 40
   endif   

   if lsleg
      if HMG_LEN(aname) * 20 > (torow - fromrow)
         msginfo("No space for showing legends")
      else
         torow := torow - (HMG_LEN(aname) * 20)
      endif
   endif

   drawrectinbitmap( hDC, fromrow + 10, fromcol + 10, torow - 10, tocol - 10, { 255, 255, 255 } )

   if l3d
      torow := torow - depth
   endif

   fromcol := fromcol + 25
   tocol := tocol - 25
   torow := torow - 25
   fromrow := fromrow + 25


   topleftrow := fromrow
   topleftcol := fromcol
   toprightrow := fromrow
   toprightcol := tocol
   bottomrightrow := torow
   bottomrightcol := tocol
   bottomleftrow := torow
   bottomleftcol := fromcol
   middletoprow := fromrow
   middletopcol := fromcol + int(tocol - fromcol) / 2
   middleleftrow := fromrow + int(torow - fromrow) / 2
   middleleftcol := fromcol
   middlebottomrow := torow
   middlebottomcol := fromcol + int(tocol - fromcol) / 2
   middlerightrow := fromrow + int(torow - fromrow) / 2
   middlerightcol := tocol






   torow := torow + 1
   tocol := tocol + 1

   for i := 1 to HMG_LEN(series)
      sum := sum + series[i]
   next i
   for i := 1 to HMG_LEN(series)
      aadd(degrees,round(series[i]/sum * 360,0))
   next i
   sum := 0
   for i := 1 to HMG_LEN(degrees)
      sum := sum + degrees[i]
   next i
   if sum <> 360
      degrees[HMG_LEN(degrees)] := degrees[HMG_LEN(degrees)] + (360 - sum)
   endif

   sum := 0
   for i := 1 to HMG_LEN(degrees)
      sum := sum + degrees[i]
      aadd(cumulative,sum)
   next i

   previos_cumulative := -1

   fromradialrow := middlerightrow
   fromradialcol := middlerightcol
   for i := 1 to HMG_LEN(cumulative)

      if cumulative[i] == previos_cumulative
         loop
      endif

      previos_cumulative := cumulative[i]

      shadowcolor := {iif(colors[i,1] > 50,colors[i,1] - 50,0),iif(colors[i,2] > 50,colors[i,2] - 50,0),iif(colors[i,3] > 50,colors[i,3] - 50,0)}

      do case
         case cumulative[i] <= 45
            toradialcol := middlerightcol
            toradialrow := middlerightrow - round(cumulative[i] / 45 * (middlerightrow - toprightrow),0)
            drawpieinbitmap(hDC,fromrow,fromcol,torow,tocol,fromradialrow,fromradialcol,toradialrow,toradialcol,,,colors[i])
            fromradialrow := toradialrow
            fromradialcol := toradialcol
         case cumulative[i] <= 90 .and. cumulative[i] > 45
            toradialrow := toprightrow
            toradialcol := toprightcol - round((cumulative[i] - 45) / 45 * (toprightcol - middletopcol),0)
            drawpieinbitmap(hDC,fromrow,fromcol,torow,tocol,fromradialrow,fromradialcol,toradialrow,toradialcol,,,colors[i])
            fromradialrow := toradialrow
            fromradialcol := toradialcol
         case cumulative[i] <= 135 .and. cumulative[i] > 90          
            toradialrow := topleftrow
            toradialcol := middletopcol - round((cumulative[i] - 90) / 45 * (middletopcol - topleftcol),0)
            drawpieinbitmap(hDC,fromrow,fromcol,torow,tocol,fromradialrow,fromradialcol,toradialrow,toradialcol,,,colors[i])
            fromradialrow := toradialrow
            fromradialcol := toradialcol
         case cumulative[i] <= 180 .and. cumulative[i] > 135          
            toradialcol := topleftcol
            toradialrow := topleftrow + round((cumulative[i] - 135) / 45 * (middleleftrow - topleftrow),0)
            drawpieinbitmap(hDC,fromrow,fromcol,torow,tocol,fromradialrow,fromradialcol,toradialrow,toradialcol,,,colors[i])
            fromradialrow := toradialrow
            fromradialcol := toradialcol
         case cumulative[i] <= 225 .and. cumulative[i] > 180          
            toradialcol := topleftcol
            toradialrow := middleleftrow + round((cumulative[i] - 180) / 45 * (bottomleftrow - middleleftrow),0)
            if l3d
               for j := 1 to depth
                  drawarcinBitMap(hDC,fromrow + j,fromcol,torow+j,tocol,fromradialrow+j,fromradialcol,toradialrow+j,toradialcol,shadowcolor)
               next j
            endif   
            drawpieinbitmap(hDC,fromrow,fromcol,torow,tocol,fromradialrow,fromradialcol,toradialrow,toradialcol,,,colors[i])
            fromradialrow := toradialrow
            fromradialcol := toradialcol
         case cumulative[i] <= 270 .and. cumulative[i] > 225          
            toradialrow := bottomleftrow
            toradialcol := bottomleftcol + round((cumulative[i] - 225) / 45 * (middlebottomcol - bottomleftcol),0)
            if l3d
               for j := 1 to depth
                  drawarcinbitmap(hDC,fromrow + j,fromcol,torow+j,tocol,fromradialrow+j,fromradialcol,toradialrow+j,toradialcol,shadowcolor)
               next j
            endif   
            drawpieinbitmap(hDC,fromrow,fromcol,torow,tocol,fromradialrow,fromradialcol,toradialrow,toradialcol,,,colors[i])
            fromradialrow := toradialrow
            fromradialcol := toradialcol
         case cumulative[i] <= 315 .and. cumulative[i] > 270          
            toradialrow := bottomleftrow
            toradialcol := middlebottomcol + round((cumulative[i] - 270) / 45 * (bottomrightcol - middlebottomcol),0)
            if l3d
               for j := 1 to depth
                  drawarcinBitMap(hDC,fromrow + j,fromcol,torow+j,tocol,fromradialrow+j,fromradialcol,toradialrow+j,toradialcol,shadowcolor)
               next j
            endif   
            drawpieinbitmap(hDC,fromrow,fromcol,torow,tocol,fromradialrow,fromradialcol,toradialrow,toradialcol,,,colors[i])
            fromradialrow := toradialrow
            fromradialcol := toradialcol
         case cumulative[i] <= 360 .and. cumulative[i] > 315
            toradialcol := bottomrightcol
            toradialrow := bottomrightrow - round((cumulative[i] - 315) / 45 * (bottomrightrow - middlerightrow),0)
            if l3d
               for j := 1 to depth
                  drawarcinBitMap(hDC,fromrow + j,fromcol,torow+j,tocol,fromradialrow+j,fromradialcol,toradialrow+j,toradialcol,shadowcolor)
               next j
            endif
            drawpieinbitmap(hDC,fromrow,fromcol,torow,tocol,fromradialrow,fromradialcol,toradialrow,toradialcol,,,colors[i])
            fromradialrow := toradialrow
            fromradialcol := toradialcol
         endcase
      if l3d            
         drawlineinbitmap(hDC, middleleftrow, middleleftcol, middleleftrow+depth, middleleftcol, { 0, 0, 0 } )
         drawlineinbitmap(hDC, middlerightrow, middlerightcol, middlerightrow+depth, middlerightcol, { 0, 0, 0 } )
         drawarcinBitMap(hDC,fromrow + depth,fromcol,torow + depth,tocol,middleleftrow+depth,middleleftcol,middlerightrow+depth,middlerightcol )
      endif
   next i
   if lsleg
      fromrow := torow + 20 + iif(l3d,depth,0)
      for i := 1 to HMG_LEN(aname)
         drawrectinbitmap(hDC, fromrow, fromcol, fromrow + 15, fromcol + 15, colors[ i ] )
         drawtextinbitmap( hDC, fromrow, fromcol + 20, aname[i]+iif(lxval," - "+ALLTRIM(STR(series[i],19,2))+" ("+ALLTRIM(STR(degrees[i] / 360 * 100,6,2))+" %)",""), 'Arial', 8, colors[i] )
         fromrow := fromrow + 20
      next i
   endif   
   BT_BitmapSaveFile(hBitmap, cImageFileName )
   BT_DeleteDC( BTstruct )
   BT_BitmapRelease( hBitmap )
return nil

function drawarcinBitMap(hDC,row,col,row1,col1,rowr,colr,rowr1,colr1,penrgb,penwidth)
   if valtype(penrgb) == "U"
      penrgb = {0,0,0}
   endif
   if valtype(penwidth) == "U"
      penwidth = 1
   endif
   arcdrawbitmap( hDC ,row,col,row1,col1,rowr,colr,rowr1,colr1,penrgb,penwidth)

return nil

function drawpieinbitmap(hDC,row,col,row1,col1,rowr,colr,rowr1,colr1,penrgb,penwidth,fillrgb)

   if valtype(penrgb) == "U"
      penrgb = {0,0,0}
   endif
   if valtype(penwidth) == "U"
      penwidth = 1
   endif
   if valtype(fillrgb) == "U"
      fillrgb := {255,255,255}
      fill := .f.
   else
      fill := .t.   
   endif
   piedrawbitmap( hDC,row,col,row1,col1,rowr,colr,rowr1,colr1,penrgb,penwidth,fillrgb,fill)

return nil

function drawpolygoninbitmap( hDC, apoints, penrgb, penwidth, fillrgb )
   local xarr := {}
   local yarr := {}
   local x := 0
   if valtype(penrgb) == "U"
      penrgb = {0,0,0}
   endif
   if valtype(penwidth) == "U"
      penwidth = 1
   endif
   if valtype(fillrgb) == "U"
      fillrgb := {255,255,255}
      fill := .f.
   else
      fill := .t.   
   endif
   for x := 1 to HMG_LEN(apoints)
       aadd(xarr,apoints[x,2])
       aadd(yarr,apoints[x,1])
   next x
   polygondrawbitmap( hDC, xarr, yarr, penrgb, penwidth, fillrgb, fill )
return nil

STATIC FUNCTION RGB2HSL( nR, nG, nB )
   LOCAL nMax, nMin
   LOCAL nH, nS, nL

   IF nR < 0
      nR := Abs( nR )
      nG := GetGreen( nR )
      nB := GetBlue( nR )
      nR := GetRed( nR )
   ENDIF

   nR := nR / 255
   nG := nG / 255
   nB := nB / 255
   nMax := Max( nR, Max( nG, nB ) )
   nMin := Min( nR, Min( nG, nB ) )
   nL := ( nMax + nMin ) / 2

   IF nMax = nMin
      nH := 0
      nS := 0
   ELSE
      IF nL < 0.5
         nS := ( nMax - nMin ) / ( nMax + nMin )
      ELSE
         nS := ( nMax - nMin ) / ( 2.0 - nMax - nMin )
      ENDIF
      DO CASE
         CASE nR = nMax
            nH := ( nG - nB ) / ( nMax - nMin )
         CASE nG = nMax
            nH := 2.0 + ( nB - nR ) / ( nMax - nMin )
         CASE nB = nMax
            nH := 4.0 + ( nR - nG ) / ( nMax - nMin )
      ENDCASE
   ENDIF

   nH := Int( (nH * 239) / 6 )
   IF nH < 0 ; nH += 240 ; ENDIF
   nS := Int( nS * 239 )
   nL := Int( nL * 239 )

RETURN { nH, nS, nL }


STATIC FUNCTION HSL2RGB( nH, nS, nL )
   LOCAL nFor
   LOCAL nR, nG, nB
   LOCAL nTmp1, nTmp2, aTmp3 := { 0, 0, 0 }

   nH /= 239
   nS /= 239
   nL /= 239
   IF nS == 0
      nR := nL
      nG := nL
      nB := nL
   ELSE
      IF nL < 0.5
         nTmp2 := nL * ( 1 + nS )
      ELSE
         nTmp2 := nL + nS - ( nL * nS )
      ENDIF
      nTmp1 := 2 * nL - nTmp2
      aTmp3[1] := nH + 1 / 3
      aTmp3[2] := nH
      aTmp3[3] := nH - 1 / 3
      FOR nFor := 1 TO 3
         IF aTmp3[nFor] < 0
            aTmp3[nFor] += 1
         ENDIF
         IF aTmp3[nFor] > 1
            aTmp3[nFor] -= 1
         ENDIF
         IF 6 * aTmp3[nFor] < 1
            aTmp3[nFor] := nTmp1 + ( nTmp2 - nTmp1 ) * 6 * aTmp3[nFor]
         ELSE
            IF 2 * aTmp3[nFor] < 1
               aTmp3[nFor] := nTmp2
            ELSE
               IF 3 * aTmp3[nFor] < 2
                  aTmp3[nFor] := nTmp1 + ( nTmp2 - nTmp1 ) * ( ( 2 / 3 ) - aTmp3[nFor] ) * 6
               ELSE
                  aTmp3[nFor] := nTmp1
               ENDIF
            ENDIF
         ENDIF
      NEXT nFor
      nR := aTmp3[1]
      nG := aTmp3[2]
      nB := aTmp3[3]
   ENDIF

RETURN { Int( nR * 255 ), Int( nG * 255 ), Int( nB * 255 ) }


STATIC PROC DrawBoxinBitmap( hDC, nY, nX, nHigh, nWidth, l3D, nDeep )

   // Set Border
   DrawLineinbitmap( hDC, nX, nY        , nX-nHigh+nDeep    , nY       , BLACK )  // LEFT
   DrawLineinbitmap( hDC, nX, nY+nWidth , nX-nHigh+nDeep    , nY+nWidth, BLACK )  // RIGHT
   DrawLineinbitmap( hDC, nX-nHigh+nDeep, nY, nX-nHigh+nDeep, nY+nWidth, BLACK )  // Top
   DrawLineinbitmap( hDC, nX, nY, nX, nY+nWidth, BLACK )                          // Bottom
   IF l3D
      // Set shadow
      DrawLineinbitmap( hDC, nX-nHigh+nDeep, nY+nWidth, nX-nHigh, nY+nDeep+nWidth, BLACK )
      DrawLineinbitmap( hDC, nX, nY+nWidth, nX-nDeep, nY+nWidth+nDeep, BLACK )
      IF nHigh > 0
         DrawLineinbitmap( hDC, nX-nDeep, nY+nWidth+nDeep, nX-nHigh, nY+nWidth+nDeep, BLACK )
         DrawLineinbitmap( hDC, nX-nHigh, nY+nDeep, nX-nHigh , nY+nWidth+nDeep, BLACK )
         DrawLineinbitmap( hDC, nX-nHigh+nDeep, nY, nX-nHigh, nY+nDeep, BLACK )
      ELSE
         DrawLineinbitmap( hDC, nX-nDeep, nY+nWidth+nDeep, nX-nHigh+1, nY+nWidth+nDeep, BLACK )
         DrawLineinbitmap( hDC, nX, nY, nX-nDeep, nY+nDeep, BLACK )
      ENDIF
   ENDIF

RETURN



#pragma BEGINDUMP

#include "SET_COMPILE_HMG_UNICODE.ch"
#include "HMG_UNICODE.h"


#include <windows.h>
#include <commctrl.h>
#include "hbapi.h"
#include <wingdi.h>
#include <winuser.h>

HB_FUNC ( PIEDRAWBITMAP )
{
   HDC hdc1;
   HGDIOBJ hgdiobj1,hgdiobj2;
   HPEN hpen;
   HBRUSH hbrush;
   hdc1 = (HDC) HMG_parnl (1);
   hpen = CreatePen( (int) PS_SOLID, (int) hb_parni(11), (COLORREF) RGB( (int) hb_parvni(10,1), (int) hb_parvni(10,2), (int) hb_parvni(10,3) ) );
   hgdiobj1 = SelectObject((HDC) hdc1, hpen);
   if (hb_parl(13))
   {
      hbrush = CreateSolidBrush((COLORREF) RGB((int) hb_parvni(12,1),(int) hb_parvni(12,2),(int) hb_parvni(12,3)));    
      hgdiobj2 = SelectObject((HDC) hdc1, hbrush);
   }   
   else
   {
      hbrush = GetSysColorBrush((int) COLOR_WINDOW);    
      hgdiobj2 = SelectObject((HDC) hdc1, hbrush);
   }      
   Pie((HDC) hdc1,(int) hb_parni(3),(int) hb_parni(2),(int) hb_parni(5),(int) hb_parni(4),(int) hb_parni(7),(int) hb_parni(6),(int) hb_parni(9),(int) hb_parni(8));
   SelectObject((HDC) hdc1,(HGDIOBJ) hgdiobj1);
   SelectObject((HDC) hdc1,(HGDIOBJ) hgdiobj2);
   DeleteObject( hpen );
   DeleteObject( hbrush );
}
   
HB_FUNC( POLYGONDRAWBITMAP )
{
   HDC hdc1;
   HGDIOBJ hgdiobj1,hgdiobj2;
   HPEN hpen;
   HBRUSH hbrush;
   POINT apoints[1024];
   int number=hb_parinfa(2,0);
   int i;
   hdc1 = (HDC) HMG_parnl (1);
   hpen = CreatePen( (int) PS_SOLID, (int) hb_parni(5), (COLORREF) RGB( (int) hb_parvni(4,1), (int) hb_parvni(4,2), (int) hb_parvni(4,3) ) );
   hgdiobj1 = SelectObject((HDC) hdc1, hpen);
   if (hb_parl(7))
   {
      hbrush = CreateSolidBrush((COLORREF) RGB((int) hb_parvni(6,1),(int) hb_parvni(6,2),(int) hb_parvni(6,3)));    
      hgdiobj2 = SelectObject((HDC) hdc1, hbrush);
   }   
   else
   {
      hbrush = GetSysColorBrush((int) COLOR_WINDOW);    
      hgdiobj2 = SelectObject((HDC) hdc1, hbrush);
   }      
   for(i = 0; i <= number-1; i++)
   {
   apoints[i].x=hb_parvni(2,i+1);
   apoints[i].y=hb_parvni(3,i+1);
   }
   Polygon((HDC) hdc1,apoints,number);
   SelectObject((HDC) hdc1,(HGDIOBJ) hgdiobj1);
   SelectObject((HDC) hdc1,(HGDIOBJ) hgdiobj2);
   DeleteObject( hpen );
   DeleteObject( hbrush );
}

HB_FUNC ( ARCDRAWBITMAP )
{
   HDC hdc1;
   HGDIOBJ hgdiobj1;
   HPEN hpen;
   hdc1 = (HDC) HMG_parnl (1);
   hpen = CreatePen( PS_SOLID, (int) hb_parni(11), (COLORREF) RGB( (int) hb_parvni(10,1), (int) hb_parvni(10,2), (int) hb_parvni(10,3) ) );
   hgdiobj1 = SelectObject( hdc1, hpen );
   Arc( hdc1,(int) hb_parni(3),(int) hb_parni(2),(int) hb_parni(5),(int) hb_parni(4),(int) hb_parni(7),(int) hb_parni(6),(int) hb_parni(9),(int) hb_parni(8));
   SelectObject( hdc1, hgdiobj1);
   DeleteObject( hpen );
}

HB_FUNC( POLYBEZIERDRAWBITMAP )
{
   HDC hdc1;
   HGDIOBJ hgdiobj1;
   HPEN hpen;
   POINT apoints[1024];
   DWORD number=(DWORD) hb_parinfa(2,0);
   DWORD i;
   hdc1 = (HDC) HMG_parnl (1);
   hpen = CreatePen( (int) PS_SOLID, (int) hb_parni(5), (COLORREF) RGB( (int) hb_parvni(4,1), (int) hb_parvni(4,2), (int) hb_parvni(4,3) ) );
   hgdiobj1 = SelectObject((HDC) hdc1, hpen);
   for(i = 0; i <= number-1; i++)
   {
   apoints[i].x=hb_parvni(2,i+1);
   apoints[i].y=hb_parvni(3,i+1);
   }
   PolyBezier((HDC) hdc1,apoints,number);
   SelectObject((HDC) hdc1,(HGDIOBJ) hgdiobj1);
   DeleteObject( hpen );
}   

#pragma ENDDUMP
Very Nice!!!
I will update BT with this functions and include Graph Bitmap in the next release of HMG, many thanks.
Best regards.
Dr. Claudio Soto
(from Uruguay)
http://srvet.blogspot.com
Post Reply