BBC BASIC for Windows
Programming >> Graphics and Games >> GDI+ DrawString Function
http://bb4w.conforums.com/index.cgi?board=graphics&action=display&num=1399559034

GDI+ DrawString Function
Post by VBI on May 8th, 2014, 2:23pm

I'm hoping somebody who knows a bit more about GDI+ than me (not hard) could take a look at the attached code and give a pointer to where I'm going wrong.

This is just a piece of testbed code to exercise the functions I need to use as part of a larger program that can render multiple images and text into a DIB that, ultimately, gets sent to a printer via a direct control DLL.

No problem rendering the images as required. The problem I'm having is that I cannot get the string rendering to work at all. The GdipDrawString function either returns 11 or 1, depending on how I play with the rcf{} parameters, and nothing is rendered to the DIB.

To experiment, I have also tried rendering a rectangle, GdipDrawRectanglel, and a filled rectangle, GdipFillRectangle, both of which complete without error but produce nothing in the DIB.

I'm sure I'm doing something fundamentally wrong here, but have gone around in fruitless circles trying to find what it may be. The code that is of primary focus (I think) is REM'd with "Start" and "End". The program will save a .bmp file of the DIB for diagnostic purposes.

Thanks,
Graham.


Code:
      HIMEM = (LOMEM+100000000) AND -4
      
      infile$="c:\windows\Soap Bubbles.bmp"
      
      pagewide%=1844 : pagehigh%=1240
      
      img1_x%=100  : img1_y%=100 : img1_w%=256 : img1_h%=256
      img2_x%=500  : img2_y%=350 : img2_w%=512 : img2_h%=512
      img3_x%=1200 : img3_y%=600 : img3_w%=512 : img3_h%=512
      
      REM Load DLL
      SYS "LoadLibrary", "GDIPLUS.DLL" TO gdip%
      IF gdip%=0 ERROR 100, "Couldn't load GDIPLUS.DLL"
      SYS "GetProcAddress", gdip%, "GdiplusStartup" TO `GdiplusStartup`
      SYS "GetProcAddress", gdip%, "GdipLoadImageFromFile" TO `GdipLoadImageFromFile`
      SYS "GetProcAddress", gdip%, "GdipDrawImageRectRectI" TO `GdipDrawImageRectRectI`
      SYS "GetProcAddress", gdip%, "GdipGetImageHeight" TO `GdipGetImageHeight`
      SYS "GetProcAddress", gdip%, "GdipGetImageWidth" TO `GdipGetImageWidth`
      SYS "GetProcAddress", gdip%, "GdipCreateFromHDC" TO `GdipCreateFromHDC`
      SYS "GetProcAddress", gdip%, "GdipSetSmoothingMode" TO `GdipSetSmoothingMode`
      SYS "GetProcAddress", gdip%, "GdipDeleteGraphics" TO `GdipDeleteGraphics`
      SYS "GetProcAddress", gdip%, "GdipDisposeImage" TO `GdipDisposeImage`
      SYS "GetProcAddress", gdip%, "GdiplusShutdown" TO `GdiplusShutdown`
      SYS "GetProcAddress", gdip%, "GdipImageRotateFlip" TO `GdipImageRotateFlip`
      SYS "GetProcAddress", gdip%, "GdipCloneImage" TO `GdipCloneImage`
      SYS "GetProcAddress", gdip%, "GdipCreateFontFamilyFromName" TO `GdipCreateFontFamilyFromName`
      SYS "GetProcAddress", gdip%, "GdipCreateFont" TO `GdipCreateFont`
      SYS "GetProcAddress", gdip%, "GdipCreateSolidFill" TO `GdipCreateSolidFill`
      SYS "GetProcAddress", gdip%, "GdipDrawString" TO `GdipDrawString`
      SYS "GetProcAddress", gdip%, "GdipCreatePen1" TO `GdipCreatePen1`
      SYS "GetProcAddress", gdip%, "GdipGetPenColor" TO `GdipGetPenColor`
      SYS "GetProcAddress", gdip%, "GdipDrawRectangleI" TO `GdipDrawRectangleI`
      SYS "GetProcAddress", gdip%, "GdipFillRectangle" TO `GdipFillRectangle`
      SYS "GetProcAddress", gdip%, "GdipDeleteFontFamily" TO `GdipDeleteFontFamily`
      SYS "GetProcAddress", gdip%, "GdipDeleteFont" TO `GdipDeleteFont`
      SYS "GetProcAddress", gdip%, "GdipDeleteBrush" TO `GdipDeleteBrush`
      SYS "GetProcAddress", gdip%, "GdipDeletePen" TO `GdipDeletePen`
      
      DIM tSI{GdiplusVersion%, DebugEventCallback%, \
      \       SuppressBackgroundThread%, SuppressExternalCodecs%}
      tSI.GdiplusVersion%=1
      SYS `GdiplusStartup`, ^lGDIP%, tSI{}, 0
      
      SYS "CreateCompatibleDC", 0 TO hdc%
      
      DIM bmi{biSize%, biWidth%, biHeight%, biPlanes{l&,h&}, biBitCount{l&,h&}, \
      \       biCompression%, biSizeImage%, biXPelsPerMeter%, biYPelsPerMeter%, \
      \       biClrUsed%, biClrImportant%}
      bmi.biSize%=DIM(bmi{})
      bmi.biWidth%=pagewide%
      bmi.biHeight%=pagehigh%
      bmi.biPlanes.l&=1
      bmi.biBitCount.l&=24
      
      SYS "CreateDIBSection", hdc%, bmi{}, 0, ^bits%, 0, 0 TO hdib%
      SYS "SelectObject", hdc%, hdib% TO old%
      SYS "PatBlt", hdc%, 0, 0, pagewide%, pagehigh%, &FF0062 : REM Paint White Bkgrnd
      SYS `GdipCreateFromHDC`, hdc%, ^gfx%
      SYS `GdipSetSmoothingMode`, gfx%, 2 : REM 2=High Quality
      
      DIM infileW% 2*LEN(infile$)+1
      SYS "MultiByteToWideChar", 0, 0, infile$, -1, infileW%, LEN(infile$)+1
      SYS `GdipLoadImageFromFile`, infileW%, ^image0%
      IF image0%=0 THEN
        SYS `GdiplusShutdown`, lGDIP%
        SYS "FreeLibrary", gdip%
      ENDIF
      
      SYS `GdipCloneImage`, image0%, ^image90%
      SYS `GdipImageRotateFlip`, image90%, 1 TO res% : REM 1=90CW No-Flip
      
      SYS `GdipGetImageWidth`, image0%, ^ix% : SYS `GdipGetImageHeight`, image0%, ^iy%
      SYS `GdipDrawImageRectRectI`, gfx%, image0%, img1_x%, img1_y%, img1_w%, img1_h%, 0, 0, ix%, iy%, 2, 0, 0, 0
      SYS `GdipDrawImageRectRectI`, gfx%, image0%, img2_x%, img2_y%, img2_w%, img2_h%, 0, 0, ix%, iy%, 2, 0, 0, 0
      
      SYS `GdipGetImageWidth`, image90%, ^ix% : SYS `GdipGetImageHeight`, image90%, ^iy%
      SYS `GdipDrawImageRectRectI`, gfx%, image90%, img3_x%, img3_y%, img3_w%, img3_h%, 0, 0, ix%, iy%, 2, 0, 0, 0
      
      REM *************
      REM *** Start ***
      REM *************
      ttf$="Arial"
      DIM ttf% 2*LEN(ttf$)+1
      SYS "MultiByteToWideChar", 0, 0, ttf$, -1, ttf%, LEN(ttf$)+1
      SYS `GdipCreateFontFamilyFromName`, ttf%, 0, ^hFontFamily% TO res%
      PRINT "CreateFontFamily Handle: ";hFontFamily%
      PRINT "CreateFontFamily Result: ";res%
      
      SYS `GdipCreateFont`, hFontFamily%, 24, 0, 0, ^hFont% TO res%
      PRINT "CreateFont Handle: ";hFont%
      PRINT "CreateFont Result: ";res%
      
      DIM ARGB% 3 : REM For Black Brush/Pen
      ARGB%?0=255
      ARGB%?1=0
      ARGB%?2=0
      ARGB%?3=0
      
      SYS `GdipCreateSolidFill`, ARGB%, ^hBrush% TO res%
      PRINT "CreateSolidFill (Brush) Handle: "hBrush%
      PRINT "CreateSolidFill (Brush) Result: ";res%
      
      SampleText$="Hello World!"
      DIM string% 2*LEN(SampleText$)+1
      SYS "MultiByteToWideChar", 0, 0, SampleText$, -1, string%, LEN(SampleText$)+1
      chars%=LEN(SampleText$)+1
      
      DIM rcf{x,y,w,h}
      rcf{}.x=10.0
      rcf{}.y=10.0
      rcf{}.w=100.0
      rcf{}.h=50.0
      
      SYS `GdipDrawString`, gfx%, string%, chars%, hFont%, rcf{}, 0, hBrush% TO res%
      IF res% <>0 res$="***FAILED***> " ELSE res$="***OK***>"
      PRINT "DrawString Result: "+res$;res%
      
      SYS `GdipCreatePen1`, ARGB%, 5, 2, ^hPen% TO res%
      PRINT "CreatePen Handle: ";hPen%
      PRINT "CreatePen Result: ";res%
      
      SYS `GdipGetPenColor`, hPen%, ^hCol% TO res%
      PRINT "GetPenColor (just to confirm): ";hCol%?0,;hCol%?1,;hCol%?2,;hCol%?3
      PRINT "GetPenColor Result: ";res%
      
      rect_x=0.5
      rect_y=0.5
      rect_w=100.0
      rect_h=50.0
      
      SYS `GdipDrawRectangleI`, gfx%, hPen%, rect_x, rect_y, rect_w, rect_h TO res%
      PRINT "DrawRectanglel Result: ";res%
      
      SYS `GdipFillRectangle`, gfx%, hBrush%, rect_x, rect_y, rect_w, rect_h TO res%
      PRINT "FillRectangle Result: ";res%
      REM *************
      REM ***  END  ***
      REM *************
      
      SYS "SelectObject", hdc%, old%
      SYS "DeleteDC", hdc%
      SYS `GdipDeleteGraphics`, gfx%
      SYS `GdipDisposeImage`, image0%
      SYS `GdipDisposeImage`, image90%
      SYS `GdipDeleteFontFamily`, hFontFamily%
      SYS `GdipDeleteFont`, hFont%
      SYS `GdipDeleteBrush`, hBrush%
      SYS `GdipDeletePen`, hPen%
      SYS `GdiplusShutdown`, lGDIP%
      SYS "FreeLibrary", gdip%
      
      outfile$=@dir$+"DIB_bits.raw"
      OSCLI "SAVE """+outfile$+""" "+STR$~bits%+" +"+STR$~((pagewide%*pagehigh%)*3)
      
      DIM hdr% 53
      hdr%?0=ASC"B"
      hdr%?1=ASC"M"
      hdr%!2=((pagewide%*pagehigh%)*3)+54
      hdr%!10=54
      hdr%!14=40
      hdr%!18=pagewide%
      hdr%!22=pagehigh%
      hdr%!26=&180001
      ch0=OPENOUT(@dir$+"DIB_bits.bmp")
      FOR p%=0 TO 53
        BPUT#ch0,hdr%?p%
      NEXT p%
      FOR p%=0 TO ((pagewide%*pagehigh%)*3)-1
        BPUT#ch0,bits%?p%
      NEXT p%
      CLOSE#ch0

 

Re: GDI+ DrawString Function
Post by rtr on May 8th, 2014, 3:02pm

on May 8th, 2014, 2:23pm, VBI wrote:
I'm sure I'm doing something fundamentally wrong here, but have gone around in fruitless circles trying to find what it may be.

This is not an answer to your question, but is there a specific reason why you are not using Hans's library GDIPlib_win.bbc which incorporates routines for outputting text, specifically PROC_g_p_text(), PROC_g_text() and PROC_g_text_fancy()?

Even if you prefer not to use that library, you could study its code and by comparing it with yours probably identify where the problem lies.

Hans's library can be found via the Libraries page on the Wiki.

Richard.

Re: GDI+ DrawString Function
Post by VBI on May 8th, 2014, 3:40pm

Doh! I'm sure I have that library downloaded already somewhere, but had forgotten it - I'll take a look.

I also think that the "FN_f4", to convert to 4 byte real format, contained within your own GDI library may also be pertinent here.

Thanks, Richard.

Graham.


Re: GDI+ DrawString Function
Post by rtr on May 8th, 2014, 3:49pm

on May 8th, 2014, 3:40pm, VBI wrote:
I also think that the "FN_f4", to convert to 4 byte real format, contained within your own GDI library may also be pertinent here.

Yes indeed. Glancing at your code the rectangle definition would need to be:

Code:
      DIM rcf{x%,y%,w%,h%}
      rcf.x% = FN_f4(10.0)
      rcf.y% = FN_f4(10.0)
      rcf.w% = FN_f4(100.0)
      rcf.h% = FN_f4(50.0) 

Richard.