Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2008.08.24;
Скачать: [xml.tar.bz2];

Вниз

Вывод текста через Canvas.TextOut   Найти похожие ветки 

 
Lines   (2008-07-18 18:11) [0]

Существует светодиодная панель, имеющая некоторое разрешение, на этой панели соответственно можно зажигать или гасить определенные светодиоды. Например, в транспорте светодиодные бегущие строки с названиями остановок и прочее.
Но в данном случае панель управляется компьютером, есть задача выводить на эту панель текст. Чтобы не придумывать собственные шрифты решено рисовать на TBitmap с помощью Canvas.TextOut текст, а потом попиксельно считывать получившееся изображения для передачи на устройство.

Но есть такое понятие как мигание символов, то есть по таймеру то на панель передается изображение со всеми символами, то передается изображение, где мигающие символы не прорисованы, возникает эффект мигания символов. При этом символы, которые не мигают должны статично оставаться на своих местах.

То есть, сразу вывести весь текст с помощью TextOut нельзя, все символы прорисуются.

Другой вариант - прорисовывать отдельно каждый символ, каждый раз сдвигая позицию вывода вправо на TextWidth от символа. При этом произойдет эффект затирания для некоторых шрифтов (думаю, кто знает - сталкивался с проблемой).

Другой вариант - выводить строчку сразу всю, где символы которые не нужно выводить заменены на пробелы. Тоже не вариант, так как символы имеют не постоянную ширину и в результате все "поедет".

Кто какие знает варианты решения проблемы?

P.S. Переиначив задачу скажу так:

Как вывести некую строку текста, притом чтобы не выводились определенные символы в строке, но оставшиеся видимые символы были на том же месте, на котором они бы были, если эти не отображаемые символы бы выводили. ;)


 
wl ©   (2008-07-18 18:28) [1]

а если тупо использовать моноширинный шрифт? или делать отступ, на основании ширины каждого отдельного символа (вроде должна быть такая фишка)


 
{RASkov} ©   (2008-07-18 19:32) [2]

Самое простое это - моноширный шрифт.
Иначе посимвольно, где "пустое место" это символ цветом фона...


 
wl ©   (2008-07-18 19:36) [3]

а зачем цвет фона, если его можно просто скипнуть


 
{RASkov} ©   (2008-07-18 19:45) [4]

ну в принципе да...)


 
Lines   (2008-07-18 20:27) [5]

Удалено модератором
Примечание: Дубль...


 
Lines   (2008-07-18 20:27) [6]

{RASkov} ©   (18.07.08 19:32) [2]
Самое простое это - моноширный шрифт


понятное дело, что для моноширных шрифтов проблемы не существует. Но она существует для других видов шрифтов. Например, Tahoma, который достаточно при этом красиво выглядит на светодиодном дисплее.

{RASkov} ©   (18.07.08 19:32) [2]
Иначе посимвольно, где "пустое место" это символ цветом фона...

wl ©   (18.07.08 19:36) [3]
а зачем цвет фона, если его можно просто скипнуть


читаем пост:

Lines   (18.07.08 18:11)
Другой вариант - прорисовывать отдельно каждый символ, каждый раз сдвигая позицию вывода вправо на TextWidth от символа. При этом произойдет эффект затирания для некоторых шрифтов (думаю, кто знает - сталкивался с проблемой).


 
Пробегал2....   (2008-07-18 20:32) [7]

эффект затирания, это когда рисование следующего отдельного символа может затирать часть предыдущего.

Например, возьмите шрифт Tahoma размера 11 и сделайте типа такого:

Canvas.TextOut(x,y, "0");
inc(x, Canvas.TextWidth("0")) ;
Canvas.TextOut(x,y, "0");


нарисуется два нуля. Но можно заметить, что второй ноль немного затрет правую границу первого нуля.
Это не тоже самое, что сделать: Canvas.TextOut(x, y, "00");


 
Zeqfreed ©   (2008-07-18 21:18) [8]

Есть у меня чувство, что при выводе можно задать режим прозрачного фона и все будет ништяк. Вот помнится мне что-то такое там было.


 
Тын-Дын ©   (2008-07-18 21:56) [9]

А гасить все символы перед выводом новых не получится?


 
antonn ©   (2008-07-19 00:58) [10]

