Files
AveryDennisonUtil/CoordMap.h
T
yoshikazu 19d1c39370 Initial commit: OtozaiPrinter (AveryDennisonUtil) ラベル/レシート レイアウト設計・印刷 MFC アプリ
- 用紙設計キャンバス(1/100mm 基準)・テキスト/画像/矩形/直線アイテム
- コピー/複製/Zオーダー/整列/グリッドスナップ、原紙(下絵)読込と印刷可否
- GDI 直接印刷、.otz 保存/再読込(版数つき)
- MFC/CRT 静的リンクで VS2022 IDE から F5 デバッグ可
2026-06-05 17:27:29 +09:00

80 lines
3.2 KiB
C++

// CoordMap.h : 物理単位(1/100mm) ⇔ デバイス単位(ピクセル) 変換
//
// 設計の背骨:
// - すべてのジオメトリ(用紙サイズ・各アイテムの矩形)は 1/100 mm の整数で保持する。
// - 画面エディタも印刷(OnPrint)も「同じ」描画コード Draw(CDC&, CoordMap&) を呼ぶ。
// 違いはこの CoordMap が保持する DPI とズーム倍率だけ。
// - これにより、画面(≒96dpi)とサーマルラベルプリンタ(≒203dpi)で
// 同一レイアウトが物理的に正しいサイズで出力される。
//
// 単位系メモ: 1 inch = 25.4 mm = 2540 (1/100mm)
#pragma once
class CoordMap
{
public:
// dpiX/dpiY : 出力デバイスの解像度(GetDeviceCaps(LOGPIXELSX/Y))
// zoom : 画面表示倍率(印刷時は 1.0)
// originDevX/Y : デバイス座標の原点オフセット(スクロール量や印刷可能領域オフセット)
CoordMap(int dpiX = 96, int dpiY = 96, double zoom = 1.0,
int originDevX = 0, int originDevY = 0)
: m_dpiX(dpiX), m_dpiY(dpiY), m_zoom(zoom),
m_originX(originDevX), m_originY(originDevY)
{
}
void SetZoom(double zoom) { m_zoom = zoom; }
double Zoom() const { return m_zoom; }
void SetOrigin(int devX, int devY) { m_originX = devX; m_originY = devY; }
// 1/100mm → デバイス(ピクセル)。原点オフセットとズームを適用。
int MmToDevX(int hu) const { return m_originX + ScaleX(hu); }
int MmToDevY(int hu) const { return m_originY + ScaleY(hu); }
// 寸法(長さ)変換: 原点オフセットを加えない
int LenToDevX(int hu) const { return ScaleX(hu); }
int LenToDevY(int hu) const { return ScaleY(hu); }
CRect MmToDev(const CRect& huRect) const
{
return CRect(MmToDevX(huRect.left), MmToDevY(huRect.top),
MmToDevX(huRect.right), MmToDevY(huRect.bottom));
}
CPoint MmToDev(const CPoint& huPt) const
{
return CPoint(MmToDevX(huPt.x), MmToDevY(huPt.y));
}
// デバイス(ピクセル) → 1/100mm
int DevToMmX(int dev) const { return UnscaleX(dev - m_originX); }
int DevToMmY(int dev) const { return UnscaleY(dev - m_originY); }
CPoint DevToMm(const CPoint& devPt) const
{
return CPoint(DevToMmX(devPt.x), DevToMmY(devPt.y));
}
// ポイント(1pt = 1/72inch) → デバイス上のフォント高さ(論理ピクセル, ズーム込み)
int PointToDevHeight(double pt) const
{
// pt → 1/100mm → デバイス
int hu = (int)(pt * 2540.0 / 72.0 + 0.5);
return LenToDevY(hu);
}
private:
// hu(1/100mm) → デバイス: dev = hu / 2540 * dpi * zoom
int ScaleX(int hu) const { return (int)((double)hu * m_dpiX * m_zoom / 2540.0 + (hu >= 0 ? 0.5 : -0.5)); }
int ScaleY(int hu) const { return (int)((double)hu * m_dpiY * m_zoom / 2540.0 + (hu >= 0 ? 0.5 : -0.5)); }
int UnscaleX(int dev) const { return (int)((double)dev * 2540.0 / (m_dpiX * m_zoom) + (dev >= 0 ? 0.5 : -0.5)); }
int UnscaleY(int dev) const { return (int)((double)dev * 2540.0 / (m_dpiY * m_zoom) + (dev >= 0 ? 0.5 : -0.5)); }
int m_dpiX;
int m_dpiY;
double m_zoom;
int m_originX;
int m_originY;
};