Новый дискмаг о старых амижных играх

Софт для классических Amiga. AmigaOS 1.x-3.9, Morphos 1.x

Модераторы: striimii, Vinnny

Re: Новый дискмаг о старых амижных играх

Сообщение Vinnny 18 янв 2012, 00:37

anny писал(а):Я хз даже что он содержит. В смысле обычный виндовый Arial фонт что содержит ? Может и cp1251, а может и нет, я хз:

ну есть же кирилица там.
только странно как-то. в кирилице заглавная А находится на позиции 0410. источник
а у тебя на позиции 023a. что-то у тебя не так с кирилической таблицей кодировок юникода.
Pegasos2+Efika, MorphOS registered
Amiga1200, Blizzard030, AmigaOS
ПэЦэ, вЕнда
Аватара пользователя
Vinnny
Менеджер
Менеджер
 
Сообщения: 2433
Зарегистрирован: 18 май 2002, 12:56
Откуда: NiNo

Re: Новый дискмаг о старых амижных играх

Сообщение Dimouse 18 янв 2012, 00:51

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

Vinnny, да но только это не юникод, я не туда увел мысль.

Изображение
Хотите поболтать о старых добрых играх на IBM-несовместимых компьютерах? Добро пожаловать к нам на форум http://www.old-games.ru/forum/ в раздел IBM-PC несовместимое!
Dimouse
Престарелый Амигодум
Престарелый Амигодум
 
Сообщения: 174
Зарегистрирован: 17 ноя 2005, 21:04
Откуда: Moscow

Re: Новый дискмаг о старых амижных играх

Сообщение anny 18 янв 2012, 02:03

@easy

Хз, вроде обычный Arial виндовый.

@Dimouse

Короче после некоторых тестов, я так понял что у нас в SDL версии (linux, aos3/aos4/morphos) - "charset" опция для фонтов сосет омигу 1200. Т.е. вот я прямо сейчас попробовал на одной из статей сделал "charset=r", загрузил в виндовую версию - показывает по русски. Далее загрузил этот же дат файл в наш двиг - иероглифы. Далее я поставил там "charset=t" (турки) - в виндовой версии турки как и должно быть, а в нашей - все теже кракозябры как и до этого. Т.е. что "r" что "t" в charset вообще роли не играет. Я также почитал ридми от панарамы, и:

"charset" specified character set. Existing character sets are: d - default, o - OEM, e - Eastern Europe, r - Russian, t - Turkish, g - Greek. Default is ... default. The value in case insensitive and can have multiple characters, but only the first is interpreted. (и теперь интересная часть:) It is not guaranteed that all browser versions for all operating systems will support this parameter


Т.е. варианта 2:

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

Я более склоняюсь естна к первому, и у нас тогда варианта опять 2:

первый - добавить поддержку чарсетов в код (но это пезд, в том смысле что возиться с фонтами и чарсетами как-то даже хз, не очень хотелось бы)
второй - тупо сделать фонт, в котором будет русский сразу же, во второй части фонта. Т.е. рассовать русские символы просто в те места, куда ссылается все сейчас. я сделал децл тестов (тупо забил "a" букву в кучу полей в фонт-креаторе) , и статьи показывают "aaaa" что говорит о том , что шрифт сделать можно. Ну и стало быть юзать его где надо (включать-выключать). Плюс в том, что мы сделаем пару шрифтов таких, и можно их юзать всегда и везде (включая и линуксовую версию).
anny
Беспардонный Амигофлуд
Беспардонный Амигофлуд
 
Сообщения: 1267
Зарегистрирован: 05 дек 2004, 01:22

Re: Новый дискмаг о старых амижных играх

Сообщение Dimouse 18 янв 2012, 17:55

anny, имхо, стоит дописать у двигла, чтобы работала опция charset (может даже у Криса попросить код, наверняка у него остался?), так как во втором случае не получится, чтобы любой шрифт работал, а такая необходимость может возникнуть в будущем. Не переделывать же все шрифты.

Кроме того, я сейчас тестирую дискмаг на версии под линуксом (так как Амигу 68k заставить работать видимо не судьба), пробовал и так и эдак (есть еще оказывается такая опция как panorama2_font_override, она 100 процентов подключает тот шрифт, который написан в пути, но русские символы в нем не показывает ни в какую. Более того, есть такая штука как Arial Cyr шрифт http://www.fontsner.com/font/Arial_Cyr-39391.html это в стародавние досовские времена делали как раз заменой западноевропейских символов в шрифте (всякие там умляуты) на кириллические. Так вот - все равно показывает квадратики. Даже если сами статьи сохранить в дос-кодировке. В общем я совсем запутался.
Хотите поболтать о старых добрых играх на IBM-несовместимых компьютерах? Добро пожаловать к нам на форум http://www.old-games.ru/forum/ в раздел IBM-PC несовместимое!
Dimouse
Престарелый Амигодум
Престарелый Амигодум
 
Сообщения: 174
Зарегистрирован: 17 ноя 2005, 21:04
Откуда: Moscow

Re: Новый дискмаг о старых амижных играх

Сообщение anny 18 янв 2012, 20:46

@Dimouse
anny, имхо, стоит дописать у двигла, чтобы работала опция charset


По уму лучше, а на деле это же писать и разбираться :) Хотя если есть пример использования Freetype + sdl в выводом русского текста в sdl окне , оно бы думаю очень помогло.

