全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:4163
推到 Plurk!
推到 Facebook!

哪裡有向量字型的技術說明

尚未結案
uu_8
一般會員


發表:2
回覆:0
積分:0
註冊:2002-12-19

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-05-20 15:16:13 IP:203.149.xxx.xxx 未訂閱
哪裡有向量字型的技術說明 , 關於字體的放大與縮小 ?
cmf
尊榮會員


發表:84
回覆:918
積分:1032
註冊:2002-06-26

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-05-20 22:31:29 IP:61.70.xxx.xxx 未訂閱
資料來源: http://www2.ccw.com.cn/2000/0031/0031b12.asp 讀取Windows的 TTF字體輪廓向量資料 西安飛機工業公司設計部 朱朝陽 ---- Windows系統的TTF字體具有字體優美、可無級縮放等優點,最適合應用在CAD類圖形處理等軟體中。直接分析TTF字體的檔格式並讀出每個字的輪廓向量是相當困難的,我們可以借助API函數來方便地獲得這些資料。 ---- 調用函數GetGlyphOutline可以得到一個字的輪廓向量或者點陣圖。 ---- 函數原型如下: DWORD GetGlyphOutline( HDC hdc, // 設備控制碼 UINT uChar, // 將要讀取的字元 UINT uFormat, // 返回資料的格式 LPGLYPHMETRICS lpgm, // GLYPHMETRICS結構位址 DWORD cbBuffer, // 數據緩衝區的大小 LPVOID lpvBuffer, // 資料緩衝區的位址 CONST MAT2 *lpmat2 // 轉置矩陣的地址 ); ---- 其中,參數uFormat取值如下: GGO_NATIVE - 要求函數返回字元的輪廓向量資料; GGO_METRICS - 函數僅返回GLYPHMETRICS結構至lpgm; 參數lpgm指向GLYPHMETRICS結構,該結構描述字元的位置。 參數lpmat2指向字元的轉置矩陣。 ---- 本文以下C++ Builder程式示範如何在畫布上以指定的大小繪製字串。 ---- 首先,建立一個新專案,在主視窗上放置一個Image控制項,一個Edit控制項,一個Button控制項;然後,在Button的點擊事件中加入如下代碼: #include < stdlib.h > void __fastcall TForm1::Button1Click(TObject *Sender) { TRect ClipRect = Rect(0,0,Image1->Width,Image1->Height); Image1->Picture = 0; StretchTextRect(Image1->Canvas, ClipRect, Edit1->Text); } ---- 添加如下子程式: //--------------------- void TForm1::StretchTextRect(TCanvas *pCanvas, TRect ClipRect, AnsiString Text) { pCanvas->Font->Size = 100; 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); } } } //--------------------- TPoint TForm1::POINTFX2TPoint(POINTFX pf, TRect TheRect,GLYPHMETRICS *gm) { TPoint point; float fx,fy; fx = pf.x.value + pf.x.fract / 65536.0f + 0.5f; fx = fx / (float)(gm->gmBlackBoxX + gm->gmptGlyphOrigin.x) * (float)TheRect.Width() + (float)TheRect.Left; fy = pf.y.value + pf.y.fract / 65536.0f + 0.5f; fy = ((float)gm->gmBlackBoxY - fy) / (float)(gm->gmBlackBoxX + gm->gmptGlyphOrigin.x) * (float)TheRect.Height() + (float)TheRect.Top; point.x = int(fx); point.y = int(fy); return point; }
------
︿︿
cmf
尊榮會員


發表:84
回覆:918
積分:1032
註冊:2002-06-26

發送簡訊給我
#3 引用回覆 回覆 發表時間:2003-05-22 15:22:59 IP:61.70.xxx.xxx 未訂閱
<Iframe height=800 width=800 src="http://www.microsoft.com/typography/users.htm"> </iframe>
------
︿︿
系統時間:2024-04-19 8:54:38
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!