Image overlap

    This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

    • Image overlap

      Hi,

      I have been using emWin for quite sometime now and haven't come across this before. On a window widget I am displaying few 2 buttons and 2 images. For some reason I see 2nd image in the background of first image. I checked the parameters and made sure I am not displaying the image twice. I have been using the same procedure on a couple other windows but haven't had any problems with it.

      I'd really appreciate it if someone came across this problem and could help me or any suggestions will do.

      Thank you,
      BMD
    • Hi,

      Do you have some code which shows how to reproduce it?

      Regards,
      Sven
      Please read the forum rules before posting.

      Keep in mind, this is *not* a support forum.
      Our engineers will try to answer your questions between their projects if possible but this can be delayed by longer periods of time.
      Should you be entitled to support you can contact us via our support system: segger.com/ticket/

      Or you can contact us via e-mail.
    • Sven,

      Thank you for quick response. Please see attached code and Images I am currently using.

      Best regards,
      BMD

      Source Code

      1. #include "DIALOG.h"
      2. #include "FS.h"
      3. static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] =
      4. {
      5. {WINDOW_CreateIndirect, "", TOOLS_3_SCREEN_WINDOW, 0, 0, 320, 240, 0, 0, 0},
      6. {HEADER_CreateIndirect, "", TOOLS_3_SCREEN_HEADER, 0, 0, 320, 40, 0, 0, 0},
      7. {BUTTON_CreateIndirect, "", SERVICE_BUTTON, 25, 40, 185, 35, 0, 0, 0},
      8. {BUTTON_CreateIndirect, "", ABOUT_BUTTON, 25, 90, 185, 35, 0, 0, 0},
      9. {IMAGE_CreateIndirect, "", SERVICE_ICON, 260, 40, 35, 35, 0, 0, 0},
      10. {IMAGE_CreateIndirect, "", ABOUT_ICON, 260, 90, 35, 35, 0, 0, 0}
      11. };
      12. static void _cbServiceIcon(WM_MESSAGE* pMsg)
      13. {
      14. if(pMsg->MsgId == WM_PAINT)
      15. {
      16. drawBMP_ExternalMemory("Service.bmp");
      17. }// end if
      18. else
      19. {
      20. IMAGE_Callback(pMsg);
      21. }// end else
      22. }// end function _cbServiceIcon
      23. static void _cbAboutIcon(WM_MESSAGE* pMsg)
      24. {
      25. if(pMsg->MsgId == WM_PAINT)
      26. {
      27. drawBMP_ExternalMemory("About.bmp");
      28. }// end if
      29. else
      30. {
      31. IMAGE_Callback(pMsg);
      32. }// end else
      33. }// end function _cbAboutIcon
      34. static void _cbTools3Screen(WM_MESSAGE* pMsg)
      35. {
      36. BUTTON_Handle hButton;
      37. HEADER_Handle hHeader;
      38. IMAGE_Handle hImage;
      39. WM_HWIN hWin;
      40. int Id;
      41. int NCode;
      42. hWin = pMsg->hWin;
      43. switch(pMsg->MsgId)
      44. {
      45. case WM_PAINT:
      46. // Draw the background. This is quite important because otherwise we would
      47. // still see the child window although it gets deleted.
      48. GUI_SetBkColor(GUI_BEIGE_BACKGROUND);
      49. GUI_Clear();
      50. break;
      51. case WM_INIT_DIALOG:
      52. // Initialize Tools header object.
      53. hHeader = WM_GetDialogItem(hWin, TOOLS_3_SCREEN_HEADER);
      54. WM_ClrHasTrans(hHeader);
      55. HEADER_SetFont(hHeader, GUI_FONT_20B_1);
      56. HEADER_SetTextColor(hHeader, GUI_BLACK);
      57. HEADER_AddItem(hHeader, 320, "Tools", GUI_TA_CENTER);
      58. // Initialize Service button object.
      59. hButton = WM_GetDialogItem(hWin, SERVICE_BUTTON);
      60. WM_ClrHasTrans(hButton);
      61. BUTTON_SetText(hButton, "Service");
      62. // Initialize About button object.
      63. hButton = WM_GetDialogItem(hWin, ABOUT_BUTTON);
      64. WM_ClrHasTrans(hButton);
      65. BUTTON_SetText(hButton, "About");
      66. // Initialize Service icon object.
      67. hImage = WM_GetDialogItem(hWin, SERVICE_ICON);
      68. WM_ClrHasTrans(hImage);
      69. WM_SetCallback(hImage, _cbServiceIcon);
      70. // Initialize About icon object.
      71. hImage = WM_GetDialogItem(hWin, ABOUT_ICON);
      72. WM_ClrHasTrans(hImage);
      73. WM_SetCallback(hImage, _cbAboutIcon);
      74. break;
      75. case WM_NOTIFY_PARENT:
      76. Id = WM_GetId(pMsg->hWinSrc);
      77. NCode = pMsg->Data.v;
      78. switch(NCode)
      79. {
      80. case WM_NOTIFICATION_CLICKED:
      81. CurrentButton.Id = Id;
      82. CurrentButton.State = CLICKED;
      83. break;
      84. case WM_NOTIFICATION_RELEASED:
      85. CurrentButton.State = RELEASED;
      86. WM_DeleteWindow(hWin);
      87. switch(Id)
      88. {
      89. case SERVICE_BUTTON:
      90. serviceScreen();
      91. break;
      92. case ABOUT_BUTTON:
      93. aboutScreen();
      94. break;
      95. case BACK_3_BUTTON:
      96. tools2Screen();
      97. break;
      98. case HOME_3_BUTTON:
      99. mainScreen();
      100. }// end switch
      101. }// end switch
      102. break;
      103. default:
      104. WM_DefaultProc(pMsg);
      105. }// end switch
      106. }// end function _cbTools3Screen
      107. void tools3Screen(void)
      108. {
      109. // Check if recommended memory for the sample is available.
      110. if(GUI_ALLOC_GetNumFreeBytes() < RECOMMENDED_MEMORY)
      111. {
      112. return;
      113. }// end if
      114. // Use memory devices for all windows.
      115. #if GUI_SUPPORT_MEMDEV
      116. WM_SetCreateFlags(WM_CF_MEMDEV);
      117. WM_EnableMemdev(WM_HBKWIN);
      118. #endif
      119. WM_MULTIBUF_Enable(TRUE); // Enable multibuffering prior to drawing the screen.
      120. GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), &_cbTools3Screen, 0,
      121. 0, 0);
      122. }// end function tools3Screen
      Display All


      Source Code

      1. #include "cytypes.h"
      2. #include "FS.h"
      3. #include "GUI.h"
      4. int getDataBMP(void* p, const uint8** ppData, unsigned NumBytes, uint32 Off)
      5. {
      6. #define MAX_LINE_BYTES 640 // 320 pixels, 16-bit color.
      7. static uint8 acBuffer[MAX_LINE_BYTES];
      8. int16 NumBytesRead;
      9. FS_FILE* pFile;
      10. pFile = (FS_FILE *)p;
      11. // Check buffer size.
      12. if(NumBytes > MAX_LINE_BYTES)
      13. {
      14. NumBytes = MAX_LINE_BYTES;
      15. }// end if
      16. // Set file pointer to the required position.
      17. FS_SetFilePos(pFile, Off, FS_FILE_BEGIN);
      18. NumBytesRead = FS_FRead(acBuffer, 1, NumBytes, pFile); // Read data into buffer.
      19. *ppData = (const uint8 *)acBuffer; // Set data pointer to the beginning of the buffer.
      20. return NumBytesRead; // Return number of available bytes.
      21. }// end function getDataBMP
      22. void drawBMP_ExternalMemory(const char * filename)
      23. {
      24. FS_FILE * pFile;
      25. pFile = FS_FOpen(filename, "rb"); // Open the file.
      26. // Draw the bmp image by passing a pointer to the file handle and the GetData
      27. // function.
      28. GUI_BMP_DrawEx(getDataBMP, pFile, 0, 0);
      29. FS_FClose(pFile); // Close the file.
      30. }
      Display All
      Files
      • About.bmp

        (2.59 kB, downloaded 335 times, last: )
      • Service.bmp

        (1.81 kB, downloaded 335 times, last: )
    • Hi,

      Not sure why you see the second image in the background, but when removing the transparency flag of the image you should make sure you paint the entire widget area.

      In the callback functions of the image widgets you draw only the BMPs. The Service BMP is smaller than the widget and there will be some undefined space left. I could imagine that this undefined area will show any kind of artifact (on my end it was simply black).

      Try something like:

      C Source Code

      1. static void _cbServiceIcon(WM_MESSAGE* pMsg)
      2. {
      3. if(pMsg->MsgId == WM_PAINT)
      4. {
      5. GUI_SetBkColor(MyBkColor);
      6. GUI_Clear();
      7. drawBMP_ExternalMemory("Service.bmp");
      8. }// end if
      9. else
      10. {
      11. IMAGE_Callback(pMsg);
      12. }// end else
      13. }// end function _cbServiceIcon
      Display All

      Best regards,
      Sven
      Please read the forum rules before posting.

      Keep in mind, this is *not* a support forum.
      Our engineers will try to answer your questions between their projects if possible but this can be delayed by longer periods of time.
      Should you be entitled to support you can contact us via our support system: segger.com/ticket/

      Or you can contact us via e-mail.
    • Sven,

      Appreciate the response. Thank you so much.
      Also, when the image is touched, it clears the entire scree. The only I know to stop that from happening is to disable the image. Is there any other efficient way of doing this?

      Best regards,
      BMD
    • Hi,


      bio_med wrote:

      Also, when the image is touched, it clears the entire scree.
      This shouldn't happen at all.

      For now I have no idea why this happens on your end.

      You could try to catch the touch events of the IMAGE widget and do nothing, like:

      C Source Code

      1. static void _cbImage1(WM_MESSAGE * pMsg) {
      2. switch (pMsg->MsgId) {
      3. case WM_PAINT:
      4. _DrawBMP("About.bmp");
      5. break;
      6. case WM_TOUCH:
      7. case WM_PID_STATE_CHANGED:
      8. break;
      9. default:
      10. IMAGE_Callback(pMsg);
      11. break;
      12. }
      13. }
      Display All

      Although, this shouldn't cause such a behavior, you could also try to remove these calls:

      C Source Code

      1. #if GUI_SUPPORT_MEMDEV
      2. WM_SetCreateFlags(WM_CF_MEMDEV);
      3. WM_EnableMemdev(WM_HBKWIN);
      4. #endif
      When using multibuffering there is little to no reason of using automatic memory devices. This will produce only an overhead in regards of drawing operations. With automatic memory devices on emWin will first write into the memory devices and then draw the memory devices onto the screen. Without memory devices emWin will write directly into the frambeuffer.

      Regards,
      Sven
      Please read the forum rules before posting.

      Keep in mind, this is *not* a support forum.
      Our engineers will try to answer your questions between their projects if possible but this can be delayed by longer periods of time.
      Should you be entitled to support you can contact us via our support system: segger.com/ticket/

      Or you can contact us via e-mail.
    • Sven,

      Thank you so much for helping me out in figuring a better way to do things.

      I tried to remove the automatic memory devices but that's causing bitmaps on buttons on each screen to flicker. Can you help me understand what could be causing this?

      Thanks and regards,
      BMD
    • Hi,

      When using memory devices for windows/widgets emWin will draw the bitmaps at first into the memory devices. Once this is done the memory device will be displayed at once. If you are using no memory devices you might experience a visual build up of the image because they will be drawn line wise. This will result in a flickering effect.

      The most efficient way to avoid this would be either multi buffering (GUIDRV_Lin) or a cache (almost any other driver, e.g. GUIDRV_FlexColor). If you don't have enough memory for multi buffering or a cache you can still use the automatic memory devices. For multi buffering or a cache you need at least as many additional bytes to hold one complete screen (xSize x ySize x bytes per pixel). The automatic memory devices require just as many memory as the size of the window/widget (xSizeWin x ySizeWin x byte per pixel).

      More information about multi buffering can be found here:
      wiki.segger.com/emWin_Multi-Buffering

      A lot of users using autom memory devices in combination with multi buffering. But this is a bit over the top because there are no benefits but an overhead in drawing.

      If you can't use multibuffering or a cache, then it is time to think about automatic memory devices.

      Regards,
      Sven
      Please read the forum rules before posting.

      Keep in mind, this is *not* a support forum.
      Our engineers will try to answer your questions between their projects if possible but this can be delayed by longer periods of time.
      Should you be entitled to support you can contact us via our support system: segger.com/ticket/

      Or you can contact us via e-mail.