(может даже у Криса попросить код, наверняка у него остался?),


Так у меня все сорцы есть: и крисовые под win32, и ransoma под sdl, и даже под beos.

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

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


Так а нам и не надо милион шрифтов. Тупо сделать 2-3. arial и еще там ченить и фсо.

Кроме того, я сейчас тестирую дискмаг на версии под линуксом (так как Амигу 68k заставить работать видимо не судьба), пробовал и так и эдак (есть еще оказывается такая опция как panorama2_font_override, она 100 процентов подключает тот шрифт, который написан в пути


На амижной все также, т.к. linux версия и амижная это 1:1 тот же самый код, только с ооочень мелкими изменениями в паре функций. Но все что касаемо фонтов один в один.

, но русские символы в нем не показывает ни в какую.


Потому как charset опция тупо не работает. Я посмотрел виндовую create_font() и sdlную : в sdlной (т.е. наша, т.е. линуксовая и амижная) - charset вообще как будто не юзается, или хз даже чего куда .. Надо совсем глубоко в коды вникать.

Более того, есть такая штука как Arial Cyr шрифт http://www.fontsner.com/font/Arial_Cyr-39391.html это в стародавние досовские времена делали как раз заменой западноевропейских символов в шрифте (всякие там умляуты) на кириллические. Так вот - все равно показывает квадратики. Даже если сами статьи сохранить в дос-кодировке. В общем я совсем запутался.


Квадратики вообще на всех буквах, или только на некоторых ? Потому как вчера я пробовал виндовый arial, и в нем я нашел место которое могу заменять, но попробовал твой a_Cooper, который имеет только english и russian, и весь текст квадратики, как будто смещений каких-то не находит.

В любом случае, даже чтобы добавить поддержку чарсетов в код, надо все равно почитать как структурированы фонты, и каким образом определяется какой чарсет юзать, далее надо найти любой пример использования freetype + sdl для вывода русского текста в sdl окне. И тогда аналогично этому коду будет в принципе легко наверно.
anny
Беспардонный Амигофлуд
Беспардонный Амигофлуд
 
Сообщения: 1267
Зарегистрирован: 05 дек 2004, 01:22

Re: Новый дискмаг о старых амижных играх

Сообщение Dimouse 18 янв 2012, 23:05

Так у меня все сорцы есть: и крисовые под win32, и ransoma под sdl, и даже под beos.

А ты не мог бы выслать? Я бы поковырялся. Если под линукс будет собираться - допилить, думаю, что-нибудь смогу.

Так а нам и не надо милион шрифтов. Тупо сделать 2-3. arial и еще там ченить и фсо.

Ну а вот, через пару лет еще захочется что-нибудь сделать, те же шрифты использовать снова?

Потому как charset опция тупо не работает. Я посмотрел виндовую create_font() и sdlную : в sdlной (т.е. наша, т.е. линуксовая и амижная) - charset вообще как будто не юзается, или хз даже чего куда .. Надо совсем глубоко в коды вникать.

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

Квадратики вообще на всех буквах, или только на некоторых ? Потому как вчера я пробовал виндовый arial, и в нем я нашел место которое могу заменять, но попробовал твой a_Cooper, который имеет только english и russian, и весь текст квадратики, как будто смещений каких-то не находит.

Да, на всех русских. Там тоже нет кроме русских и английских ничего, урезанный шрифт, то есть такое ощущение, что по умолчанию он считывает что-то за пределами первых 256 символов ttf. Вопрос - какие. Если бы были исходники, можно это было бы тупо проверить, поставив вывод в консоль в нужном месте кода.
Хотите поболтать о старых добрых играх на IBM-несовместимых компьютерах? Добро пожаловать к нам на форум http://www.old-games.ru/forum/ в раздел IBM-PC несовместимое!
Dimouse
Престарелый Амигодум
Престарелый Амигодум
 
Сообщения: 174
Зарегистрирован: 17 ноя 2005, 21:04
Откуда: Moscow

Re: Новый дискмаг о старых амижных играх

Сообщение anny 19 янв 2012, 03:26

@Dimouse
А ты не мог бы выслать? Я бы поковырялся. Если под линукс будет собираться - допилить, думаю, что-нибудь смогу.


К сожалению нет, т.к. мне их дали по типу "только тебе для порта".

Если бы были исходники, можно это было бы тупо проверить, поставив вывод в консоль в нужном месте кода.


В консоль уже по русски все выводится... Если более детально, то вот смотри:

1. делается всякое говно инициализующее и тд и тп

2. начинается парсинг текста

3. вызывается функция font_install - она тупо загружает фонт. Вот она:

Код: Выделить всё
/* Installs truetype font ("where" is the same as for create_file())
   This gives you a font (TTF) file. These files are saved in your
   temp directory (see create_file()) prior to calling this method,
   so "from_where" should specify temp. You don't have to care much
   about this method - just warn the users in the doc that they
   should install appropriate fonts before running the program.
   These fonts should also be supplied by container/issue authors.
*/
void SDLSystem::install_font (const char* filename, UINT from_where)
{
   if (config->getVerbose())
      printf("install_font, '%s', from: %i\n", filename, from_where);
   
   Vector* dirList = Vector_construct();
   
   char* tempDir = new char[2048];
   snprintf(tempDir, 2048, "%s%s%s", platform->getCurrentDir(), "temp", platform->getDirSeparator());
   
   platform->createDirListing( tempDir, dirList);
   delete[] tempDir;
   
   for (int i = 0; i < Vector_getSize(dirList); i++)
   {
      char* entry = (char*) Vector_get(dirList, i);
      
      if (strstr(entry, filename) == NULL)
      {
         Vector_remove(dirList, i);
         i--;
         delete[] entry;
      }
   }
   
   fontMapping->createFontMapping(dirList, fontMap);
}


4. Далее вызывается функция create_font. Она берет основные настройки (размер, цвет и чарсет (по идее) ). Вот она:

Код: Выделить всё
/* Creates a font object. See the corresponding stuff in system.cpp
   This will be difficult for you if your system does not support
   TrueType fonts. You have to create a font according to the use specs.
   Flags are defined in system.h (bold, italic, underline). Charsets too.
   You return height=ascent and add_height=descent. Do not add the additional
   spacing. FONT is defined as void*, so you have to supply your own
   structure and cast it to (FONT). Beware of duplicating the fonts,
   the create_font() requests will be multiple, and often the parameters
   will be the same. The face will always be lowercase. If the requested
   face doesn't exist, you should use some default font (perhaps system
   default). Like in all the other cases, the Win32 and BeOS SI sources
   supplied by me should show you some tips.

   CHARSET_DEFAULT              = 0
   CHARSET_OEM                  = 1
   CHARSET_EASTEUROPE           = 2
   CHARSET_RUSSIAN              = 3
   CHARSET_TURKISH              = 4
   CHARSET_GREEK                = 5

   FF_BOLD                      = 1
   FF_ITALIC                    = 2
   FF_UNDERLINE                 = 4

*/
FONT SDLSystem::create_font (const char* faceName, UINT required_height, UINT flags, UINT charset, UINT& height, UINT& add_height)
{
   char* fontName       = NULL;
   char* path      = NULL;
   char* face      = NULL;
   SDLFace* sdlFace    = NULL;
   
   if (config->getVerbose())
      printf("create_font, '%s', height: %i, flags: %x, charset: %i\n", faceName, required_height, flags, charset);

   face = (char*) malloc(strlen(faceName) + 3);
   sprintf(face, "%s:%i", faceName, flags);
   
   path = (char*) Map_get(fontMap, face);
   
   if (path == NULL)
   {
                if (config->getVerbose())
            fprintf(stderr, "Loading of unmapped font, '%s' requested. Falling back to default.\n", face);

      face = "default:0";
      path = (char*) Map_get(fontMap, face);
   }

   /* Copy the font name, since the core system reuses the memory! */
   fontName = (char*) malloc( strlen(face) + 100 ); //Oh my god, magic constant on a buffer - typical buffer overflow invitation

   sprintf(fontName, "%s:%i", face, required_height);
   
   
   /* Check if this particulare font has allready been loaded */
   sdlFace = (SDLFace*) Map_get(fontBuffer, fontName);
   
   if (sdlFace != NULL)
   {
      height      = SDLFace_getAny(sdlFace)->ascender;
      add_height   = SDLFace_getAny(sdlFace)->descender;
      return sdlFace;
   }
   sdlFace = SDLFace_load(path, required_height);
   
   height      = SDLFace_getAny(sdlFace)->ascender;
   add_height   = SDLFace_getAny(sdlFace)->descender;

   Map_put(fontBuffer, fontName, sdlFace);
   
   return sdlFace;
}


5. Далее идет функция out_text. Которая выводит непосредственно текст в двигло. Вот она:

Код: Выделить всё
/* Renders text. The return value is important when printing -
it's the width of the printed text, given in Panorama coordinates.
   "text_len" is provided so you do not have to call strlen(text).
   (x,y) specifies upper left corner of the rectangle within which
   the text will be drawn. Take care of the region ! Color format
   specified by you in get_user_flag().
   See print() for meaning of return value.
*/
UINT SDLSystem::out_text (const char* text, UINT text_len, UINT x, UINT y, DWORD color, FONT _font)
{
   color = SWAP24(color);

   SDLFace* face      = (SDLFace*)_font;
   SDLFont* font       = SDLFace_getColour(face, color);

   if (config->getVerbose())
      printf("out_text, '%s', length: %i, x: %i, y: %i, color:%i\n", text, text_len, x, y, color);

   return SDLFont_draw(font, (char*) text, text_len, current, x, y);
}


Вот тут видишь "printf()" ? Как раз перед SDLFont_draw. Вот он в консоль уже все по русски выводит. Т.е. до этого момента все ок, и "text" буфер уже содержит русские символы в cp1251. И далее, вызывается этот SDLFont_draw, которая берет буфер "text" с нашим текстом (который все же в cp1251).

6. Непосредственно SDLFont_Draw выглядит так:

Код: Выделить всё
Uint32 SDLFont_draw(SDLFont* font, char* string, Uint32 textLength, SDL_Surface* surface, Uint32 x, Uint32 y)
{
   Uint32 width      = 0;
   SDLCharacter* chr   = NULL;
   SDL_Rect dstrect;
   SDL_Rect srcrect;
   
   srcrect.x = 0;
   srcrect.y = 0;

   for (Uint32 i = 0; i < textLength; i++)
   {
      chr = SDLFont_getCharacter( font, string[i] );

      srcrect.w = chr->bitmap->w;
      srcrect.h = chr->bitmap->h;
      
      dstrect.x = x + chr->xDisplace;
      dstrect.y = y - chr->yDisplace + font->ascender;

      SDL_BlitSurface(chr->bitmap, &srcrect, surface, &dstrect);

      x    += chr->advance;
      width    += chr->advance;
   }

   return width;
}


Собственно вот такая логика загрузки фонта.

Почему в консоль уже выводит по русски я хз - скорей всего потому что у меня система настроена cp1251 показывать. А двигло так сказать кеймапа не имеет (т.е. таблицу с которой модно все сопаставить). И походу нам надо кеймап как-внедрять или хз, чего.
anny
Беспардонный Амигофлуд
Беспардонный Амигофлуд
 
Сообщения: 1267
Зарегистрирован: 05 дек 2004, 01:22

Re: Новый дискмаг о старых амижных играх

Сообщение Dimouse 19 янв 2012, 12:39

Самое интересное-то ты и не показал:)

