- 用紙設計キャンバス(1/100mm 基準)・テキスト/画像/矩形/直線アイテム - コピー/複製/Zオーダー/整列/グリッドスナップ、原紙(下絵)読込と印刷可否 - GDI 直接印刷、.otz 保存/再読込(版数つき) - MFC/CRT 静的リンクで VS2022 IDE から F5 デバッグ可
102 lines
3.9 KiB
C++
102 lines
3.9 KiB
C++
// 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);
|
|
}
|
|
}
|