не понял проблемы... если вывод будет идти на светодиодную панель с совсем конкретными размерами букв в пикселях, то было бы разумнее изначально нарисовать весь алфавит, загружать буковки в битмап и потом через canvas.copyrect() выводить каждую букву там где надо.
ковыряния  с моноширинными буквами трутайповых шрифтов - это баловство получается.


 
Германн ©   (2008-07-19 01:16) [11]


> Lines   (18.07.08 20:27) [6]
>
> {RASkov} ©   (18.07.08 19:32) [2]
> Самое простое это - моноширный шрифт
>
> понятное дело, что для моноширных шрифтов проблемы не существует.
>  Но она существует для других видов шрифтов. Например, Tahoma,
>  который достаточно при этом красиво выглядит на светодиодном
> дисплее.
>


> Но есть такое понятие как мигание символов, то есть по таймеру
> то на панель передается изображение со всеми символами,
> то передается изображение, где мигающие символы не прорисованы,
>  возникает эффект мигания символов. При этом символы, которые
> не мигают должны статично оставаться на своих местах.
>
>

Может не надо извращений?


 
wl ©   (2008-07-19 02:27) [12]

> [7] Пробегал2....   (18.07.08 20:32)
> эффект затирания, это когда рисование следующего отдельного
> символа может затирать часть предыдущего.
>
> Например, возьмите шрифт Tahoma размера 11 и сделайте типа
> такого:
>
> Canvas.TextOut(x,y, "0");
> inc(x, Canvas.TextWidth("0")) ;
> Canvas.TextOut(x,y, "0");
>
> нарисуется два нуля. Но можно заметить, что второй ноль
> немного затрет правую границу первого нуля.
> Это не тоже самое, что сделать: Canvas.TextOut(x, y, "00")
> ;

а что, индент между буквами сделать религия не позволяет?


 
korneley ©   (2008-07-19 10:06) [13]

Вообще не понял, в чем, собственно проблема.

> Существует светодиодная панель, имеющая некоторое разрешение,
>  на этой панели соответственно можно зажигать или гасить
> определенные светодиоды

 Ну так и надо контроллеру панели дать соответствующие указания на вкл/выкл диода по его местоположению и в соответствии с его (контроллера) логикой. Бегущая строка реализуется именно средствами конроллера, а не компа с ним сопряженного. Шрифты - моноширинные (8х13 и 6х8 дос-овские очень для табло подходят, если надо могу бмп-шку прислать) Всё, что красиво выглядит на форме/окне - как правило на табло - полное... нечитаемое. :) Вывод делаю в результате использования одного и того же табло 192х96. Использовалось для спорт.гимнастики (windows - шрифты, не я :) а затем на чемпионате России по вольной борьбе (моноширинные - я :) Всеми было отмечена лучшая читаемость на табло, именно, более "древних" шрифтов :))
 Мигание для табло - вообще вещь непонятная. Это следствие или неправильной работы самого табло (с контроллером на пАру), или неудачного протокола обмена. У меня 18432 диода, управление через COM, 57600 bps(!) Не мигают. Правда обмен раз в секунду :)))


 
Lines   (2008-07-19 12:44) [14]

Интересно, что перенесли в начинающие ;)
На самом деле тонкий момент.


> Есть у меня чувство, что при выводе можно задать режим прозрачного
> фона и все будет ништяк

Очень неплохой вариант... Но я тоже не знаю как задать режим прозрачного фона при TextOut?! Если так можно - проблема бы решилась.


> А гасить все символы перед выводом новых не получится?

э-э-э... Не понял. Зачем их гасить?
Проблема не в том, что какие-то последующие изображения накладываются на предыдущую картинку. Проблема в том, что при выводе очередного знако-места оно для не моноширинных шрифтов может немного затирать предыдущее знако-место.


> не понял проблемы... если вывод будет идти на светодиодную
> панель с совсем конкретными размерами букв в пикселях

в том и дело, что нет. Клиент сам задает какиш шрифтом, размером, стилем шрифта выводить информацию на табло. Делать все вручную - имхо, повторять систему шрифтов в windows. Только работы прибавится по ручному рисованию и созданию шрифтов.


> а что, индент между буквами сделать религия не позволяет?

Что такое индент? В смысле, увеличить расстояние между буквами? Ну тогда мы поимеем косяк в том, что расстояния между буквами будут больше, чем нужно.