sdlFace = SDLFace_load(path, required_height); - вот эта функция должна из пути делать шрифт в формате SDL (то есть, как я понимаю, битмеп в памяти)
chr = SDLFont_getCharacter( font, string[i] ); - а вот эта подгружает нужный символ из шрифта.

Вопрос в том, подгружает ли он все символы сразу или же только символы той кодировки, которую он хочет (то есть западноевропейскую)? В первом случае надо копать функцию getcharacter (вторую), чтобы она подключала нужные символы. Во втором - менять первую функцию, чтобы она грузила другую часть шрифта. Интересно было бы посмотреть как выглядит сам битмеп с шрифтом, но я сам на SDL ничего не писал, только на Аллегре, которая является над ним надстройкой, там функции другие.
Хотите поболтать о старых добрых играх на IBM-несовместимых компьютерах? Добро пожаловать к нам на форум http://www.old-games.ru/forum/ в раздел IBM-PC несовместимое!
Dimouse
Престарелый Амигодум
Престарелый Амигодум
 
Сообщения: 174
Зарегистрирован: 17 ноя 2005, 21:04
Откуда: Moscow

Re: Новый дискмаг о старых амижных играх

Сообщение anny 19 янв 2012, 15:06

@Dimouse
Что SDLFace_load что SDLFont_getCharacter, это не SDLные функции, это панарамные функции, названы просто так. Вот короче весь SDLFont.cpp:

Код: Выделить всё
#include "SDLFont.h"
#include <assert.h>

#define CHARACTERS 256

FT_Library library = NULL;

SDLFace* SDLFace_load(char* path, Uint32 size)
{
   FT_Face font      = NULL;   
   
   if (library == NULL)
   {
      int result = FT_Init_FreeType( &library );
      if ( result )
      {
         fprintf(stderr, "SDLFont.c: Unable to initialize freetype library. Error: %i\n", result);
         return NULL;
      }
   }
   
   int result = FT_New_Face(library, path, 0, &font);
   if ( result )
   {
      fprintf(stderr, "SDLFont.c: Unable to load font '%s', check your font paths. Error code: %i\n", path, result);
      return NULL;
   }

   if (FT_Set_Char_Size(font, 0, size*64, 58, 58))
   {
      fprintf(stderr, "SDLFont.c: Unable to set font '%s' to size: %i\n", path, size);
      return NULL;      
   }
   
   SDLFace* returnValue = SDLFace_create(font);

   return returnValue;

}

SDLFace* SDLFace_create(FT_Face face)
{
   SDLFace* sdlFace = (SDLFace*) malloc( sizeof(SDLFace) );
   
   /* Create the initial white version */
   SDLFont* white = SDLFont_create(face, 255, 255, 255);
      
   sdlFace->fonts = Vector_construct();
   Vector_add(sdlFace->fonts, white);
   
   return sdlFace;
}

SDLFont* SDLFace_getColour( SDLFace* face, Uint32 colour )
{
   int i          = 0;
   int size       = 0;
   SDLFont* current   = NULL;

   
   size = Vector_getSize(face->fonts);
   
   for (i = 0; i < size; i++)
   {
      current = (SDLFont*)Vector_get(face->fonts, i);
      
      if (current->colour == colour)
      {
         //If this font is not first, swap so that it is - as the same colour is often requested several times
         if (i != 0)
         {
            SDLFont* temp = (SDLFont*) Vector_get(face->fonts, 0);
            Vector_set(face->fonts, 0, current);
            Vector_set(face->fonts, i, temp);
         }
         return current;
      }
   }
   
   //The colour we are looking for does not exist - so create it.
   current = SDLFont_createFrom( (SDLFont*)Vector_get(face->fonts, 0), colour );
   Vector_add(face->fonts, current);
   
   return current;
}

SDLFont* SDLFont_createFrom( SDLFont* font, Uint32 colour)
{
   int i = 0;
   SDLFont* newFont = (SDLFont*) malloc( sizeof(SDLFont) );

   newFont->colour    = colour;
   newFont->ascender    = font->ascender;
   newFont->descender    = font->descender;
   
   for (i = 0; i < CHARACTERS; i++)
   {
      newFont->characters[i] = SDLCharacter_copy(font->characters[i], colour);
   }
   return newFont;
}

SDLFont* SDLFont_create(FT_Face face, Uint8 red, Uint8 green, Uint8 blue)
{
   int i = 0;
   SDLFont* newFont = (SDLFont*) malloc( sizeof(SDLFont) );
   
   for (i = 0; i < CHARACTERS; i++)
   {
      newFont->characters[i] = SDLCharacter_create(face, i, red, green, blue);
   }
   newFont->colour    = SDL_MapRGB(newFont->characters[0]->bitmap->format, red, green, blue);
   newFont->ascender    = FT_MulFix(face->ascender, face->size->metrics.y_scale)>>6;
   newFont->descender    = - ((FT_MulFix(face->descender, face->size->metrics.y_scale))>>6);

   return newFont;
}

SDLCharacter* SDLCharacter_create(FT_Face face, char character, Uint8 red, Uint8 green, Uint8 blue)
{
   SDLCharacter* newChar    = NULL;
   int i          = 0;
   int j          = 0;
   FT_Bitmap* bitmap    = NULL;   
   Uint8* pixels      = NULL;
   SDL_Surface* surface   = NULL;
   Uint32* pixel      = NULL;
   SDL_PixelFormat* format = NULL;
   Uint8 alpha       = 0;

   
   //Make the freetype system render the font
   int glyph_index = FT_Get_Char_Index( face, (unsigned char)character );
   
   FT_Load_Glyph( face, glyph_index, FT_LOAD_DEFAULT );
   FT_Render_Glyph( face->glyph, FT_RENDER_MODE_NORMAL );
   bitmap = &(face->glyph->bitmap);
   
   //Convert it to a SDL_Surface
   newChar = (SDLCharacter*) malloc( sizeof(SDLCharacter) );

   surface = SDL_CreateRGBSurface(SDL_SWSURFACE, bitmap->width, bitmap->rows, 32, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff);
   newChar->bitmap = SDL_DisplayFormatAlpha(surface);
   SDL_FreeSurface(surface);
   surface = newChar->bitmap;
   
   pixels = (Uint8*)surface->pixels;
   format = surface->format;
   
   for (i = 0 ; i < bitmap->rows; i++)
   {
      pixel = (Uint32*)pixels;
      
      for (j = 0; j < bitmap->width; j++)
      {
         alpha = bitmap->buffer[i*bitmap->pitch+j];
         
         *pixel = SDL_MapRGBA(format, red, green, blue, alpha);
         pixel++;
      }
      pixels += surface->pitch;
   }

   pixels = (Uint8*)surface->pixels;
   pixel = (Uint32*)pixels;   
   
   //Calculate various metrics
   newChar->xDisplace    = face->glyph->bitmap_left;
   newChar->yDisplace    = face->glyph->bitmap_top;
   newChar->advance    = face->glyph->advance.x >> 6;
   
   return newChar;
}

SDLCharacter* SDLCharacter_copy( SDLCharacter* character, Uint32 colour)
{
   int i             = 0;
   int j             = 0;
   Uint8 red          = 0;
   Uint8 green          = 0;
   Uint8 blue          = 0;
   Uint8 newRed          = colour>>16;
   Uint8 newGreen          = colour>>8;
   Uint8 newBlue          = colour;
   Uint8 alpha         = 0;
   Uint32* src          = NULL;
   Uint32* dst          = NULL;
   Uint8* srcLine          = NULL;
   Uint8* dstLine          = NULL;
   SDL_Surface* dstSurface    = NULL;
   SDL_Surface* srcSurface      = character->bitmap;

   SDLCharacter* copy    = (SDLCharacter*) malloc( sizeof(SDLCharacter) );
   
   copy->xDisplace    = character->xDisplace;
   copy->yDisplace    = character->yDisplace;
   copy->advance      = character->advance;
   dstSurface      = SDL_CreateRGBSurface(SDL_SWSURFACE, srcSurface->w, srcSurface->h, 32, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff);
   copy->bitmap       = SDL_DisplayFormatAlpha(dstSurface);
   SDL_FreeSurface(dstSurface);
   dstSurface       = copy->bitmap;
   
   srcLine = (Uint8*)srcSurface->pixels;
   dstLine = (Uint8*)dstSurface->pixels;
   
   for (i = 0; i < srcSurface->h; i++)
   {
      src = (Uint32*)srcLine;
      dst = (Uint32*)dstLine;
      
      for (j = 0; j < srcSurface->w; j++)
      {
         SDL_GetRGBA(*src, srcSurface->format, &red, &green, &blue, &alpha);
         *dst = SDL_MapRGBA(dstSurface->format, newRed, newGreen, newBlue, alpha);
         
         src++;
         dst++;
      }
      srcLine += srcSurface->pitch;
      dstLine += dstSurface->pitch;
   }
   
   return copy;
}

SDLCharacter* SDLFont_getCharacter( SDLFont* font, char character )
{
   return font->characters[(Uint8)character];
}

