HOWTO: Calculate a Bounding Rectangle For a of String Text

ID: Q203099


The information in this article applies to:


SUMMARY

In many cases it is necessary to calculate the display area occupied by a particular text string when outputting it to a display context. The code in this article demonstrates one way of deriving this information and returning it as a bounding rectangle.

Regardless of the rotation or orientation of the text, the bounding rectangle is not rotated. The left and right sides of the bounding rectangle parallel the Y axis and the top and bottom sides parallel the X axis. It is noteworthy that the bounding rectangle that's returned represents the pixel bounds of the text's glyphs rather than the typographical extents that would be used for text formatting.


MORE INFORMATION

The following function returns a bounding rectangle for a string of text. It does this by drawing the text as a path and then retrieving the data comprising the path and scanning it for the maximum and minimum extents.

NOTE: Only True Type fonts are supported in paths so this function only works with True Type fonts.


/********************************************************************
  *                                                                   *
  * FUNCTION:  GetTextBoundingRect()                                  *
  *                                                                   *
  * PURPOSE:   Get a bounding rectangle for a string of text output   *
  *            to a specified coordinate in a DC using the currently  *
  *            selected font                                          *
  *                                                                   *
  * NOTES:     The reference DC must have a True Type font selected   *
  *                                                                   *
  *********************************************************************/ 
  BOOL GetTextBoundingRect(HDC    hDC,   // Reference DC
                           int    x,     // X-Coordinate
                           int    y,     // Y-Coordinate
                           LPSTR  lpStr, // The text string to evaluate
                           DWORD  dwLen, // The length of the string 
                           LPRECT lprc)  // Holds bounding rectangle
  {
      LPPOINT lpPoints; 
      LPBYTE lpTypes;
      int i, iNumPts;
  
      // Draw the text into a path
      BeginPath(hDC);
      i = SetBkMode(hDC, TRANSPARENT);
      TextOut(hDC, x, y, lpStr, dwLen);
      SetBkMode(hDC, i);
      EndPath(hDC);
  
      // How many points are in the path
      iNumPts = GetPath(hDC, NULL, NULL, 0);
      if (iNumPts == -1) return FALSE;
  
      // Allocate room for the points
      lpPoints = (LPPOINT)GlobalAlloc(GPTR, sizeof(POINT) * iNumPts);
      if (!lpPoints) return FALSE;
  
      // Allocate room for the point types
      lpTypes = GlobalAlloc(GPTR, iNumPts);
      if (!lpTypes) {
          GlobalFree(lpPoints);
          return FALSE;
      }
  
      // Get the points and types from the current path
      iNumPts = GetPath(hDC, lpPoints, lpTypes, iNumPts);
  
      // Even more error checking
      if (iNumPts == -1) {
          GlobalFree(lpTypes);
          GlobalFree(lpPoints);
          return FALSE;
      }
  
      // Initialize the rectangle
      SetRect(lprc, 0xFFFFF, 0xFFFFF, 0, 0);

      // Get the maximum/minimum extents from the path data
      for (i=0; i<iNumPts; i++) {
          if (lpPoints[i].x > lprc->right)  lprc->right  = lpPoints[i].x;
          if (lpPoints[i].y > lprc->bottom) lprc->bottom = lpPoints[i].y;
          if (lpPoints[i].x < lprc->left)   lprc->left   = lpPoints[i].x;
          if (lpPoints[i].y < lprc->top)    lprc->top    = lpPoints[i].y;
      }
  
      GlobalFree(lpTypes);
      GlobalFree(lpPoints);
  
      return TRUE;
  } 


REFERENCES

For more information on paths, what they are, and how to use them, please see the following article in the Microsoft Knowledge Base:

Q128091 SAMPLE: How to Use Paths to Create Text Effects

Additional query words: kbDSupport


Keywords          : 
Version           : WINDOWS:
Platform          : WINDOWS 
Issue type        : kbhowto 

Last Reviewed: May 3, 1999