OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Четверг, 28 Март, 2024 20:46

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 4 ] 
Автор Сообщение
СообщениеДобавлено: Четверг, 22 Май, 2014 12:43 

Зарегистрирован: Четверг, 17 Ноябрь, 2005 11:51
Сообщения: 2935
Откуда: г. Ярославль
Там проблема вот в чём. Установка размера шрифта делается в момент открытия файла шрифта, в TTF_OpenFont.
И всё. Других возможностей "на ходу" изменить размер нет. А ведь в составном документе может быть большое разнообразие шрифтов и размеров. Не станешь же каждый раз открывать один и тот же шрифт с нужным размером.

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


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Четверг, 22 Май, 2014 21:02 

Зарегистрирован: Пятница, 26 Август, 2011 23:42
Сообщения: 339
Откуда: Россия, Самара
А если загрузить шрифт в память, и открывать в памяти.

Пример загружаем с помощью SDL_RWFromFile. И первым параметром в TTF_OpenFontRW, передаём созданный указатель на память.

Шрифт загружается один раз, а открывается с нужным размером много раз.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Четверг, 22 Май, 2014 22:49 

Зарегистрирован: Пятница, 26 Август, 2011 23:42
Сообщения: 339
Откуда: Россия, Самара
Сэкономить не получится, вот исходник функций

Код:
TTF_Font* TTF_OpenFontRW( SDL_RWops *src, int freesrc, int ptsize )
{
    return TTF_OpenFontIndexRW(src, freesrc, ptsize, 0);
}