SDLFont* SDLFace_getAny( SDLFace* face)
{
   return (SDLFont*) Vector_get(face->fonts, 0);
}

Uint32 SDLFont_getWidth(SDLFont* font, char* string)
{
   int i          = 0;
   Uint32 width      = 0;
   SDLCharacter* chr   = NULL;

   for (i = 0; string[i] != 0; i++)
   {
      chr = SDLFont_getCharacter( font, string[i] );
      width += chr->advance;
   }
   return width;
}

Uint32 SDLFont_getWidthSubstring(SDLFont* font, char* string, Uint32 from, Uint32 to)
{
   Uint32 i;
   Uint32 pixelWidth = 0;
   SDLCharacter* chr   = NULL;
   
   for (i = from; i < to; i++)
   {
      chr = SDLFont_getCharacter( font, string[i] );
      pixelWidth += chr->advance;
   }
   return pixelWidth;
}



Uint32 SDLFont_draw(SDLFont* font, char* string, Uint32 textLength, SDL_Surface* surface, Uint32 x, Uint32 y)
{
   Uint32 width      = 0;
   SDLCharacter* chr   = NULL;
   SDL_Rect dstrect;
   SDL_Rect srcrect;
   
   srcrect.x = 0;
   srcrect.y = 0;

   for (Uint32 i = 0; i < textLength; i++)
   {
      chr = SDLFont_getCharacter( font, string[i] );

      srcrect.w = chr->bitmap->w;
      srcrect.h = chr->bitmap->h;
      
      dstrect.x = x + chr->xDisplace;
      dstrect.y = y - chr->yDisplace + font->ascender;

      SDL_BlitSurface(chr->bitmap, &srcrect, surface, &dstrect);

      x    += chr->advance;
      width    += chr->advance;
   }

   return width;
}


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


Я хз, но как я на данный момент понимаю, ttf шрифты содержат в себе информацию о том какие они имеют кодировки и где они расположены (я так понимаю не все, например те что мы пробовали куцие, и они квадратики дают нам, можно этой инфы и не имеют, а arial имеет, потому и символы дает нам типа правильные, токо в cp1251). Эту информацию freetype библиотека считывает и относительно этого уже и. Хотя хз.. По идее то если в шрифте есть инфа где символы (а это же рисунки), то стало быть эти же рисунки также и должны выводится.
anny
Беспардонный Амигофлуд
Беспардонный Амигофлуд
 
Сообщения: 1267
Зарегистрирован: 05 дек 2004, 01:22

Re: Новый дискмаг о старых амижных играх

Сообщение Q-Master 20 янв 2012, 09:19

anny писал(а):Я хз, но как я на данный момент понимаю, ttf шрифты содержат в себе информацию о том какие они имеют кодировки и где они расположены (я так понимаю не все, например те что мы пробовали куцие, и они квадратики дают нам, можно этой инфы и не имеют, а arial имеет, потому и символы дает нам типа правильные, токо в cp1251). Эту информацию freetype библиотека считывает и относительно этого уже и. Хотя хз.. По идее то если в шрифте есть инфа где символы (а это же рисунки), то стало быть эти же рисунки также и должны выводится.

Все TTF шрифты используют только уникод. Никаких кодировок там нет. А в коде, который был выше я что-то не заметил как инициализируется charmap. Ф-ция FT_Get_Char_Index юзает именно charmap для выдергивания из уникода индекса нужного глифа. Первые 127 символов там это ISO-8859-1, остальные 128, судя по чуши которую он отображает, мапятся туда-же. Почините маппинг - будет русский. Ну и проверьте что у вас шрифты содержат кириллицу.
WBR, Q-Master^MiR
Q-Master
Престарелый Амигодум
Престарелый Амигодум
 
Сообщения: 200
Зарегистрирован: 20 май 2002, 15:41
Откуда: Иваново, Россия

Re: Новый дискмаг о старых амижных играх

Сообщение anny 20 янв 2012, 15:15

@Q-master
Все TTF шрифты используют только уникод. Никаких кодировок там нет.

Никогда и не при каких обстоятельствах ? Т.е. чисто рисунки ?

А в коде, который был выше я что-то не заметил как инициализируется charmap. Ф-ция FT_Get_Char_Index юзает именно charmap для выдергивания из уникода индекса нужного глифа.


А что такое charmap, где оно лежит, как его инициализировать, и как узнать индексы нужного глифа для русского (и почему по умолчанию все не делается автоматом, ведь юзается freetype, которая должна обо всем заботится, нет ?). Вот ведь есть код:

Код: Выделить всё
   //Make the freetype system render the font
   int glyph_index = FT_Get_Char_Index( face, (unsigned char)character );
   
   FT_Load_Glyph( face, glyph_index, FT_LOAD_DEFAULT );
   FT_Render_Glyph( face->glyph, FT_RENDER_MODE_NORMAL );
   bitmap = &(face->glyph->bitmap);
   


Что тут не так и почему русский из-за этого не работает ? Я тут не вижу что бы в FT_Get_Char_Index какоето подобие какогото мапа загружалось, тупо 2 параметра: face и character (но не charactermap).

Первые 127 символов там это ISO-8859-1, остальные 128, судя по чуши которую он отображает, мапятся туда-же. Почините маппинг - будет русский.


