Initial commit: OtozaiPrinter (AveryDennisonUtil) ラベル/レシート レイアウト設計・印刷 MFC アプリ
- 用紙設計キャンバス(1/100mm 基準)・テキスト/画像/矩形/直線アイテム - コピー/複製/Zオーダー/整列/グリッドスナップ、原紙(下絵)読込と印刷可否 - GDI 直接印刷、.otz 保存/再読込(版数つき) - MFC/CRT 静的リンクで VS2022 IDE から F5 デバッグ可
This commit is contained in:
+101
@@ -0,0 +1,101 @@
|
||||
// RenderScene.cpp
|
||||
#include "pch.h"
|
||||
#include "RenderScene.h"
|
||||
#include "LabelLayout.h"
|
||||
#include "PrintItem.h"
|
||||
#include "ImageItem.h"
|
||||
|
||||
#pragma comment(lib, "msimg32.lib") // CDC::AlphaBlend(原紙の薄表示)
|
||||
|
||||
// レイアウト1枚分を dc に描画する。画面エディタと印刷の共通描画パス。
|
||||
// 描画順は 用紙白地(画面のみ)→ 原紙 → グリッド/余白ガイド(画面のみ)→ 各アイテム。
|
||||
// screen=true : 画面用。用紙の白地・グリッド・余白ガイド・選択枠を描く。原紙は薄く表示。
|
||||
// screen=false: 印刷用。原紙は m_printTemplate のときだけ・等倍・薄表示なしで描く。
|
||||
// map がDPI/ズーム/原点を吸収するので、同じコードで解像度差を正しく出力できる。
|
||||
void Render::DrawLayout(CDC& dc, const CLabelLayout& layout, const CoordMap& map,
|
||||
bool screen, const CPrintItem* selected, int gridHu)
|
||||
{
|
||||
CRect paper(0, 0, layout.m_paperWidthHu, layout.m_paperHeightHu);
|
||||
CRect paperDev = map.MmToDev(paper);
|
||||
|
||||
if (screen)
|
||||
{
|
||||
CBrush white(RGB(255, 255, 255));
|
||||
dc.FillRect(paperDev, &white);
|
||||
}
|
||||
|
||||
// 原紙(背景下絵): 全アイテムの背面。画面では常に・印刷は許可時のみ。
|
||||
CImageItem* tpl = layout.Template();
|
||||
if (tpl && (screen || layout.m_printTemplate))
|
||||
{
|
||||
tpl->SetRect(paper); // 常に用紙全体へ
|
||||
tpl->Draw(dc, map, /*selected=*/false);
|
||||
|
||||
if (screen && paperDev.Width() > 0 && paperDev.Height() > 0)
|
||||
{
|
||||
// 画面では原紙を薄く被せ、上に載るアイテムを見やすくする
|
||||
CDC tmp;
|
||||
tmp.CreateCompatibleDC(&dc);
|
||||
CBitmap wb;
|
||||
wb.CreateCompatibleBitmap(&dc, 1, 1);
|
||||
CBitmap* pOldB = tmp.SelectObject(&wb);
|
||||
tmp.SetPixelV(0, 0, RGB(255, 255, 255));
|
||||
BLENDFUNCTION bf = { AC_SRC_OVER, 0, 110, 0 }; // 白を約43%重ねる
|
||||
dc.AlphaBlend(paperDev.left, paperDev.top, paperDev.Width(), paperDev.Height(),
|
||||
&tmp, 0, 0, 1, 1, bf);
|
||||
tmp.SelectObject(pOldB);
|
||||
}
|
||||
}
|
||||
|
||||
if (screen)
|
||||
{
|
||||
|
||||
// グリッド(アイテムの下・用紙内)。デバイス間隔が細かすぎる時は描かない。
|
||||
if (gridHu > 0 && map.LenToDevX(gridHu) >= 5)
|
||||
{
|
||||
CPen grid(PS_SOLID, 1, RGB(225, 225, 225));
|
||||
CPen* pOldG = dc.SelectObject(&grid);
|
||||
for (int x = gridHu; x < layout.m_paperWidthHu; x += gridHu)
|
||||
{
|
||||
int dx = map.MmToDevX(x);
|
||||
dc.MoveTo(dx, paperDev.top);
|
||||
dc.LineTo(dx, paperDev.bottom);
|
||||
}
|
||||
for (int y = gridHu; y < layout.m_paperHeightHu; y += gridHu)
|
||||
{
|
||||
int dy = map.MmToDevY(y);
|
||||
dc.MoveTo(paperDev.left, dy);
|
||||
dc.LineTo(paperDev.right, dy);
|
||||
}
|
||||
dc.SelectObject(pOldG);
|
||||
}
|
||||
|
||||
// 余白ガイド(破線)
|
||||
if (layout.m_marginHu > 0)
|
||||
{
|
||||
CRect mdev = map.MmToDev(layout.ContentRect());
|
||||
int oldBk = dc.SetBkMode(TRANSPARENT);
|
||||
CPen mpen(PS_DOT, 1, RGB(150, 150, 200));
|
||||
CPen* pOldM = dc.SelectObject(&mpen);
|
||||
CBrush* pOldMB = (CBrush*)dc.SelectStockObject(NULL_BRUSH);
|
||||
dc.Rectangle(mdev);
|
||||
dc.SelectObject(pOldMB);
|
||||
dc.SelectObject(pOldM);
|
||||
dc.SetBkMode(oldBk);
|
||||
}
|
||||
|
||||
CPen edge(PS_SOLID, 1, RGB(120, 120, 120));
|
||||
CPen* pOld = dc.SelectObject(&edge);
|
||||
CBrush* pOldBrush = (CBrush*)dc.SelectStockObject(NULL_BRUSH);
|
||||
dc.Rectangle(paperDev);
|
||||
dc.SelectObject(pOldBrush);
|
||||
dc.SelectObject(pOld);
|
||||
}
|
||||
|
||||
for (int i = 0; i < layout.GetItemCount(); ++i)
|
||||
{
|
||||
CPrintItem* p = layout.GetItem(i);
|
||||
bool sel = screen && (p == selected);
|
||||
p->Draw(dc, map, sel);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user