Код:
TTF_Font* TTF_OpenFontIndexRW( SDL_RWops *src, int freesrc, int ptsize, long index )
{
    TTF_Font* font;
    FT_Error error;
    FT_Face face;
    FT_Fixed scale;
    FT_Stream stream;
    FT_CharMap found;
    Sint64 position;
    int i;

    if ( ! TTF_initialized ) {
        TTF_SetError( "Library not initialized" );
        if ( src && freesrc ) {
            SDL_RWclose( src );
        }
        return NULL;
    }

    if ( ! src ) {
        TTF_SetError( "Passed a NULL font source" );
        return NULL;
    }

    /* Check to make sure we can seek in this stream */
    position = SDL_RWtell(src);
    if ( position < 0 ) {
        TTF_SetError( "Can't seek in stream" );
        if ( freesrc ) {
            SDL_RWclose( src );
        }
        return NULL;
    }

    font = (TTF_Font*) malloc(sizeof *font);
    if ( font == NULL ) {
        TTF_SetError( "Out of memory" );
        if ( freesrc ) {
            SDL_RWclose( src );
        }
        return NULL;
    }
    memset(font, 0, sizeof(*font));

    font->src = src;
    font->freesrc = freesrc;

    stream = (FT_Stream)malloc(sizeof(*stream));
    if ( stream == NULL ) {
        TTF_SetError( "Out of memory" );
        TTF_CloseFont( font );
        return NULL;
    }
    memset(stream, 0, sizeof(*stream));

    stream->read = RWread;
    stream->descriptor.pointer = src;
    stream->pos = (unsigned long)position;
    stream->size = (unsigned long)(SDL_RWsize(src) - position);

    font->args.flags = FT_OPEN_STREAM;
    font->args.stream = stream;

    error = FT_Open_Face( library, &font->args, index, &font->face );
    if ( error ) {
        TTF_SetFTError( "Couldn't load font file", error );
        TTF_CloseFont( font );
        return NULL;
    }
    face = font->face;

    /* Set charmap for loaded font */
    found = 0;
    for (i = 0; i < face->num_charmaps; i++) {
        FT_CharMap charmap = face->charmaps[i];
        if ((charmap->platform_id == 3 && charmap->encoding_id == 1) /* Windows Unicode */
         || (charmap->platform_id == 3 && charmap->encoding_id == 0) /* Windows Symbol */
         || (charmap->platform_id == 2 && charmap->encoding_id == 1) /* ISO Unicode */
         || (charmap->platform_id == 0)) { /* Apple Unicode */
            found = charmap;
            break;
        }
    }
    if ( found ) {
        /* If this fails, continue using the default charmap */
        FT_Set_Charmap(face, found);
    }

    /* Make sure that our font face is scalable (global metrics) */
    if ( FT_IS_SCALABLE(face) ) {
        /* Set the character size and use default DPI (72) */
        error = FT_Set_Char_Size( font->face, 0, ptsize * 64, 0, 0 );
        if ( error ) {
            TTF_SetFTError( "Couldn't set font size", error );
            TTF_CloseFont( font );
            return NULL;
        }

        /* Get the scalable font metrics for this font */
        scale = face->size->metrics.y_scale;
        font->ascent  = FT_CEIL(FT_MulFix(face->ascender, scale));
        font->descent = FT_CEIL(FT_MulFix(face->descender, scale));
        font->height  = font->ascent - font->descent + /* baseline */ 1;
        font->lineskip = FT_CEIL(FT_MulFix(face->height, scale));
        font->underline_offset = FT_FLOOR(FT_MulFix(face->underline_position, scale));
        font->underline_height = FT_FLOOR(FT_MulFix(face->underline_thickness, scale));

    } else {
        /* Non-scalable font case.  ptsize determines which family
         * or series of fonts to grab from the non-scalable format.
         * It is not the point size of the font.
         * */
        if ( ptsize >= font->face->num_fixed_sizes )
            ptsize = font->face->num_fixed_sizes - 1;
        font->font_size_family = ptsize;
        error = FT_Set_Pixel_Sizes( face,
                face->available_sizes[ptsize].width,
                face->available_sizes[ptsize].height );
        if ( error ) {
            TTF_SetFTError( "Couldn't set font size", error );
            TTF_CloseFont( font );
            return NULL;
        }

        /* With non-scalale fonts, Freetype2 likes to fill many of the
         * font metrics with the value of 0.  The size of the
         * non-scalable fonts must be determined differently
         * or sometimes cannot be determined.
         * */
        font->ascent = face->available_sizes[ptsize].height;
        font->descent = 0;
        font->height = face->available_sizes[ptsize].height;
        font->lineskip = FT_CEIL(font->ascent);
        font->underline_offset = FT_FLOOR(face->underline_position);
        font->underline_height = FT_FLOOR(face->underline_thickness);
    }

    if ( font->underline_height < 1 ) {
        font->underline_height = 1;
    }

#ifdef DEBUG_FONTS
    printf("Font metrics:\n");
    printf("\tascent = %d, descent = %d\n",
        font->ascent, font->descent);
    printf("\theight = %d, lineskip = %d\n",
        font->height, font->lineskip);
    printf("\tunderline_offset = %d, underline_height = %d\n",
        font->underline_offset, font->underline_height);
    printf("\tunderline_top_row = %d, strikethrough_top_row = %d\n",
        TTF_underline_top_row(font), TTF_strikethrough_top_row(font));
#endif

    /* Initialize the font face style */
    font->face_style = TTF_STYLE_NORMAL;
    if ( font->face->style_flags & FT_STYLE_FLAG_BOLD ) {
        font->face_style |= TTF_STYLE_BOLD;
    }
    if ( font->face->style_flags & FT_STYLE_FLAG_ITALIC ) {
        font->face_style |= TTF_STYLE_ITALIC;
    }

    /* Set the default font style */
    font->style = font->face_style;
    font->outline = 0;
    font->kerning = 1;
    font->glyph_overhang = face->size->metrics.y_ppem / 10;
    /* x offset = cos(((90.0-12)/360)*2*M_PI), or 12 degree angle */
    font->glyph_italics = 0.207f;
    font->glyph_italics *= font->height;

    return font;
}


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Четверг, 22 Май, 2014 22:56 

Зарегистрирован: Четверг, 17 Ноябрь, 2005 11:51
Сообщения: 2935
Откуда: г. Ярославль
И что сие значит?

Я ещё поглядел мельком исходники SDL_RTF, там вроде как RTF-текст выводится на экран. Судя по всему, алгоритм сперва определяет все шрифты из RTF-документа и загружает их в память. А только потом рендерит.

Для задачи рендера составного документа BlackBox, видимо, придётся поступать так же. Шрифтов в документе может быть много, и тормозить рендер загрузкой очередного шрифта нехорошо, надо предварительно загрузить все начертания.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 4 ] 

Часовой пояс: UTC + 3 часа


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

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


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Вся информация, размещаемая участниками на конференции (тексты сообщений, вложения и пр.) © 2005-2024, участники конференции «OberonCore», если специально не оговорено иное.
Администрация не несет ответственности за мнения, стиль и достоверность высказываний участников, равно как и за безопасность материалов, предоставляемых участниками во вложениях.
Без разрешения участников и ссылки на конференцию «OberonCore» любое воспроизведение и/или копирование высказываний полностью и/или по частям запрещено.
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB