Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Звук, графика и видео > Пишу предпросмотра


Автор: кварк 16.11.2004, 12:02
Нужно вывести текст на принтер. И чтобы предпросмотр был. Со скроллингом и зумом. Основная проблема - масштабирование текста. Хотелось бы "как в ворде". Но не особо получается, потому что font.size имеет тип integer и довольно резко скачет при изменении зума.

Единственным выходом вижу создание чего-нибудь а-ля Bitmap с размером в страницу принтера, рисование на нем, предпросмотр через StretchDraw и вывод на принтер через тот же StretchDraw. Так как опыта у меня в этом деле нет, то вопрос: может, есть алгоритм лучше?

Я хочу разобраться в этом вопросе, поэтому особо нужны теоретические размышления.

P.S. нарыл мнение, что для "буфера" надо использовать TMetafile. Но как на нем рисовать - не ясно. и в D6 примера не нашел.


[Допишу, пожалуй]
Пытаюсь применить Metafile в качестве буфера.
Код

var
 mf : TMetafile;
 mfc: TMetafileCanvas;
begin
 mf := TMetafile.Create;
 mf.Height := 500;
 mf. Width := 500;
 mfc := TMetafileCanvas.Create(mf, 0);
 mfc.Ellipse(mfc.ClipRect);

 // ???

 mfc.Free;
 mf.Free;
end;


Вместо вопросов надо вставить код, отрисовывающий содержимое метафайла на канве (ну, например, Form1). Никак не могу этого сделать.

Автор: Kesh 16.11.2004, 21:07
А почему не на Bitmap рисовать?

Автор: p0s0l 16.11.2004, 21:58
TMetaFileCanvas передаёт рисунок метафайлу при разрушении.
Поэтому, прежде чем выводить метафайл, надо уничтожить метаканвас...
Код
var
 mfc: TMetafileCanvas;
begin
 mf := TMetafile.Create;
 mf.Height := 500;
 mf. Width := 500;
 mfc := TMetafileCanvas.Create(mf, 0);
 mfc.Ellipse(mfc.ClipRect);

 mfc.Free;

 Image1.Canvas.Draw (0, 0, mf);

 mf.Free;
end;

Автор: кварк 17.11.2004, 10:12
Цитата
А почему не на Bitmap рисовать?

Полагаю, что Bitmap размером со страницу на принтере немало памяти отъест. А если страниц будет штук 50? (но пока я об этом не думаю - главное с одной разобраться, а там проще будет)
А может, подумаю над алгоритмом рендеринга, где создается Bitmap, на него выводится содержимое страницы, потом оно отправляется либо на предпросмотр, либо на принтер, потом Bitmap очищается и на нем рисуется следующая следующая страница (по-моему, в Ворде так и сделано).

Цитата
TMetaFileCanvas передаёт рисунок метафайлу при разрушении.
Поэтому, прежде чем выводить метафайл, надо уничтожить метаканвас...


Да. Я нашел пример. Но вот незадача: код
Код

// b2 - TButton
// img - TImage на форме, куда я вывожу изображение
// mf - TMetafile

procedure TForm1.b2Click(Sender: TObject);
begin
 b2.Enabled := false;
 try
   mf := TMetafile.Create;
   mf.Width  := Printer.PageWidth;
   mf.Height := Printer.PageHeight;

   with TMetafileCanvas.Create(mf, 0) do
   try
      Ellipse(ClipRect);
   finally
     Free;
   end;

   Canvas.Rectangle(img.BoundsRect);  // (*1)
   Canvas.StretchDraw(img.BoundsRect, mf);  //(*2)
 finally
   mf.Free;
   b2.Enabled := true;
 end;
end;

выводит прямоугольник (*1) четко по краям img, а вот эллипс (*2) получается какой-то маленький в левом верхнем углу. Я ожидал, что эллипс будет точно вписан в прямоугольник. Что не так?


Автор: p0s0l 17.11.2004, 18:44
Дело в том, что в TMetafileCanvas.Create во втором параметре указывается контекст устройства, на котором предполагается выводить картинку...
Ты указываешь 0 - это значит текущий экран, например, разрешением 1024x768...
А в mf.Width и mf.Height указываешь разрешение канваса принтера...
Например, будет 2500x2000 к примеру...
Поэтому Ellipse (Cliprect) рисуется не на всём метафайле, а только на левой-верхней четверти...

Блин, принтера нет, чтобы проверить... Но предполагаю, что заменив второй параметр в создании метаканваса (0) на Printer.Canvas.Handle проблема уйдёт:
Код
with TMetafileCanvas.Create(mf, Printer.Canvas.Handle) do

Автор: кварк 26.1.2005, 12:42
Подниму свою старую тему... Продолжаю дописывать компонент. Столкнулся с проблемой масштабирования текста. Как бы так сделать, чтобы текст (или отдельный символ - неважно) точно вписывался в заданный прямоугольник (как, например, это сделано в редакторе Macromedia Flash)? Просто если менять Font.Size, то получается топорно.

Может, в WinApi есть функции для этого?

Пока реализовал то, что первым пришло на ум, но это медленно работает.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)