Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 9078223
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 16, 20262026-06-16T19:33:56+00:00 2026-06-16T19:33:56+00:00

The question is simple. How to draw following text into TStringGrid cell? Operating system

  • 0

The question is simple. How to draw following text into TStringGrid cell?

enter image description here

Operating system is Windows XP (or Windows Vista or Windows 7). Preferred development environment is C++ Builder 6, but I will accept also solutions for C++ Builder XE of Delphi. Preferred API function is DrawText, but if better function exists than this no problem. Font name is Times New Roman, font size is 11. Currently I am using this method to render cell content (simplified):

void __fastcall TForm_Main::StringGrid_DrawCell(TObject *Sender,
  int ACol, int ARow, TRect &Rect, TGridDrawState State)
{
   TStringGrid *grid = (TStringGrid*)Sender;
   if (grid == NULL) return;

   // 1. BACKGROUND
   grid->Canvas->Brush->Color = grid->Color;
   grid->Canvas->FillRect(Rect);

   // 2. TEXT
   grid->Canvas->Font->Assign(grid->Font);   // Times New Roman, 11pt

   // horizontal centering
   RECT RText = static_cast<RECT>(Rect);
   AnsiString text = grid->Cells[ACol][ARow];
   if (!text.IsEmpty()) {
      int text_len = strlen(text.c_str());
      SIZE size;
      memset(&size, 0, sizeof(SIZE));
      GetTextExtentPoint32(grid->Canvas->Handle, text.c_str(), text_len, &size);
      int offset_x = (Rect.Width() - size.cx) >> 1;
      RText.left += offset_x; RText.right += offset_x;

      // rendering
      DrawText(grid->Canvas->Handle, text.c_str(), text_len, &RText, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
   }
}

Some characters have subscript glyph as special unicode character (for example code 0x2081 is assigned to subscript one) but unfortunately this is not case for capital letter U. Also these characters are not supported by all fonts (for example Times New Roman font doesnt support code range 0x2070 – 209F), see this Wikipedia article. I am searching for a more general solution like those implemented by Microsoft Word. MS Word doesn’t have problem to render capital letter U as subscript using Times New Roman font.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-16T19:34:00+00:00Added an answer on June 16, 2026 at 7:34 pm

    If you want some char to render as superscript you must prefix it with ^. Likewise subscript characters must be prefixed with _.

    void __fastcall TForm_Main::StringGrid_DrawCell(TObject *Sender, int ACol, int ARow, TRect &Rect, TGridDrawState State)
    {
       TStringGrid *grid = (TStringGrid*)Sender;
       if (grid == NULL)
       {
          return;
       }
       WideString wtext = L"φ_U = 120";
       if (wtext.IsEmpty()) return;
    
       // layout
       SIZE size;
       memset(&size, 0, sizeof(SIZE));
       SSGetTextExtentPoint(grid->Canvas, wtext, size);
       int offset_x = (Rect.Width() - size.cx + 1) >> 1;  // horizontal centering
       RECT RText = static_cast<RECT>(Rect);
       RText.left += offset_x;
       RText.right += offset_x;
    
       // rendering
       SetBkMode(grid->Canvas->Handle, TRANSPARENT);
       SSDrawText(grid->Canvas, wtext, RText, DT_LEFT);
    }
    
    int TForm_Main::SSGetTextExtentPoint(TCanvas *canvas, WideString text, SIZE &size)
    {
       // Source: http://www.codeproject.com/Articles/12660/Using-Subscripts-and-Superscripts-When-Showing-Tex
       SaveDC(canvas->Handle);
    
       SIZE sz;
       RECT outRect =
       {0, 0, 0, 0};
    
       HFONT oldFont;
    
       LOGFONT lf;
       GetObject(canvas->Font->Handle, sizeof(LOGFONT), &lf);
    
       POINT sub, sup, subofs, supofs;
    
       // Calculate subscript/superscript size and offsets
       bool use_pixel_unit = false;
       if (lf.lfHeight < 0)
       {
          lf.lfHeight    = MulDiv(-lf.lfHeight, 72, GetDeviceCaps(canvas->Handle, LOGPIXELSY));
          use_pixel_unit = true;
       }
       sub.x = lf.lfWidth / 2;
       sup.x = lf.lfWidth / 2;
       sub.y = lf.lfHeight / 3 * 2;
       sup.y = lf.lfHeight / 3 * 2;
    
       subofs.x = lf.lfWidth / 2;
       supofs.x = lf.lfWidth / 2;
       subofs.y = lf.lfHeight / 6;
       supofs.y = lf.lfHeight / 3;
    
       lf.lfWidth  = sub.x;
       lf.lfHeight = sub.y;
       if (use_pixel_unit)
       {
          lf.lfHeight = -MulDiv(lf.lfHeight, GetDeviceCaps(canvas->Handle, LOGPIXELSY), 72);
       }
       HFONT SubFont;
       SubFont = CreateFontIndirect(&lf);
    
       lf.lfWidth  = sup.x;
       lf.lfHeight = sup.y;
       HFONT SupFont;
       if (use_pixel_unit)
       {
          lf.lfHeight = -MulDiv(lf.lfHeight, GetDeviceCaps(canvas->Handle, LOGPIXELSY), 72);
       }
       SupFont = CreateFontIndirect(&lf);
    
       WideString temp = text;
       TCHAR c;
    
       // Calculate the size of the text that needs to be displayed
       do
       {
          int x1       = 1, x2 = 1, x = 1;
          WideString s = "";
          c            = ' ';
          bool bFind   = true;
    
          // Find the first "^" or "_", indicating the sub- or superscript
          while (bFind)
          {
             x1 = text.Pos(L"^");
             x2 = text.Pos(L"_");
             if ((x1 == 0) && (x2 == 0))
             {
                x = 0;
             }
             else if ((x1 > 0) && (x2 > 0))
             {
                x = min(x1, x2);
             }
             else if (x1 > 0)
             {
                x = x1;
             }
             else
             {
                x = x2;
             }
             if (x == 0)
             {
                bFind = false;
                x     = text.Length() + 1;
             }
             else if (x == text.Length())
             {
                bFind = false;
             }
             else if (text[x] != text[x + 1])
             {
                bFind = false;
                c     = text[x];
             }
             else
             {
             x++;
             }
             s = s + text.SubString(1, x - 1);
             text.Delete(1, min(x, text.Length()));
          }
          sz = canvas->TextExtent(s);
          outRect.right += sz.cx;
          if ((outRect.bottom - outRect.top) < sz.cy)
          {
             outRect.top = outRect.bottom - sz.cy;
          }
    
          switch (c)
          {
          case '^':
             oldFont = (HFONT)SelectObject(canvas->Handle, SupFont);
             GetTextExtentPoint32W(canvas->Handle, text.c_bstr(), 1, &sz);
             outRect.right += sz.cx + supofs.x;
             text.Delete(1, 1);
             SelectObject(canvas->Handle, oldFont);
             break;
          case '_':
             oldFont = (HFONT)SelectObject(canvas->Handle, SubFont);
             GetTextExtentPoint32W(canvas->Handle, text.c_bstr(), 1, &sz);
             outRect.right += sz.cx + subofs.x;
             text.Delete(1, 1);
             SelectObject(canvas->Handle, oldFont);
             break;
          }
       }
       while (c != ' ');
    
       // Adjust text position
       outRect.bottom += subofs.y;
       outRect.top -= subofs.x;
    
       size.cx = outRect.right - outRect.left;
       size.cy = outRect.bottom - outRect.top;
    
       DeleteObject(SubFont);
       DeleteObject(SupFont);
       // Done, restoring the device context
       RestoreDC(canvas->Handle, -1);
       return 0;
    }
    
    // ---------------------------------------------------------------------------
    int TForm_Main::SSDrawText(TCanvas *canvas, WideString text, RECT &drawRect, int justification)
    {
       // Source: http://www.codeproject.com/Articles/12660/Using-Subscripts-and-Superscripts-When-Showing-Tex
       SaveDC(canvas->Handle);
    
       SIZE sz;
       RECT outRect =
       {0, 0, 0, 0};
    
       HFONT oldFont;
       LOGFONT lf;
       GetObject(canvas->Font->Handle, sizeof(LOGFONT), &lf);
    
       POINT sub, sup, subofs, supofs;
       bool contains_subscript   = false;
       bool contains_superscript = false;
    
       // Calculate subscript/superscript size and offsets
       bool use_pixel_unit = false;
       if (lf.lfHeight < 0)
       {
          lf.lfHeight    = MulDiv(-lf.lfHeight, 72, GetDeviceCaps(canvas->Handle, LOGPIXELSY));
          use_pixel_unit = true;
       }
    
       sub.x = (lf.lfWidth + 1) >> 1;
       sup.x = (lf.lfWidth + 1) >> 1;
       sub.y = (lf.lfHeight << 1) / 3;
       sup.y = (lf.lfHeight << 1) / 3;
       if (lf.lfHeight == 10)
       {
          sub.y++; // make subscript a little larger
       }
    
       subofs.x = (lf.lfWidth + 1) >> 1;
       supofs.x = (lf.lfWidth + 1) >> 1;
       subofs.y = (lf.lfHeight + 3) / 6;
       supofs.y = (lf.lfHeight) / 3;
    
       long sub_shift_down = lf.lfHeight - sub.y;
    
       lf.lfWidth  = sub.x;
       lf.lfHeight = sub.y;
       if (use_pixel_unit)
       {
          lf.lfHeight = -MulDiv(lf.lfHeight, GetDeviceCaps(canvas->Handle, LOGPIXELSY), 72);
       }
       HFONT SubFont;
       SubFont = CreateFontIndirect(&lf);
    
       lf.lfWidth  = sup.x;
       lf.lfHeight = sup.y;
       if (use_pixel_unit)
       {
          lf.lfHeight = -MulDiv(lf.lfHeight, GetDeviceCaps(canvas->Handle, LOGPIXELSY), 72);
       }
       HFONT SupFont;
       SupFont = CreateFontIndirect(&lf);
    
       WideString temp = text;
       TCHAR c;
    
       // Calculate the size of the text that needs to be displayed
       do
       {
          int x1       = 1, x2 = 1, x = 1;
          WideString s = "";
          c            = ' ';
          bool bFind   = true;
    
          // Find the first "^" or "_", indicating the sub- or superscript
          while (bFind)
          {
             x1 = text.Pos(L"^");
             x2 = text.Pos(L"_");
             if ((x1 == 0) && (x2 == 0))
             {
                x = 0;
             }
             else if ((x1 > 0) && (x2 > 0))
             {
                x = min(x1, x2);
             }
             else if (x1 > 0)
             {
                x = x1;
             }
             else
           {
                x = x2;
             }
             if (x == 0)
             {
                bFind = false;
                x     = text.Length() + 1;
             }
             else if (x == text.Length())
             {
                bFind = false;
             }
             else if (text[x] != text[x + 1])
             {
                bFind = false;
                c     = text[x];
             }
             else
             {
                x++;
             }
             s = s + text.SubString(1, x - 1);
             text.Delete(1, min(x, text.Length()));
          }
          sz = canvas->TextExtent(s);
          outRect.right += sz.cx;
          if ((outRect.bottom - outRect.top) < sz.cy)
          {
             outRect.top = outRect.bottom - sz.cy;
          }
    
          switch (c)
          {
          case '^':
             oldFont = (HFONT)SelectObject(canvas->Handle, SupFont);
             GetTextExtentPoint32W(canvas->Handle, text.c_bstr(), 1, &sz);
             outRect.right += sz.cx + supofs.x;
             text.Delete(1, 1);
             SelectObject(canvas->Handle, oldFont);
             contains_superscript = true;
             break;
          case '_':
             oldFont = (HFONT)SelectObject(canvas->Handle, SubFont);
             GetTextExtentPoint32W(canvas->Handle, text.c_bstr(), 1, &sz);
             outRect.right += sz.cx + subofs.x;
           text.Delete(1, 1);
             SelectObject(canvas->Handle, oldFont);
             contains_subscript = true;
             break;
          }
       }
       while (c != ' ');
    
       // Adjust text position
       if (contains_subscript)
       {
          outRect.bottom += subofs.y;
       }
       if (contains_superscript)
       {
          outRect.top -= supofs.y;
       }
       POINT Origin;
       Origin.y = drawRect.top + (((drawRect.bottom - drawRect.top) - (outRect.bottom - outRect.top) + 1) >> 1);
    
       switch (justification)
       {
       case DT_CENTER:
         Origin.x = (drawRect.right - drawRect.left) / 2 - (outRect.right - outRect.left) / 2 + drawRect.left;
         break;
       case DT_LEFT:
         Origin.x = drawRect.left;
         break;
       case DT_RIGHT:
         Origin.x = drawRect.right - (outRect.right - outRect.left);
       }
    
       POINT pnt = Origin;
    
       text = temp;
    
       // Draw text
       do
       {
          int x1       = 1, x2 = 1, x = 1;
          WideString s = "";
          c            = ' ';
          bool bFind   = true;
    
          // Find the first "^" or "_", indicating the sub- or superscript
         while (bFind)
          {
             x  = text.Pos(L"^_");
             x1 = text.Pos(L"^");
             x2 = text.Pos(L"_");
             if ((x1 == 0) && (x2 == 0))
             {
                x = 0;
             }
             else if ((x1 > 0) && (x2 > 0))
             {
                x = min(x1, x2);
             }
             else if (x1 > 0)
             {
                x = x1;
             }
             else
             {
                x = x2;
             }
             if (x == 0)
             {
                bFind = false;
                x     = text.Length() + 1;
             }
             else if (x == text.Length())
             {
                bFind = false;
             }
             else if (text[x] != text[x + 1])
             {
                bFind = false;
                c     = text[x];
             }
             else
             {
                x++;
             }
             s = s + text.SubString(1, x - 1);
             text.Delete(1, min(x, text.Length()));
          }
          // Draw main text
          ExtTextOutW(canvas->Handle, pnt.x, pnt.y, 0, &drawRect, s.c_bstr(), s.Length(), NULL);
          GetTextExtentPoint32W(canvas->Handle, s.c_bstr(), s.Length(), &sz);
         pnt.x += sz.cx;
    
          // Draw subscript or superscript
          switch (c)
          {
          case '^':
             oldFont = (HFONT)SelectObject(canvas->Handle, SupFont);
             ExtTextOutW(canvas->Handle, pnt.x + supofs.x, pnt.y - supofs.y, 0, &drawRect, text.c_bstr(), 1, NULL);
             GetTextExtentPoint32W(canvas->Handle, text.c_bstr(), 1, &sz);
             pnt.x += sz.cx + supofs.x;
             text.Delete(1, 1);
             SelectObject(canvas->Handle, oldFont);
             break;
          case '_':
             oldFont = (HFONT)SelectObject(canvas->Handle, SubFont);
             ExtTextOutW(canvas->Handle, pnt.x + subofs.x, pnt.y + subofs.y + sub_shift_down, 0, &drawRect, text.c_bstr(), 1, NULL);
             GetTextExtentPoint32W(canvas->Handle, text.c_bstr(), 1, &sz);
             pnt.x += sz.cx + subofs.x;
             text.Delete(1, 1);
             SelectObject(canvas->Handle, oldFont);
             break;
          }
       }
       while (c != ' ');
    
       DeleteObject(SubFont);
       DeleteObject(SupFont);
       // Done, restoring the device context
       RestoreDC(canvas->Handle, -1);
       return 0;
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Following on from my previous question: Simple inner join in linq How would I
Simple question, I would like to append text to the front of every print
Pretty simple Question, unfortunatly never used draw controls etc in C# so im not
I was unsuccessful browsing web for a solution for the following simple question: How
I need your help in following question (using .Net 3.5 and Windows Forms): I
A few days ago I asked the following question: How to draw graphics as
Hey, Like in title can someone answer this simple question? I need draw line
I have a quite simple question I suppose. If I draw a scatter plot
Question simple and quick: I have started to use Netbeans to write some code
Question is simple: I have two List List<String> columnsOld = DBUtils.GetColumns(db, TableName); List<String> columnsNew

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.