// 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; };