> Мигание для табло - вообще вещь непонятная. Это следствие
> или неправильной работы самого табло

ты не понял. Проблема не в том, что табло мигает. Надо СДЕЛАТЬ, чтобы табло мигало. А точнее, отдельные его пиксели.

Если ты говоришь про спортивные табло, то например представь, что на табло пишется список замен игроков. И при замене, идущей прямо сейчас, имена игроков мигают. То есть, мигание определенных элементов, части надписи на табло нужно для привлечения внимания к этому месту. И реализуется это не средствами табло, а путем периодического изменения картинки на табло. То некоторые буквы прорисоваются, то прорисовываются, возникает эффект мигания.

Но буквы, которые всегда прорисовываются должны оставаться на своих местах. Из всего этого и возникла тема.


 
korneley ©   (2008-07-19 13:13) [15]


> Lines   (19.07.08 12:44) [14
> ...Но буквы, которые всегда прорисовываются должны оставаться
> на своих местах...

 Неизвестно, табло у Вас "знакоместное" или "поле". Интерфейс связи не озвучен. Но, в любом случае, правильней (имхо) переложить задачу мигания на контроллер. Опять же, как в DOS-е: байт атрибута + байт информации = счастье :) "Похожие задачи рождают похожие решения" (с)


 
AlexanderMS_   (2008-07-19 13:13) [16]


>  режим прозрачного фона при TextOut?!

Canvas.Brush.Style := bsClear;
Должно помочь.


 
Lines   (2008-07-19 13:28) [17]


> Неизвестно, табло у Вас "знакоместное" или "поле".

"поле"


> Интерфейс связи не озвучен

какая разница? Я могу зажигать и тушить любой "пиксель".


> Но, в любом случае, правильней (имхо) переложить задачу
> мигания на контроллер

может быть. Но я не пишу прошивки контроллера, я пишу программы под windows и задание такое ;)


> Canvas.Brush.Style := bsClear;
> Должно помочь

большое спасибо! Попробую.


 
korneley ©   (2008-07-19 14:00) [18]


> Lines   (19.07.08 13:28) [17]
> > Неизвестно, табло у Вас "знакоместное" или "поле".
> "поле"
> > Интерфейс связи не озвучен
>какая разница? Я могу зажигать  и тушить любой "пиксель".

 Разница в скорости обмена. Именно с графикой и возникают траблы т.к. знакогенератор удалён и каждый пиксель нужно отрисовать на табло. А теперь просчитайте темп выдачи "картинки" (кадра) на табло и объём перекачиваемых данных, а затем сравните его с пропускной способность интерфейса комп <-> контроллер. Или у Вас все таки не табло, а телевизор/монитор? Тогда и подходы другие.


 
Тын-Дын ©   (2008-07-19 14:10) [19]


> э-э-э... Не понял. Зачем их гасить?


Я имел ввиду - полностью стирать текст и отрисовывать его заново.


 
antonn ©   (2008-07-19 15:09) [20]

если монитор/телефизор, то я начинаю понимать что такое "мигание символов" :)


 
Lines   (2008-07-19 15:27) [21]

korneley ©   (19.07.08 14:00) [18]
Разница в скорости обмена


и что? Причем здесь это?! Это никак не проблема недостаточной пропускной способности. Проблема в том, что при ВЫВОДЕ на TBitmap не всей строчки сразу, а отдельными символами происходит частичное затирание иногда предыдущего символа. Причем тут вообще табло? Надо было наверное вообще про него ничего не говорить, оно тут не причем, косяк уже на TBitmap виден...

Тын-Дын ©   (19.07.08 14:10) [19]
Я имел ввиду - полностью стирать текст и отрисовывать его заново


перечитайте ветку заново. Вы вообще о чем-то совсем другом.

Каждый раз я забеляю полностью поверхность TBitmap"а...

antonn ©   (19.07.08 15:09) [20]
если монитор/телефизор, то я начинаю понимать что такое "мигание символов" :)


почему никто полностью посты не читает? Это не мерцание как в телевизоре, это именно мигание СИМВОЛОВ. Символы то выводятся на экран, то не выводятся СПЕЦИАЛЬНО. Получается, они то есть на экране, то их нету - и они визуально как бы мигают. Секунду горят, на полсекунды тухнут. Ну как еще объяснить?! Специальный эффект который надо делать!!! Чтобы символы или целая строчка мигала, привлекая к себе внимание!


 
Тын-Дын ©   (2008-07-19 15:37) [22]