А что за маппинг, куда-чего, как прога будет знать куда маппить и что. Т.е. я вообще сейчас абсолютно не понимаю, почему русский не работает, ведь есть шрифт с кирилицей, и юзается freetype, которая автоматом должна обо всем заботится, имхо

Ну и проверьте что у вас шрифты содержат кириллицу.

Содержат естна, это arial.ttf виндовый , посмотри если не лень на пару постов назад где fontcreatorа скрин всунут.
anny
Беспардонный Амигофлуд
Беспардонный Амигофлуд
 
Сообщения: 1267
Зарегистрирован: 05 дек 2004, 01:22

Re: Новый дискмаг о старых амижных играх

Сообщение anny 20 янв 2012, 19:57

@Q-master

И вот еще что не понятно кстати: Есть ttf , в нем кирилица, также там есть какие-то указатели которые говорят о том какой charmap где. А как же кодировка на которой текст написан ? Ну т.е. если я написал на koi8r, как опять-же freetype сопоставит эти символы с нужным чарсетом ? А если написано в cp1251 , то как ? А если еще в какой древности типа амижной кодировки русской старой ?

И вот еще в гугле нашел такую фразу:
Сначала создаем структуры цвета и координат и заполняем их значениями, а затем выводим надпись на английском и на русском. Заметьте, что на русском можно писать, если только у вас шрифт в соответствующей кодировке. Прилагаемый с исходниками шрифт Courier в кодировке KOI8-R.
Рекомендую загрузить исходники для этого урока и внимательно их изучить.


Т.е. "если у вас шрифт в соответствующей кодировке". В том смысле что видимо и кодировка в шрифте имеет место быть ? Особенно вот эта вот фраза "прилагаемый с исходниками шрифт Courier в кодировке KOI8-R", это как понимать ?

Я вот сейчас некоторые тесты делаю, и вижу что кодировка в шрифта есть. Ну т.е. кирилица распологается в разных местах в зависимости от кодировки, и это именно в самих шрифтах. Т.е. вот я имею сейчас тестовый пример, который через SDL_ttf (врапер для freetype), выводит в сдл окне текст: так вот не один шрифт из amigaos4 у меня по умолчанию нормально не отображает русский с этим примером, а вот специально сделанный courier.ttf , в той самой "в кодировке KOI8-R", работает, и по русски показывает. Что говорит о том, что в самом фотне в зависимости от кодировки и кирилица в разных местах. Странно только что вот специально сделанный courier с koi8r отображает все ок, а вот все дефолтные шрифты (и виндовые тоже), которые по идее cp1251 - хрена.
anny
Беспардонный Амигофлуд
Беспардонный Амигофлуд
 
Сообщения: 1267
Зарегистрирован: 05 дек 2004, 01:22

Re: Новый дискмаг о старых амижных играх

Сообщение Q-Master 20 янв 2012, 21:02

anny писал(а):Q-master
Никогда и не при каких обстоятельствах ? Т.е. чисто рисунки ?

Не рисунки, а векторные данные (глифы).

anny писал(а):А что такое charmap, где оно лежит, как его инициализировать, и как узнать индексы нужного глифа для русского (и почему по умолчанию все не делается автоматом, ведь юзается freetype, которая должна обо всем заботится, нет ?). Вот ведь есть код:

Код: Выделить всё
   //Make the freetype system render the font
   int glyph_index = FT_Get_Char_Index( face, (unsigned char)character );
   
   FT_Load_Glyph( face, glyph_index, FT_LOAD_DEFAULT );
   FT_Render_Glyph( face->glyph, FT_RENDER_MODE_NORMAL );
   bitmap = &(face->glyph->bitmap);
   


Что тут не так и почему русский из-за этого не работает ? Я тут не вижу что бы в FT_Get_Char_Index какоето подобие какогото мапа загружалось, тупо 2 параметра: face и character (но не charactermap).


Читаем документацию: FT_Get_Char_Index берет face и по карте соответствия 1-байтного символа 2-х байтному смещению внутри шрифта. В винде или линухе эти данные берутся скорее всего при инициализации либы, в амигаоси такого вероятно нет. Думаю что надо заюзать FT_Select_Charmap. см http://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#FT_Select_Charmap


anny писал(а):А что за маппинг, куда-чего, как прога будет знать куда маппить и что. Т.е. я вообще сейчас абсолютно не понимаю, почему русский не работает, ведь есть шрифт с кирилицей, и юзается freetype, которая автоматом должна обо всем заботится, имхо

см http://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#FT_Set_Charmap
Нужна как я понимаю 512 байтная табличка соответствия где код глифа = таблица[код символа*2]. Готовых уже полно.
WBR, Q-Master^MiR
Q-Master
Престарелый Амигодум
Престарелый Амигодум
 
Сообщения: 200
Зарегистрирован: 20 май 2002, 15:41
Откуда: Иваново, Россия

Re: Новый дискмаг о старых амижных играх

Сообщение anny 20 янв 2012, 21:12

@Q-master
Угу ок, буду иметь ввиду. Но пока я вот еще что нашел в гугле:

Кодировка тесно связана со шрифтами - шрифт обычно делается под конкретную кодировку, то есть, например в шрифте кодировки KOI8-R позиция 204 отведена под 'л'. В шрифте кодировки Windows-1251 буква 'л' находится совсем на другой позиции (235), а 204 отведена под букву 'М'.


