Как стать автором
Обновить

Комментарии 17

НЛО прилетело и опубликовало эту надпись здесь
Инструмент для дизайнеров.
Отсутствие системных шрифтов можно обойти через try/catch, перебрав список при старте приложения — какой-то минимальный набор типа arial/verdana/helvetica/times new roman/etc. в системе скорее всего будет.
Потом, вы же не под сферического коня в вакууме разрабываете приложение, можно и потестировать перед публикацией на чем-нибудь.

И насчет скорости, оно что, совсем медленно работает?
Можно ведь по идее и нагенерить себе кэш из текстур в какой-то промежуточный момент.

И на мобильном устройстве неприменимо, потому что у них System.Drawing зарезан по функциональности, или из-за того что медленно?
> В результате получаем текст с рваными краями, полное отсутствие сглаживания.
Неправда ваша. Там шрифт выведен на белый фон со сглаживанием, после чего белый цвет заменен на синий.
Да. Вы правы.
Если ещё точнее. Неверно создан альфа-канал. Он как бы однобитный. Сглаживание есть у шрифта, но отсутствует у битмапа. Корректный альфа-канал и создаётся при рисовании с blendAlpha.
На мобильном устройстве и не получится использоваться — там GDI нету :(
  Stream fs = new MemoryStream();
  bmp.Save(fs, System.Drawing.Imaging.ImageFormat.Png);
  var tex = Texture2D.FromStream(gdev, fs);
  fs.Close();
  fs.Dispose();
  return tex;

мелочь конечно, но в подобных местах как-бы просто напрашивается использование «using»:

  using (Stream fs = new MemoryStream())
  {
  	bmp.Save(fs, System.Drawing.Imaging.ImageFormat.Png);
  	return Texture2D.FromStream(gdev, fs);
  }
MemoryStream вроде как managed, а по сути просто массив, поэтому using здесь не очень нужен — все равно потом GC вызовет Dispose на каждом объекте.
В пример, кстати, Dispose явно лишний, т.к. перед ним делается Close, который, согласно его описанию, освобождает все ресурсы.
А Dispose реализует интерфейс IDisposable, который предназначен для GC, который сам его дернет когда посчитает нужным вызовет на последней стадии жизни объекта, а самому лично вызывать его западло нужно только в особо сложных случаях.
ИМХО, в данной реализации Dispose просто вызовет Close в том случае, если он не был вызван.

Вот функции GDI желательно или в try/catch обрамить, или в using, т.к. они используют unmanaged ресурсы и может вылезти внешний exception на ровном месте — бывало иногда при сохранении файла в jpg/png.
/*
А так, если работает то и ладно — в try/catch это все загнать и сообщение показать вразумительное если что вдруг — потому как нефиг каждую копеечную фигную усложнять там где это не понадобится.
*/
Минусующим так понимаю сказать нечего, дальше школьного учебника ж никто ничего не читает, а три строчки написал и уже пограммер.
MemoryStream вроде как managed, а по сути просто массив, поэтому using здесь не очень нужен — все равно потом GC вызовет Dispose на каждом объекте.

По-моему у вас какая-то каша в голове — нельзя так перемешивать мягкое сразу и с тёплым и с пушистым.
Пояснить свою точку зрения, так понимаю, у вас не получается?
Ну давайте тогда я поясню свою, а вы поправите если что.

Итак:
using имеет практический смысл для немедленного уничтожения ссылок на unmanaged ресурсы, все прочие объекты и так уйдут в мусор после выхода из функции.
MemoryStream не является unmanaged ресурсом, т.к. представляет собой обертку над массивом byte, и принудительно уничтожать его надо только если памяти совсем мало.

ЧЯДНТ?
Сказать можно.
1) GC не вызывает Dispose, GC вызывает Finalize, если определён деструктор;
2) Сложно спрогнозировать, когда будет вызов GC, если его не вызывать через GC.Collect();
3) Close вызывает Dispose и вызывает GC.SuppressFinalize, что разгружает очередь финализатора. Но using использовать короче;
4) В реализации MemoryStream в .NET от MS действительно не использует managed ресурсы, но вы можете это заявить про Mono, Silverlight и про последующие версии .NET?
5) Просто вызовы без using или try finally объектов попадающих в очередь финализатора (обычно они реализуют IDisposable) использовать плохо, так как это не будет гарантировать освобождения ресурсов когда они не нужны, что, возможно, создаст memory pressure или нерациональное использование ресурсов.
Зачем прогнозировать, когда будет вызов GC? Видимо, он будет когда посчитает необходимым почистить память, а GC.Collect() раньше просили самому не вызывать.
Если у нас копеечное приложение на одного пользователя, то возможно что весь поток умрет раньше, чем GC займется расчисткой памяти.

Про Mono согласен, что непонятно как там все живет на самом деле, про последующие версии .Net — вряд ли что-то радикально поменяют в базовых классах, скорее сделают новый класс для больших объемов данных.

Что использовать try/catch/finally надо, согласен абсолютно, но не на каждый же оператор их лепить.
В примере, мы сразу после using выходим из функции, но при этом у нас нет catch на внешние вызовы GDI, вероятность ошибок в которых гораздо выше.

// (P.S. Вы на своем CV-сайте тоже не закрываете через try/catch создание объектов, в результате видно только белый экран...)
Пардон, я вас не корректно понял, указав 2ю причину.
Главная страница сайта — статический код, и, вероятно, у вас белый экран потому, что либо браузер не поддерживает inline svg, либо ещё не подгрузились ресурсы.
Да ладно, в общем это уже не важно.

IE8, Silverlite выключен — не люблю рекламу — видимо где-то здесь надо смотреть.
Если сделаете отработку с выводом сообщений, пользователи вас быстрее поймут ))
Не знаю как там в XNA, не доводилось писать, но немного знаю как в DirectX. XNA, по сути, является оберткой над DirectX, потому должно иметь те же возможности.

Для вывода текста в DirectX мне известны 3 способа:
1. ID3DXFont. Интерфейс использует для отображения текста GDI, но зато поддерживает сложные шрифты и форматирование

2. CD3DFont. Класс, который отображает текст используя текстурированные треугольники и Direct3D. Он не поддерживает сложные шрифты и форматирование, но если нужна скорость и достаточно простых шрифтов, то вполне сойдет. Рисует вполне красивый сглаженный шрифт

image

3. D3DXCreateText. Позволяет рисовать трехмерный текст(двумерный, естественно, тоже), использует Direct3D (рисует мешами).
Позволяет задавать высоту, ширину, насыщенность, гарнитуру шрифта. Гладко, просто, быстро и красиво.


Странно, что в XNA нужно так извращаться.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации