首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ Builder >

TrueType文字显示,该如何解决

2012-03-23 
TrueType文字显示 - C++ Builder / Windows SDK/API下面的代码我想大家都见过 是读取TrueType字体结构的代

TrueType文字显示 - C++ Builder / Windows SDK/API
下面的代码我想大家都见过 是读取TrueType字体结构的代码,我现在用他读取的轮廓感觉比较粗糙,锯齿多,不够圆滑,请问有什么方法可以修正 或者有更好的算法,请赐教,谢谢

  pCanvas->Font->Size =80;
  pCanvas->Font->Name="宋体";
  pCanvas->Pen->Color = clBlack;
  pCanvas->Pen->Mode = pmCopy;
  pCanvas->Pen->Style = psSolid;
  pCanvas->Pen->Width = 1;
  int XSize = ClipRect.Width() / Text.Length();
  int YSize = ClipRect.Height();

  MAT2 mat2; // 转置矩阵,不用变换
  mat2.eM11.value = 1;mat2.eM11.fract = 0;
  mat2.eM12.value = 0;mat2.eM12.fract = 0;
  mat2.eM21.value = 0;mat2.eM21.fract = 0;
  mat2.eM22.value = 1;mat2.eM22.fract = 0;

  GLYPHMETRICS gm,gmm;

  // 首先获得字符的位置矩阵,存入gm
  GetGlyphOutlineA(pCanvas->Handle,0x0b0a1,
  GGO_METRICS,&gm,0,NULL,&mat2);

  char *ptr = Text.c_str();
  TRect TheRect;
  for(int i = 0;i < Text.Length();) {
  int c1 = (unsigned char)*ptr;
  int c2 = (unsigned char)*(ptr + 1);
  UINT nChar;
  TheRect.Left = i * XSize + ClipRect.Left;
  TheRect.Top = ClipRect.Top;
  TheRect.Right = (i + 2) * XSize + ClipRect.Left;
  TheRect.Bottom = ClipRect.Top + YSize;
  if(c1 > 127) { // 当前字符是汉字
  nChar = c1 * 256 + c2;
  ptr+=2;i+=2;
  }
  else { // 字母或数字
  nChar = c1;
  ptr++;i++;
  }
  // 获得当前字符数据的数组的大小
 DWORD cbBuffer = GetGlyphOutlineA(pCanvas->
Handle,nChar,GGO_NATIVE,&gmm,0,NULL,&mat2);
  if(cbBuffer == GDI_ERROR) break;
  void *lpBuffer = malloc(cbBuffer);
  if(lpBuffer != NULL) {
  // 读入数据置缓冲区
  if(GetGlyphOutlineA(pCanvas->
  Handle,nChar,GGO_NATIVE,
  &gmm,cbBuffer,lpBuffer,&mat2) != GDI_ERROR) {
 // 分析数据并绘制字符
  TMemoryStream *MBuffer = new TMemoryStream();
  MBuffer->Write(lpBuffer,cbBuffer);
  MBuffer->Position = 0;
  for(;MBuffer->Position < MBuffer->Size;) {
  int CurPos = MBuffer->Position;
  TTPOLYGONHEADER polyheader;

  int ptn = 0;
  MBuffer->Read(&polyheader,sizeof(polyheader));
  ptn++;
for(int j = 0;j < (int)(polyheader.cb 
 - sizeof(polyheader));) {
  WORD wtype,cpfx;
  MBuffer->Read(&wtype,sizeof(WORD));
  MBuffer->Read(&cpfx,sizeof(WORD));
  MBuffer->Position += cpfx * sizeof(POINTFX);
  j += sizeof(WORD) * 2 + cpfx * sizeof(POINTFX);
  if(wtype == TT_PRIM_LINE) ptn += cpfx;
  else ptn += (cpfx - 1) * 3 + 1;
  }

  TPoint *pts = new TPoint[ptn+1]; // 存储多边形顶点
  MBuffer->Position = CurPos;
  ptn = 0;
  MBuffer->Read(&polyheader,sizeof(polyheader));
 TPoint pt0 = POINTFX2TPoint(polyheader.pfxStart,TheRect,&gm);
  pts[ptn++] = pt0;
  for(int j = 0;j < (int)(polyheader.cb - sizeof(polyheader));) {
  TPoint pt1;
  WORD wtype,cpfx;
  MBuffer->Read(&wtype,sizeof(WORD));
  MBuffer->Read(&cpfx,sizeof(WORD));
  POINTFX *pPfx = new POINTFX[cpfx];
  MBuffer->Read((void *)pPfx,cpfx * sizeof(POINTFX));
  j += sizeof(WORD) * 2 + cpfx * sizeof(POINTFX);
  if(wtype == TT_PRIM_LINE) { // 直线段
  for(int i = 0;i < cpfx;i++) {
  pt1 = POINTFX2TPoint(pPfx[i],TheRect,&gm);
  pts[ptn++] = pt1;
  }
  }
  else { // Bezier曲线


  TPoint p0,p1,p2,p3,p11,p22,pp0,pp1,pp2,pt11,pt22;
  int i;
  for(i = 0;i < cpfx-1;i++) {
  pt11 = POINTFX2TPoint(pPfx[i],TheRect,&gm);
  pt22 = POINTFX2TPoint(pPfx[i+1],TheRect,&gm);
  pp0 = pts[ptn-1];
  pp1 = pt11;
  pp2.x = (pt11.x + pt22.x)/2;
  pp2.y = (pt11.y + pt22.y)/2;

  p0 = pp0;
  p1.x = pp0.x/3 + 2 * pp1.x/3;
  p1.y = pp0.y/3 + 2 * pp1.y/3;
  p2.x = 2 * pp1.x/3 + pp2.x/3;
  p2.y = 2 * pp1.y/3 + pp2.y/3;
  p3 = pp2;

  for(float t = 0.0f;t <= 1.0f;t += 0.5f) {
float x = (1-t)*(1-t)*(1-t)*p0.x+ 
3*t*(1-t)*(1-t)*p1.x+ 3*t*t
*(1-t)*p2.x + t*t*t*p3.x;
float y = (1-t)*(1-t)*(1-t)*p0.y
+ 3*t*(1-t)*(1-t)*p1.y+3
*t*t*(1-t)*p2.y + t*t*t*p3.y;
  pts[ptn].x = x;
  pts[ptn].y = y;
  ptn++;
  }
  }
  pt1 = POINTFX2TPoint(pPfx[i],TheRect,&gm);
  pts[ptn++] = pt1;
  }
  delete pPfx;
  }
  pts[ptn] = pts[0]; // 封闭多边形
  pCanvas->Brush->Color = clWhite;
  pCanvas->Pen->Mode = pmXor;
  pCanvas->Pen->Style = psClear;
  pCanvas->Brush->Style = bsSolid;
  pCanvas->Polygon(pts,ptn);

  delete pts;
  }
  delete MBuffer;
  }
  free(lpBuffer);
  }

[解决办法]
不懂,帮顶,学习
[解决办法]
还是用GDI+吧
[解决办法]
网上流传的这段读取TrueType字体并显示的代码,显示出来确实有锯齿。我曾试验过。效果不是很理想。
[解决办法]
我来做广告啦,楼主可以考虑用AGG来取出轮廓填充,看这里http://www.cppprog.com/2009/0901/154_2.html

热点排行