打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
VC输出上小标

Introduction

Recently I have been searching The Code Project on how to show subscripts and superscripts in the device context (when using TextOut or ExtTextOut functions). But I could not find anything. So finally I decided to write the function myself.

Features and How To Use

My function SSTextOut has similar functionality to ExtTextOut. You need to specify the pointer to the device context, the pointer to bounding rectangle, the string itself, and the justification mode.

The string should contain special formatting codes - ^ for superscript and _ for subscript. The next symbol after ^ or _ will be shown as subscript or superscript. If you need to show ^ or _ themselves - just type them twice - ^^ or __.

Justification can be DT_CENTER, DT_LEFT, or DT_RIGHT. It affects only horizontal justification. Vertically, the text will be centered in the bounding rectangle automatically. The text outside the rectangle is clipped. The function uses the current font of the specified device context.

So, to draw the meaningless text in the image above, you need to call:

Hide   Copy Code
SSTextOut(pDC,"ms^2/Hz+H_2O-mc^^2__4",&rect,DT_CENTER);

Source Code

The source code of SSTextOut is shown below:

Hide   Shrink
  Copy Code
void SSTextOut(CDC* pDC, CString data , CRect* drawRect, int justification){ //Necessary initializations pDC->SaveDC();  CSize sz; CRect outRect(0,0,0,0); CFont* pFont = pDC->GetCurrentFont(); CFont* oldFont; pDC->SetTextAlign(TA_BOTTOM|TA_LEFT); LOGFONT lf; pFont->GetLogFont(&lf); CPoint sub,sup,subofs,supofs; // Calculate subscript/superscript size and offsets 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; CFont SubFont; SubFont.CreateFontIndirect(&lf);  lf.lfWidth=sup.x; lf.lfHeight=sup.y; CFont SupFont; SupFont.CreateFontIndirect(&lf);  CString temp = data; TCHAR c;  // Calculate the size of the text that needs to be displayed do {  int x=0;  CString s = "";  c=' ';  bool bFind=true;  // Find the first "^" or "_", indicating the sub- or superscript  while (bFind)  {   x=data.FindOneOf("^_");   if (x==-1)    {    bFind=false;    x=data.GetLength();   }   else if (x==data.GetLength()-1) bFind=false;   else if (data[x]!=data[x+1])    {    bFind=false;     c=data[x];   }   else x++;   s=s+data.Left(x);   data.Delete(0,min(x+1,data.GetLength()));  }  sz = pDC->GetTextExtent(s);  outRect.right+=sz.cx;  if (outRect.Height()<sz.cy) outRect.top=outRect.bottom-sz.cy;    switch (c)   {  case '^':   oldFont = pDC->SelectObject(&SupFont);   sz = pDC->GetTextExtent(data[0]);   outRect.right+=sz.cx+supofs.x;   data.Delete(0);   pDC->SelectObject(oldFont);   break;  case '_':   oldFont = pDC->SelectObject(&SubFont);   sz = pDC->GetTextExtent(data[0]);   outRect.right+=sz.cx+subofs.x;   data.Delete(0);   pDC->SelectObject(oldFont);   break;  } } while (c!=' ');  // Adjust text position outRect.bottom+=2*subofs.y; outRect.top-=2*subofs.x; CPoint Origin; Origin.y = drawRect->Height()/2+outRect.Height()/2+drawRect->top; switch (justification) { case DT_CENTER:  Origin.x = drawRect->Width()/2-outRect.Width()/2+drawRect->left;  break; case DT_LEFT:  Origin.x = drawRect->left;  break; case DT_RIGHT:  Origin.x = drawRect->right-outRect.Width(); } CPoint pnt = Origin; data = temp; // Draw text do {  int x=0;  CString s = "";  c=' ';  bool bFind=true;  // Find the first "^" or "_", indicating the sub- or superscript  while (bFind)  {   x=data.FindOneOf("^_");   if (x==-1)    {    bFind=false;    x=data.GetLength();   }   else if (x==data.GetLength()-1) bFind=false;   else if (data[x]!=data[x+1])    {    bFind=false;     c=data[x];   }   else x++;   s=s+data.Left(x);   data.Delete(0,min(x+1,data.GetLength()));  }  // Draw main text  pDC->ExtTextOut(pnt.x,pnt.y,ETO_CLIPPED,drawRect,s,NULL);  sz = pDC->GetTextExtent(s);  pnt.x+=sz.cx;    // Draw subscript or superscript  switch (c)   {  case '^':   oldFont = pDC->SelectObject(&SupFont);   pDC->ExtTextOut(pnt.x+supofs.x,pnt.y-supofs.y,ETO_CLIPPED,drawRect,data[0],NULL);   sz = pDC->GetTextExtent(data[0]);   pnt.x+=sz.cx+supofs.x;   data.Delete(0);   pDC->SelectObject(oldFont);   break;  case '_':   oldFont = pDC->SelectObject(&SubFont);   pDC->ExtTextOut(pnt.x+subofs.x,pnt.y+subofs.y,ETO_CLIPPED,drawRect,data[0],NULL);   sz = pDC->GetTextExtent(data[0]);   pnt.x+=sz.cx+supofs.x;   data.Delete(0);   pDC->SelectObject(oldFont);   break;  } } while (c!=' '); // Done, restoring the device context pDC->RestoreDC(-1);}
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
字体设置
一个类似VS2010中的CMemDC类,VC6中用
VC图片的半透明处理
Delphi Knowledge Base: How to write on a canvas with a rotated font
$信立泰(SZ002294)$ PDC技术平台。PDC(peptide
改变控件字体大小
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服