> Тын-Дын ©   (19.07.08 14:10) [19]
> Я имел ввиду - полностью стирать текст и отрисовывать его
> заново
>
> перечитайте ветку заново. Вы вообще о чем-то совсем другом.
>


Можешь привести кусок кода с отрисовкой на Bimap, где проявляется этот эффект затирания?


 
antonn ©   (2008-07-19 15:51) [23]


> почему никто полностью посты не читает? Это не мерцание
> как в телевизоре, это именно мигание СИМВОЛОВ. Символы то
> выводятся на экран, то не выводятся СПЕЦИАЛЬНО. Получается,
>  они то есть на экране, то их нету - и они визуально как
> бы мигают. Секунду горят, на полсекунды тухнут. Ну как еще
> объяснить?! Специальный эффект который надо делать!!! Чтобы
> символы или целая строчка мигала, привлекая к себе внимание!
>

потому что в куче постов все размыто и общими понятиями написано.
в чем проблема-то? рисуете на битмапе с черным фоном белый текст. в следующую рисуете черый текст - вот и мигание.


 
{RASkov} ©   (2008-07-19 15:51) [24]

const Txt= "Текстовая "ВНИМАНИЕ" строка";
var N, J, K: Integer;
begin
 Canvas.Font.Name:="Tahoma";
 Canvas.Font.Size:=30;
 for N:=1 to 6 do begin
  K:=0;
  for J:= 1 to Length(Txt) do begin
   if J>1 then INC(K, Canvas.TextWidth(Txt[J-1]));
   if ODD(N) and (J in [12,13,14,15,16,17,18,19]) then Canvas.Font.Color:=Canvas.Brush.Color
    else Canvas.Font.Color:=Font.Color;
   Canvas.TextOut(50+K, 100, Txt[J]);
  end;
  Sleep(250);
 end;
end;

Нормально вроде мигает :)
Или это не то?


 
AlexanderMS_   (2008-07-19 15:58) [25]


> Проблема в том, что при ВЫВОДЕ на TBitmap не всей строчки
> сразу, а отдельными символами происходит частичное затирание
> иногда предыдущего символа

а эта строчка не спасла отца русской демократии? :)
Canvas.Brush.Style := bsClear;
Её нужно непосредственно перед выводом текста написать, после заливки и прочих операций.
И символ не затирается.


 
antonn ©   (2008-07-19 16:55) [26]

эта строчка рисует текст без фона :)


 
antonn ©   (2008-07-19 16:55) [27]

точнее заставляет рисовать без фона :)


 
AlexanderMS_   (2008-07-19 17:08) [28]


> точнее заставляет рисовать без фона :)

просто если рисовать с фоном, возможен эффект затирания символов.
Пример (сорри, что без with)

procedure TForm1.FormPaint(Sender: TObject);
var
 X, Y : Integer;
begin

X := 0;
Y := 0;
Canvas.Font.Size := 10;
Canvas.Font.Name := "Arial Black";

Canvas.Brush.Style := bsClear;

Canvas.TextOut(x,y, "W");
inc(x, Canvas.TextWidth("W")) ;
Canvas.TextOut(x,y, "W");

Canvas.Brush.Style := bsSolid;
Canvas.Brush.Color := clBtnFace;
Y := Canvas.TextHeight("W");
X := 0;

Canvas.TextOut(x,y, "W");
inc(x, Canvas.TextWidth("W")) ;
Canvas.TextOut(x,y, "W");

end;


Разница есть, к сожалению.


 
{RASkov} ©   (2008-07-19 17:12) [29]

> [26, 27] antonn ©   (19.07.08 16:55)

Ну вообще-то так и планируется.... т.е. не затирать соседние символы фоном текущего :)
Хотя в моем примере без прозрачного стиля кисти, а если с bsClear то появляется нежелаемый эффект...
По крайней мере у меня при "тестировании" оказалось лучше без bsClear :)
Возможно при наклонном тексте и происходит наложение символов и следственно затирание, но при обычном - "все пучком" ...вроде)


 
{RASkov} ©   (2008-07-19 17:15) [30]

> [28] AlexanderMS_   (19.07.08 17:08)

Можно сделать:
inc(x, Canvas.TextWidth("W")+1) ;
например.


 
antonn ©   (2008-07-19 18:36) [31]

я про затирание не понял:)
привык, что сначала фон очищается и на него наносятся надписи, там где надо. т.ч. оно все просто "затирается"


 
User   (2008-07-19 22:49) [32]

>> близко к теме ...
была аналогичная задумка 10 лет тому назад, правда далее тестового варианта не дошло, а реализация на К155ИР13, вывод через LPT - работало ;-) ...
<< по теме:
- непонятно, зачем использовать TextOut, графику и т.д. для вывода текста в строку? Тем более отображать весь символ сразу ... правда, все зависит от способа вывода текста и/или его отображения ...  
Судя по постановке задачи (бегущая строка в транспорте), то символы нужно выводить не сразу, а "постолбично", смещая отображаемый текст с сторону (лево или право, в зависимости от движения текста).
Свой шрифт я не придумывал, просто в цикле выводил масштабированый символ в область на экране, по столбцам считывал цвет в определенных координатах, и все по-новому - получалось для каждого символа массив из 8-и байт (символы тогда были 8х8, EGA). Для вывода использовались эти заготовки ... реализация кода - на Turbo Pascal 5.5.
Применительно к теме - можно мрименить тот же принцип для получения "матрицы" символов - их не так уж много (можно норма, I, B, IB)...


 
Тын-Дын ©   (2008-07-20 19:07) [33]


> AlexanderMS_   (19.07.08 17:08) [28]

Так и не понял проблемы особо.
По мне, так вот такая простая реализация решает проблемы.

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, Math, ExtCtrls;

type

 TSym=class
 public
   FCanvas: TCanvas;
   FW: array[0..255] of Integer;
   constructor Create(Canvas: TCanvas);
   procedure Paint(const Str: String;X,Y: Integer);
 end;

 TForm1 = class(TForm)
   Timer1: TTimer;
   procedure FormPaint(Sender: TObject);
   procedure FormCreate(Sender: TObject);
   procedure FormDestroy(Sender: TObject);
   procedure Timer1Timer(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

const
 StrPaint="ABCDEFGHIJKLMNOPQRSTUVWXYZ";

var
 Form1: TForm1;
 SymObj: TSym;

implementation

{$R *.dfm}

procedure TForm1.FormPaint(Sender: TObject);
begin
 SymObj.Paint(StrPaint,FOrm1.Tag,0);
end;

{ TSym }

constructor TSym.Create(Canvas: TCanvas);
var
 i: Integer;
begin
 FCanvas := Canvas;
 for i := 0 to 255 do
 begin
   FW[i] := FCanvas.TextWidth(Chr(i));
 end;
end;

procedure TSym.Paint(const Str: String; X, Y: Integer);
var
 i: Integer;
 XP: Integer;
begin
 XP := X;
 for i := 1 to Length(Str) do
 begin
   FCanvas.TextOut(XP,Y,Str[i]);
   Inc(XP,FW[Ord(Str[i])]{+1});
 end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 Timer1.Tag := 1;
 Canvas.Font.Size := 10;
 Canvas.Font.Name := "Arial Black";
 DoubleBuffered := True;
 SymObj := TSym.Create(Form1.Canvas);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
 SymObj.Free;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
 case Timer1.Tag of
   1:  if Form1.Tag+Form1.Canvas.TextWidth(StrPaint)>Form1.Width then Timer1.Tag := -1;
   -1: if Form1.Tag<0 then Timer1.Tag := 1;
 end;

 Form1.Tag := Form1.Tag+Timer1.Tag;
 Form1.Repaint;
end;

end.



Страницы: 1 вся ветка

Форум: "Начинающим";
Текущий архив: 2008.08.24;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.57 MB
Время: 0.042 c
15-1215161784
гпрс
2008-07-04 12:56
2008.08.24
автодозвон


3-1204279537
Ega23
2008-02-29 13:05
2008.08.24
Добавить GUID в базу


2-1216559033
ДжоШуа
2008-07-20 17:03
2008.08.24
не понимаю


6-1192557976
Rembo
2007-10-16 22:06
2008.08.24
TIdIcmpClient количество посланных байт


2-1216221664
MikeZ
2008-07-16 19:21
2008.08.24
Hooks: память не может быть read.





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский