| netlib.narod.ru | < Назад | Оглавление | Далее > |
При желании можно настраивать координаты, передаваемые функциям рисования объекта Graphics, через свойства DpiX и DpiY. Допустим, нужно что-то нарисовать в миллиметровых координатах с плавающей точкой. Для этого потребуется метод, преобразующий миллиметры в пикселы:
PointF MMConv(Graphics grfx, PointF pointf)
{
pointf.X *= grfx.DpiX / 25.4f;
pointf.Y *= grfx.DpiY / 25.4f;
return pointf;
}
Метод получает координаты точек, выраженные в миллиметрах. Путем деления на 25,4 эти координаты преобразуются в дюймы (кстати, это точный пересчет). После умножения результата на разрешение устройства (в точках на дюйм) получается число пикселов.
Проверим наши расчеты, нарисовав 10-сантиметровую линейку.
TenCentimeterRuler.cs
//---------------------------------------------------
// TenCentimeterRuler.cs (C) 2001 by Charles Petzold
//---------------------------------------------------
using System;
using System.Drawing;
using System.Windows.Forms;
class TenCentimeterRuler: PrintableForm
{
public new static void Main()
{
Application.Run(new TenCentimeterRuler());
}
public TenCentimeterRuler()
{
Text = "Ten-Centimeter Ruler";
}
protected override void DoPage(Graphics grfx, Color clr, int cx, int cy)
{
Pen pen = new Pen(clr);
Brush brush = new SolidBrush(clr);
const int xOffset = 10;
const int yOffset = 10;
grfx.DrawPolygon(pen, new PointF[]
{
MMConv(grfx, new PointF(xOffset, yOffset)),
MMConv(grfx, new PointF(xOffset + 100, yOffset)),
MMConv(grfx, new PointF(xOffset + 100, yOffset + 10)),
MMConv(grfx, new PointF(xOffset, yOffset + 10))
});
StringFormat strfmt = new StringFormat();
strfmt.Alignment = StringAlignment.Center;
for (int i = 1; i < 100; i++)
{
if (i % 10 == 0) // Сантиметровые деления
{
grfx.DrawLine(pen,
MMConv(grfx, new PointF(xOffset + i, yOffset)),
MMConv(grfx, new PointF(xOffset + i, yOffset + 5)));
grfx.DrawString((i/10).ToString(), Font, brush,
MMConv(grfx, new PointF(xOffset + i, yOffset + 5)),
strfmt);
}
else if (i % 5 == 0) // Полусантиметровые деления
{
grfx.DrawLine(pen,
MMConv(grfx, new PointF(xOffset + i, yOffset)),
MMConv(grfx, new PointF(xOffset + i, yOffset + 3)));
}
else // Миллиметровые деления
{
grfx.DrawLine(pen,
MMConv(grfx, new PointF(xOffset + i, yOffset)),
MMConv(grfx, new PointF(xOffset + i, yOffset + 2.5f)));
}
}
}
PointF MMConv(Graphics grfx, PointF pointf)
{
pointf.X *= grfx.DpiX / 25.4f;
pointf.Y *= grfx.DpiY / 25.4f;
return pointf;
}
}
Вот как выглядит эта линейка на экране:

Кроме рисунка, здесь выводится текст. Почему я был уверен, что размер текста будет правильным? Просто мне было известно, что свойством Font задан шрифт с кеглем около 8 пунктов, высота его символов будет около 3 мм, что примерно соответствует нужному размеру.
Я сделал класс TenCentimeterRuler потомком PrintableForm, чтобы раз и навсегда стало ясно: эта методика не будет работать на принтере. Мой принтер с разрешением 600 dpi печатает эту линейку в шесть раз больше, чем она выглядит на экране.
| netlib.narod.ru | < Назад | Оглавление | Далее > |