Что опять говорит о том, что кодировка имеет место быть в шрифте. Т.е. она там одна, но разная. Из всех фонтов у меня сейчас только самодельный courier_koi8r.ttf взятый с инета работает и показывает. Другие же фонты отсасывают что в koi8r, что в cp1251. Причем юзают не директно freetype, а sdl_ttf, что враппер и тут я так понимаю не подразумевается использования всех этих set_charset.

Я пока все больше склоняюсь к тому, что просто стандартные виндовые шрифты, имеют кирилицу да, но они ее имеют вообще не в какой кодировке, а тупо подряд все по алфавиту. И вот для таких шрифтов естна надо парится с кеймапами и чарсетами. А можно тупо сделать фонтов в нужной кодировке и фсо.

Чекни ради интереса вот это вот. Вот я именно этим примером сейчас играюсь, и только их couier сделанные в koi8 и показывает тект в koi8. Они тут и шрифт прямиком указывают и тд. Посмотрел этот фонт через fontcreator, и там не по алфавиту кирилица вообще, а чтото типа : ю, а, б , ц, д, е, ф, г , х, и, й и тд. В то время как во всех остальных (виндовых и прочих) шрифтах все тупо по алфавиту.
anny
Беспардонный Амигофлуд
Беспардонный Амигофлуд
 
Сообщения: 1267
Зарегистрирован: 05 дек 2004, 01:22

Re: Новый дискмаг о старых амижных играх

Сообщение Q-Master 20 янв 2012, 21:23

anny писал(а):Я вот сейчас некоторые тесты делаю, и вижу что кодировка в шрифта есть. Ну т.е. кирилица распологается в разных местах в зависимости от кодировки, и это именно в самих шрифтах. Т.е. вот я имею сейчас тестовый пример, который через SDL_ttf (врапер для freetype), выводит в сдл окне текст: так вот не один шрифт из amigaos4 у меня по умолчанию нормально не отображает русский с этим примером, а вот специально сделанный courier.ttf , в той самой "в кодировке KOI8-R", работает, и по русски показывает. Что говорит о том, что в самом фотне в зависимости от кодировки и кирилица в разных местах. Странно только что вот специально сделанный courier с koi8r отображает все ок, а вот все дефолтные шрифты (и виндовые тоже), которые по идее cp1251 - хрена.


Идея ттфа в том что данные там хранятся в формате уникод. Те спецподготовленные шрифты формально - хрень. Все виндовые шрифты это стандартный ттф и для получения 1251 из него надо сконвертить значение чара в 1251 в уникод и выдернуть нужный глиф. Я вообще не очень понимаю какого фига в журнале прямые вызовы во фритайп. Проще реально заюзать SDL_ttf, конвертнуть все тексты в utf8 и спокойно показывать их через TTF_RenderUTF8_Solid. Гемороя будет в разы меньше.

anny писал(а):Что опять говорит о том, что кодировка имеет место быть в шрифте. Т.е. она там одна, но разная. Из всех фонтов у меня сейчас только самодельный courier_koi8r.ttf взятый с инета работает и показывает. Другие же фонты отсасывают что в koi8r, что в cp1251. Причем юзают не директно freetype, а sdl_ttf, что враппер и тут я так понимаю не подразумевается использования всех этих set_charset.

Я пока все больше склоняюсь к тому, что просто стандартные виндовые шрифты, имеют кирилицу да, но они ее имеют вообще не в какой кодировке, а тупо подряд все по алфавиту. И вот для таких шрифтов естна надо парится с кеймапами и чарсетами. А можно тупо сделать фонтов в нужной кодировке и фсо.

Чекни ради интереса вот это вот. Вот я именно этим примером сейчас играюсь, и только их couier сделанные в koi8 и показывает тект в koi8. Они тут и шрифт прямиком указывают и тд. Посмотрел этот фонт через fontcreator, и там не по алфавиту кирилица вообще, а чтото типа : ю, а, б , ц, д, е, ф, г , х, и, й и тд. В то время как во всех остальных (виндовых и прочих) шрифтах все тупо по алфавиту.

Блин. Ну естественно в кодировке 1251 буква л будет не в том месте где в кои-8. И даже не в том где в 866й. НО! ТТФ шрифты используют УНИКОД. Для уникода кириллица находится по смещениям начиная с 0x0400. http://www.utf8-chartable.de/unicode-utf8-table.pl?start=1024 В утф-16 немного по другому, но тебе это все ни к чему. Поэтому у тебя шрифт, получающий на вход число 0x100 будет искать его совсем не там где ты думаешь и это будет в результате нихрена не кириллица. Ну блин, у тебя-же интернет есть, ну почитай-же уже маны и заюзай таки TTF_RenderUTF8_*(), либо смотри как правильно подсунуть фритайпу таблицу конвертации 1251 в уникод. В этом случае так-же все будет отображаться верно.
WBR, Q-Master^MiR
Q-Master
Престарелый Амигодум
Престарелый Амигодум
 
Сообщения: 200
Зарегистрирован: 20 май 2002, 15:41
Откуда: Иваново, Россия

Пред.След.

Вернуться в Софт Classic Amiga

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 30

cron