BCB プログラム
// .h
inline double __fastcall getY(double pos)
{
// Bitmap 㯠Y ãé転ãããã
return(outlineBitmap->Height - pos);
};
// .cpp
//---------------------------------------------------------------------------
// POINTFX->double åå¤æ
//---------------------------------------------------------------------------
void __fastcall TMainForm::cmnPointfx2double(POINTFX pfx, double* x, double* y)
{
*x = pfx.x.value + pfx.x.fract / 65536;
*y = pfx.y.value + pfx.y.fract / 65536;
}
//---------------------------------------------------------------------------
// outline ç»åãtxt ãã¼ã¿çæ
//---------------------------------------------------------------------------
int __fastcall TMainForm::cmnMakeTxt(void)
{
TxtMemo->Clear();
// TBitmapåæå
if(outlineBitmap == NULL)
{
outlineBitmap = new Graphics::TBitmap;
}
// ãµã¤ãºåæå
outlineBitmap->Width = FontPaintBox->Width;
outlineBitmap->Height = FontPaintBox->Height;
// èæ¯åæå
outlineBitmap->Canvas->Brush->Color = ConfigForm->OutlineBmpBgJvColorComboBox->ColorValue;
outlineBitmap->Canvas->Brush->Style = bsSolid;
outlineBitmap->Canvas->FillRect(ClientRect);
outlineBitmap->Canvas->Brush->Style = bsClear;
// ãã³åæå
outlineBitmap->Canvas->Pen->Color = ConfigForm->OutlineBmpLineJvColorComboBox->ColorValue;
outlineBitmap->Canvas->Pen->Width = ConfigForm->OutlineBmpLineWidthJvEdit->Text.ToInt();
// AnsiString ã C æååå
char* str = (char*)malloc(StringEdit->Text.Length() + 1);
if(str == NULL)
{
cmnShowError();
return(S2N_NG);
}
memset(str, 0x00, StringEdit->Text.Length() + 1);
strncpy(str, StringEdit->Text.c_str(), StringEdit->Text.Length());
char* ptr = str;
baseX = baseY = 0;
// æååçµç«¯ã¾ã§æååä½ã«ã«ã¼ã
while(UINT asciiOfChar = _mbsnextc(ptr))
{
GLYPHMETRICS glyphMetrics;
memset(&glyphMetrics, 0x00, sizeof(GLYPHMETRICS));
MAT2 mat2 = {{0,1}, {0,0}, {0,0}, {0,1}}; // value 㯠1, 0, 0, 1 ã§åºå®
// ãããã¡ãµã¤ãºåå¾
DWORD bufSize = GetGlyphOutline(
fontBitmap->Canvas->Handle, // DCãã³ãã«
asciiOfChar, // 対象æå
GGO_NATIVE, // ãã¯ã¿ã¼æ
å ±ã®åå¾
&glyphMetrics, // åå¾ãã¼ã¿
0, // 0 ã ã¨å¿
è¦ãªãããã¡ãµã¤ãºãè¿ã
NULL, // NULL ã ã¨å¿
è¦ãªãããã¡ãµã¤ãºãè¿ã
&mat2); // å¤æãããªã¯ã¹
if(bufSize == GDI_ERROR)
{
cmnShowError();
return(S2N_NG);
}
char* buf = new BYTE[bufSize];
char* pos = buf;
// ãããã¡åå¾
DWORD rtn = GetGlyphOutline(
fontBitmap->Canvas->Handle, // DCãã³ãã«
asciiOfChar, // 対象æå
GGO_NATIVE, // ãã¯ã¿ã¼æ
å ±ã®åå¾
&glyphMetrics, // åå¾ãã¼ã¿
bufSize, // ãããã¡ãµã¤ãº
(LPVOID)buf, // ãããã¡
&mat2); // å¤æãããªã¯ã¹
if(rtn == GDI_ERROR)
{
cmnShowError();
return(S2N_NG);
}
// ã¢ã¦ãã©ã¤ã³ã®ãããã¼ãåå¾
TTPOLYGONHEADER* header = (TTPOLYGONHEADER*)pos;
if(str == ptr) // æååã®æåãªã
{
baseX = glyphMetrics.gmptGlyphOrigin.x;
baseY = glyphMetrics.gmptGlyphOrigin.y;
}
double x, y, aX, aY, bX, bY, cX, cY;
while(header->dwType == TT_POLYGON_TYPE) // ãããã¿ã¤ã(ç¾ç¶ TT_POLYGON_TYPE åºå®))
{
// ã¢ã¦ãã©ã¤ã³ã®éå§åº§æ¨
cmnPointfx2double(header->pfxStart, &x, &y);
double startX = x;
double startY = y;
outlineBitmap->Canvas->MoveTo(baseX + x, getY(baseY + y));
// ã¢ã¦ãã©ã¤ã³ã®æ¬ä½ãåå¾
pos += sizeof(TTPOLYGONHEADER);
TTPOLYCURVE* curve = (TTPOLYCURVE*)pos;
POINTFX* pfx;
aX = aY = bX = bY = cX = cY = 0;
signed int remainSize = header->cb - sizeof(TTPOLYGONHEADER); // æ®ããµã¤ãº
while(remainSize > 0)
{
// ã«ã¼ãã®éå§åº§æ¨(ã¢ã¦ãã©ã¤ã³ã®éå§åº§æ¨ or ååã®æå¾ã®åº§æ¨)
TxtMemo->Lines->Add(AnsiString(baseX + x) + " " + AnsiString(baseY + y) + " ");
outlineBitmap->Canvas->LineTo(baseX + x, getY(baseY + y));
WORD type = curve->wType;
if((type != TT_PRIM_LINE) && // ç´ç·
(type != TT_PRIM_QSPLINE)) // æ²ç·
{
return(S2N_NG);
}
if((type == TT_PRIM_QSPLINE) && (aX == 0) && (aY == 0))
{
aX = x;
aY = y;
}
WORD num = curve->cpfx;
if(num > 0)
{
pos = (char*)(&(curve->apfx)[0]);
pfx = (POINTFX*)pos;
for(int i = 0; i < num; i++)
{
// ç´ç·ãªã x,y ããã®ã¾ã¾æç»åº§æ¨ã«ãã
if(type == TT_PRIM_LINE)
{
cmnPointfx2double(*pfx, &x, &y);
TxtMemo->Lines->Add(AnsiString(baseX + x) + " " + AnsiString(baseY + y) + " ");
outlineBitmap->Canvas->LineTo(baseX + x, getY(baseY + y));
}
else if(type == TT_PRIM_QSPLINE)
{
if((bX == 0) && (bY == 0))
{
cmnPointfx2double(*pfx, &x, &y);
bX = x;
bY = y;
// b ãåºåããªãã¨æ²ç·è£éãªã
if(ConfigForm->TxtCurve3PointRadioButton->Checked)
{
TxtMemo->Lines->Add(AnsiString(baseX + x) + " " + AnsiString(baseY + y) + " ");
outlineBitmap->Canvas->LineTo(baseX + x, getY(baseY + y));
}
}
else
{
cmnPointfx2double(*pfx, &x, &y);
cX = x;
cY = y;
// æ²ç·ãäºæ¬¡ã¹ãã©ã¤ã³å
if(ConfigForm->TxtCurveSplineRadioButton->Checked)
{
// åå¾ãããæ²ç·ã® 3 ç¹ã«å¯¾ã㦠t (0.0ï½1.0)ãå¤åããã¦å¾ãç¹ã§ãããããã
// x(t) = (xA-2xB+xC)*(t^2) + (2xB-2xA)*t + xA
// y(t) = (yA-2yB+yC)*(t^2) + (2yB-2yA)*t + yA
int splineDivNum = ConfigForm->TxtSplineDivNumJvEdit->Text.ToInt();
for(int i = 0; i < (splineDivNum + 1); i++)
{
double t = (1.0 / splineDivNum) * i;
x = ((aX - (bX * 2) + cX) * pow(t, 2)) + (((bX * 2) - (aX * 2)) * t) + aX;
y = ((aY - (bY * 2) + cY) * pow(t, 2)) + (((bY * 2) - (aY * 2)) * t) + aY;
TxtMemo->Lines->Add(FormatFloat("0.###", x + baseX) + " " + FormatFloat("0.###", baseY + y) + " ");
outlineBitmap->Canvas->LineTo(baseX + x, getY(baseY + y));
}
}
else
{
TxtMemo->Lines->Add(AnsiString(baseX + x) + " " + AnsiString(baseY + y) + " ");
outlineBitmap->Canvas->LineTo(baseX + x, getY(baseY + y));
}
}
}
pos += sizeof(POINTFX);
pfx = (POINTFX*)pos;
}
}
curve = (TTPOLYCURVE*)pos;
remainSize -= (sizeof(TTPOLYCURVE) + (sizeof(POINTFX) * (num - 1)));
aX = aY = bX = bY = cX = cY = 0;
}
// æå¾ã®åº§æ¨ãå§ç¹ã¨ä¸è´ããªããã°ç©å½¢ã®å§ç¹ã«æ»ãç·ãæ¸ã
if((startX != x) || (startY != y))
{
TxtMemo->Lines->Add(AnsiString(baseX + startX) + " " + AnsiString(baseY + startY) + " ");
outlineBitmap->Canvas->LineTo(baseX + startX, getY(baseY + startY));
}
header = (TTPOLYGONHEADER*)pfx;
TxtMemo->Lines->Add("");
}
ptr = _mbsinc(ptr); // 次ã®æåã®åå¾
baseX += glyphMetrics.gmCellIncX;
baseY += glyphMetrics.gmCellIncY;
delete [] buf;
}
delete [] str;
// Canvas ã®ã³ãã¼
OutlinePaintBox->Canvas->CopyRect(
Rect(0, 0, OutlinePaintBox->Width, OutlinePaintBox->Height),
outlineBitmap->Canvas,
Rect(0, 0, outlineBitmap->Width, outlineBitmap->Height));
return(S2N_OK);
}