CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 1 of 1
  1. #1
    Join Date
    Feb 2000
    Location
    Indore, India
    Posts
    1,046

    Windows SDK GDI: How do I display text filled and in shape of a region?

    Q: How do I display text filled and in shape of a region?

    A: Displaying text as non-rectangular is a bit of tricky. Here, I will explain how the text can be displayed as deformed to take the shape of a region. I am presenting the code in the form of a function (I have used the familiar name 'DrawText()' for this function), whose parameters are handles to the device context (as 'HDC'), the string to be displayed (as 'LPSTR') and the handle to the region (as 'HRGN').


    Code:
    void DrawText(HDC hdc, LPSTR lpstring, HRGN hrgn)
    {
      // Creates a memory device context
      HDC hMemDC = CreateCompatibleDC(hdc);
      if (hMemDC)
      {
        // Memory device context is created successfully
        // Gets the width and height of the string
        DWORD Size = GetTabbedTextExtent(hMemDC, lpstring, strlen(lpstring), 0, NULL);
        int Width  = LOWORD(Size);
        int Height = HIWORD(Size);
    
        // Creates bitmap and selects to the memory device context
        HBITMAP hBitmap = CreateCompatibleBitmap(hdc, Width, Height);
        HBITMAP hOldBitmap = (HBITMAP) SelectObject(hMemDC, hBitmap);
    
        // Paints memory device context in white
        RECT Rect;
        SetRect(&Rect, 0, 0, Width, Height);
        FillRect(hMemDC, &Rect, (HBRUSH) GetStockObject(WHITE_BRUSH));
    
        // Sets color and background mode
        COLORREF Black = RGB(0, 0, 0);
        SetTextColor(hMemDC, Black);
        SetBkMode(hMemDC, TRANSPARENT);
    
        // Displays string in memory device context
        TextOut(hMemDC, 0, 0, lpstring, strlen(lpstring));
    
        // Finds the text occupying area bounded by X0, Y0, X1, Y1
        int X0 = -1;
        int X1 = -1;
        int Y0 = -1;
        int Y1 = -1;
    
        for (int iX = 0; iX <= Width; iX++)
          for (int iY = 0; iY <= Height; iY++)
            if (GetPixel(hMemDC, iX, iY) == Black)
            {
              X0 = X0 >= 0 ? (iX < X0 ? iX : X0) : iX;
              Y0 = Y0 >= 0 ? (iY < Y0 ? iY : Y0) : iY;
              X1 = X1 >= 0 ? (iX > X1 ? iX : X1) : iX;
              Y1 = Y1 >= 0 ? (iY > Y1 ? iY : Y1) : iY;
            }
    
        // Computes bounds of region
        GetRgnBox(hrgn, &Rect);
    
        // Gets current text color of device context
        COLORREF Color = GetTextColor(hdc);
    
        // Scans the region in X direction
        for (iX = Rect.left; iX <= Rect.right; iX++)
        {
          int X = X0 + (X1 - X0) * (iX - Rect.left) / (Rect.right - Rect.left);
          int YMin = -1, YMax = -1;
    
          // Computes bounds of Y for corresponding iX
          for (int iY = Rect.top; iY <= Rect.bottom; iY++)
            if (PtInRegion(hrgn, iX, iY))
            {
              YMin = YMin >= 0 ? (iY < YMin ? iY : YMin) : iY;
              YMax = YMax >= 0 ? (iY > YMax ? iY : YMax) : iY;
            }
    
          // Scales string image for current Y limits
          if (YMax != YMin)
            for (iY = YMin; iY <= YMax; iY++)
            {
              int Y = Y0 + (Y1 - Y0) * (iY - YMin) / (YMax - YMin);
              if (GetPixel(hMemDC, X, Y) == Black)
                SetPixel(hdc, iX, iY, Color);
            }
        }
    
        // Deselects bitmap and deletes device context
        SelectObject(hMemDC, hOldBitmap);
        DeleteDC(hMemDC);
      }
    }
    The method used here is quite simple. What I did is to write the string in a memory device context and scale it to the region according to its minimum and maximum 'Y' value at each 'X' position. Sample comments are given at each steps.

    Here is a screen shot of what I got. Note that the region is shaded in gray for illustration.



    Attached Images Attached Images  
    Last edited by Andreas Masur; May 20th, 2006 at 09:45 AM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured