OS XP VC++6.0 MFC使用
以下のようにExtCreatePenで一点鎖線の線種の論理ペンを生成し、印刷したのですが、
プリンタの解像度によっては、期待した長さのピッチの線種になりません。
だれか詳しい方、教えてください。
ちなみに、PDFで出力して解像度を変更したりしてテストしています。
50mm幅の線の中に12mm(線),1.5mm(空白),3.5mm(線),1.5mm(空白)の線種になるので、
------- - ---------- - ----------- ← こうなるはず、
実際は
------ - --------- - ---------- -- ← 線幅が指定した通りにならない
CPrintDialog dlg(FALSE);
if (dlg.DoModal() == IDCANCEL)
{
return;
}
HDC hdc = dlg.GetPrinterDC();
CDC dcPrn;
dcPrn.Attach(hdc);
DOCINFO di;
::ZeroMemory(&di, sizeof(DOCINFO));
di.cbSize = sizeof(DOCINFO);
di.lpszDocName = _T(TEST);
StartDoc(hdc, &di);
StartPage(hdc);
::SetMapMode(hdc, MM_HIMETRIC);
int nVert = dcPrn.GetDeviceCaps(VERTRES);
::SetViewportOrgEx(hdc, 0, nVert, NULL);
DWORD Style[4];
Style[0] = 1200;
Style[1] = 150;
Style[2] = 350;
Style[3] = 150;
// LOGBRUSH構造体の設定
LOGBRUSH logbrush;
logbrush.lbStyle = BS_SOLID;
logbrush.lbColor = RGB(0, 0, 0);
logbrush.lbHatch = 0;
// ペンの生成
CPen* pPen = new CPen;
pPen->CreatePen(PS_GEOMETRIC | PS_USERSTYLE, 13, &logbrush, 4, Style);
CPen* pOldPen = dcPrn.SelectObject(pPen);
dcPrn.MoveTo(1000, 1000);
dcPrn.LineTo(6000, 1000);
EndPage(hdc);
EndDoc(hdc);
dcPrn.SelectObject(pOldPen);
delete pPen;
dcPrn.Detach();
マッピングモードはMM_HIMETRICにしているので、同じように印刷されると思っているの
ですが、、。
やはり、解像度による誤差なのでしょうか?回避策などありますでしょうか?
過去の記憶なので自信がないですが。
> DWORD Style[4];
> Style[0] = 1200;
> Style[1] = 150;
> Style[2] = 350;
> Style[3] = 150;
これらの指定ってLP単位系のはずなので、CDC::HIMETRICtoLP()を使って
変換した値を使用しないと正確に印刷されないような気がします。
HIMETRICtoLP, LPtoHIMETRIC、あたりでググると詳細な資料が出てくると
思います。
(変換座標系関数 XxxExt, XxxOrgのリセット是非については注意してください)
こちらの過去ログにも該当するスレッドがあったので追加です。
>> 文字サイズと用紙サイズ
> http://rararahp.cool.ne.jp/cgi-bin/lng/vc/vclng.cgi?print+200303/03030061.txt
文字系でのスレッドですが、何かしらの参考になるかと思います。
ありがとうございます。
教えて頂いたようにHIMETRICtoLPを使用して変換した値で、ExtCreatePenを
使ったのですが、結果は同じでした。
(ちなみに、幅とMoveTo,LineToの座標値も変換しました。)
何か他に原因があるのでしょうか?
DWORD Style[4];
Style[0] = 1200;
Style[1] = 150;
Style[2] = 350;
Style[3] = 150;
for (int i = 0; i < 4; i++)
{
CSize szSize(Style[i], Style[i]);
dcPrn.HIMETRICtoLP(&szSize);
Style[i] = szSize.cx;
}
過去のプログラムを掘り漁ったらHIMETRICtoLP()を使ってませんでした(汗
> ::SetMapMode(hdc, MM_HIMETRIC);
> int nVert = dcPrn.GetDeviceCaps(VERTRES);
> ::SetViewportOrgEx(hdc, 0, nVert, NULL);
この部分を以下のように書き換えるとどうでしょうか?
(私の環境からPDF, 印刷で確認しましたが問題なさそうでした)
---
::SetMapMode(hdc, MM_HIMETRIC);
::SetMapMode(hdc, MM_ANISOTROPIC);
::ScaleWindowExtEx(hdc, 1, 1, 1, -1, NULL);
---
確か、Microsoftの技術文章で公開されてたと思うのですが、HIMETRICでスケーリング
した後に、Y座標系を反転(HMETRICは上が正座標なので)している、ハズです。
# スケーリングは冷静にならないとハマるなぁ・・・
玲音 (st.lain) さん、どうもありがとうございました。
ご教授頂いた方法で、やってみたのですが、
PDF印刷等で、300DPIで印刷した場合と600DPIで印刷した場合で、
線の出力のされ方が違ってしまうので、困っています。
50mm幅の線の中に12mm(線),1.5mm(空白),3.5mm(線),1.5mm(空白)の線種
なので、600DPIの出力が正しい(一点鎖線が2回分になる)と思いますが、
300DPIでは最後に中途半端な線(点)が出力されてしまいます。
やはり、これはDPIによる誤差か何かでしょうか?それとも何か他に解決策が
ありますでしょうか?すいませんが、もし知っていたら教えてください。
Canon MP610で試してみたところ、最初のコードでどの解像度でも
(300dpi/600dpi)正しい長さで印刷されました。
Acrobat Distiller 5.0で試すと、おっしゃる通り300dpi以下で
結果が変わります。
プリンタドライバの問題かもしれませんね。
フリーの仮想プリンタに300, 600, 1200, 4000とまわしてみました。
中度半端な破線が出現することはありませんでしたが、左端合わせてある
拡大したキャプチャを並べましたが、びみょ~な差異があるようです。
Windowsのプリンタ周りの保証精度について知りませんが(それともドライバ側に
その任があるのかも知りません)、環境に依存する線が強そうですね。
# LP, DP間の内部的な座標変換による誤差かと思ったのですが、Kerryさんの
# 結果を見る限りその線は薄そうですね。
# 調べたことはないですが、同じ300dpiでもGetDeviceCaps()辺りで値を調べると
# 違いでもでるのカナ、と勘ぐってみたり。
みなさん、どうもありがとうございました。
プリンタドライバに依存するところもあるようですね。
画面で表示できてたので、印刷もそんなに苦労しないと思ってましたが、
結構、奥が深いですね。どんなプリンタでも同じように印刷できるのが、
理想ですけれど、なかなか難しいというのがよくわかりました。