Pango

Started by josebita, December 29, 2008, 12:19:47 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

josebita

Hola:

Entre ayer y hoy (y con un poquito de ayuda :)) he creado una librería de interfaz a pango. Pango es el sistema de renderizado de textos que se usa en gnome, uno de los dos escritorios más utilizados en linux.
Bueno, la gracia es que soporta muchas de las cosas que soporta HTML a la hora de escribir textos, es decir, es válido algo de la forma:
[code language="html4strict"]<span font_family="Arial" size="xx-large" color="#0000ff"><u>Hello</u>, World!</span>[/code]
La lista completa de lo soportado está aquí.
Adjunta dejo el código de una primera versión de la librería y la versión binaria para Linux de 32 bits junto con un pequeño código de ejemplo bennu. Debería funcionar bien en 32 bits de color, pero no funciona bien en 16 bits (Si alguien quisiera ayudar, splinter, creo que el problema está en los valores de las masks al crear surface en 16 bits, pero no estoy seguro y tampoco sé los valores que deberían ser... :) ).

En cuanto arregle el problema con los 16 bits tenga un rato intentaré compilarla para windows, ok? ¡Ya tengo los binarios para Windows! (rezo para que no os den problemas, son un infierno de compilar, leed el post más abajo).
Espero que sea útil.

Además, dejo un par de screenshots del programa de ejemplo:
Se pueden poner superíndices y subíndices:

Y se pueden renderizar alfabetos no latinos:


[Edito] Acabo de actualizar el ejemplo con código válido para 16 y 32 bits de color.
[Edito] Podeis probar los binarios de windows desde aquí.

SplinterGU

Excelente... luce muy bien...

en 16 bits es 565...
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

josebita

Ya, he copiado (por si acaso) los masks de libgrbase/g_bitmap.c pero nada. Aparece siempre un fondo de color sólido detrás de las letras y las letras en otro color encima (a veces no se aprecian casi las letras).
En el caso de 16 bits creo la surface con:
SDL_CreateRGBSurface(0, w, h, 16, ((0xFF) >> 3) << 11, ((0xFF) >> 2) << 5 , (0xFF) >> 3, 0xFF);
Luego convierto la surface a un gráfico como me dijiste:
bitmap_new_ex(bitmap_next_code(), surface->w, surface->h, surface->format->BitsPerPixel, surface->pixels, surface->pitch);
Pero a la hora de mostrarlo en pantalla... aparece como un rectángulo de fondo sólido y las letras en otro que nada tiene que ver con el pedido.
Lo que me extraña también es que haya diferencia entre lo que saca SDL directamente al bmp y lo que muestra bennu en pantalla...

¿Ideas?. ¿Debería establecer como transparentes los pixels del fondo?.
Gracias por adelantado

SplinterGU

podrias poner una captura? asi me doy una idea.
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

josebita

El BMP que saca SDL:

El PNG que saca Bennu:


Si te fijas, en el segundo se aprecian, aunque mal, sobre el fondo las letras.

SplinterGU

1) no tenes que liberar el surface, por eso aparece basura en el grafico... la funcion bitmap_new_ex crea un bitmap falso, sin alocar memoria para la data, usa la que le pasas vos que ya esta alocada... otra opcion si necesitas liberar el surface es hacer un clone del mapa antes de eliminar el surface y obviamente borrar el mapa fake creado, en ese caso no debes usar la funcion bitmap_next_code() en la bitmap_new_ex

2) Lamento decir que creo que el BMP que decis saca SDL es un BMP viejo, porque acabo de descomentar de tu codigo el SaveBMP y da lo mismo que da Bennu... o sea, todo color solido... por otra parte si cambiar los colores en la linea del makeup, poniendo rojo absoluto, verde o azul, el color es correcto, asi que no es problema de mascaras, me temo que es un problema de la pango... tambien hay funciones de la pango que no funcionan, como la creatergbsurfacedraw o algo asi, que deberia crear y dibujar a la vez, pero no lo hace...
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

SplinterGU

#6
Bien asi funciona...


/*
*  Fenix - Videogame compiler/interpreter
*  Current release       : FENIX - PROJECT 1.0 - R 0.82
*  Last stable release   :
*  Project documentation : http://fenix.divsite.net
*
*
*  This program is free software; you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation; either version 2 of the License, or
*  (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with this program; if not, write to the Free Software
*  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
*
*  Copyright © 2008/2009 Joseba García Echebarria
*
*/

/*
* FILE        : image.c
* DESCRIPTION : sdlf_Image Fenix support DLL
*/

#ifdef WIN32
#include <windows.h>
#include <winbase.h>
#endif

#include <stdlib.h>
#include <math.h>
#include <stdio.h>
#include <memory.h>
#include <SDL_Pango.h>
/* BennuGD stuff */
#include <bgddl.h>
#include <xstrings.h>
#include <libgrbase.h>
#include <g_video.h>

/* This function initializes Pango, and renders the given text, then return its graph */
static int bgd_pango_render(INSTANCE *my, int * params)
{
SDLPango_Context *context;
SDL_Surface *surface=NULL;
GRAPH *gr, *gr1;
int w, h;

// Initialize BennuGD graphics & Pango, if they're not already started
if(! scr_initialized) gr_init(320, 240);
if(! SDLPango_WasInit () ) SDLPango_Init();

// This "context" is our reference object when dealing with Pango
// More initialization stuff: set default values...
context = SDLPango_CreateContext();

SDLPango_SetDefaultColor(context, MATRIX_TRANSPARENT_BACK_WHITE_LETTER);
SDLPango_SetMinimumSize(context, -1, -1);

// Now, give Pango the text we want to render, UTF-8 with HTML-like markup
SDLPango_SetMarkup(context, string_get(params[0]), -1);
string_discard(params[0]);

// Actually draw the surface
w = SDLPango_GetLayoutWidth(context);
h = SDLPango_GetLayoutHeight(context);

if(screen->format->BitsPerPixel == 16) {
surface = SDL_CreateRGBSurface(0, w, h, 16, (((Uint32)0xff) >> 3) << 11, (((Uint32)0xff) >> 2) << 5 , ((Uint32)0xff) >> 3, 0);
} else if (screen->format->BitsPerPixel == 32) {
surface = SDL_CreateRGBSurface(0, w, h, 32, (Uint32)(255 << (8*2)), (Uint32)(255 << (8*1)), (Uint32)(255 << 8*0), (Uint32)(255 << 8*3) );
}

if(surface == NULL) {
fprintf(stderr, "Pango binding error: Screen depth not supported.\n");
return -1;
}

SDLPango_Draw(context, surface, 0, 0);

// For debug purposes: save the surface to a BMP prior to conversion
SDL_SaveBMP(surface, "pango.bmp");

// Convert the surface into a bgd graph
gr1 = bitmap_new_ex(0, surface->w, surface->h, surface->format->BitsPerPixel, surface->pixels, surface->pitch);
gr = bitmap_clone(gr1);
    bitmap_destroy(gr1);
    gr->code = bitmap_next_code() ;
    grlib_add_map( 0, gr ) ;

// Free things
SDLPango_FreeContext(context);
SDL_FreeSurface(surface);

return gr->code;
}

DLSYSFUNCS __bgdexport( pango, functions_exports )[] =
{
{"PANGO_RENDER", "S", TYPE_DWORD, bgd_pango_render },
{0, 0, 0, 0}
};



#ifdef __VERSION__
import "mod_say";
import "mod_key";
import "mod_video";
import "mod_map";
import "mod_mouse";
import "mod_text";
#endif

import "pango";

Process main()
Private
int retval=0;
string markup = "e=mc< sup>2< /sup>";

Begin
set_mode(640, 480, 16, MODE_WINDOW);
if(argc == 2)
markup = '< span font_family="Serif" size="xx-large" foreground="blue" background="black">< u>'+argv[1]+'< /u>< /span>';
end;

say("Going to render:");
say(markup);

graph = pango_render(markup);

x = 200;
y = 100;
write_var(0, 0, 0, 0, x);
write_var(0, 0, 10, 0, y);
while(! key(_esc))
x = mouse.x;
y = mouse.y;
FRAME;
End;
unload_map(0, graph);
End;


El problema esta en la pango que si no le pones el color de fondo, dibuja todo con el color del texto.

Yo te diria que le cambies el credito, esto no es para Fenix, ni se llama image.c, etc, etc..
Y otra cosa que te diria es que le pongas chequeos a las funciones que agregue yo, creo que las que tenias vos no faltaba nada, pero bueno, ya no recuerdo... chequeatelo...

La verdad que esta muy bien...

NOTA: Fijate que en el ejemplo agregue un espacio a los "<" ya que sino no sale el codigo... suerte....
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

osk

¡Qué guay! Nos podremos olvidar entonces de set_text_color, set_text_position y cosas así, ¿no?
¿Qué tal incluir esta librería dentro de las oficiales?...
Y una pregunta: la versión para windows, ¿no requiere tener instalado previamente nada extra rollo librerías gtk o algo?
Venga, hasta luego!!

josebita

:) Splinter, las cabeceras las he copiado del image y ni me he dado cuenta. Y lo del color sólido: algo había tocado.... En fin, ahora pruebo tu código y os cuento.

Osk: En windows habría que instalar/distribuir con el juego SDL_Pango, Pango y creo que alguna cosilla más. No lo sé seguro, pero en cuanto lo tenga en windows lo miro.
En principio, se podría reemplazar cierta parte de la funcionalidad de write aunque no completamente y tampoco funcionaría igual (la función devuelve un mapa, no un texto). Tiene muchos matices.
En cambio, gana mucho en funcionalidad.

josebita

Acabo de actualizar el adjunto con el código arreglado de Splinter y he cambiado el archivo hello_world para que efectivamente diga "Hello world!" en japonés.

A ver si hago un poco de código bennu para una cabecera que añada unas funciones tipo write() con los alineados y eso, que eso es fácil.

PD: Gracias Splinter, que no te lo he dicho.

SplinterGU

Pues de nada... :)
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

darío

Estupendo josebita  :D. Esto facilitará mucho hacer textos complejos sin mucho esfuerzo... además, que HTML sabemos casi todos jeje.
My sites:
Smart Fpg Editor - Painless FPG Edition for Bennu and PixTudio
fenixlib - .NET support for manipulating PixTudio, Bennu and Div graphic formats

Prg

wow, y ¿para cuándo estaría la de windows?

me llama mucho la atención, se ve muy bien.
en humos puedes mover la camara con los cursores. es necesario para los niveles a partir del dos :)

josebita

Estoy con la de windows, pero me da problemas de librerías. A ver si los arreglo.

Feliz año a todos.

josebita

Acabo de subir los binarios de windows compilados con mingw32. Son un infierno de compilar, porque al final me he tenido que compilar todos los paquetes a mano, como indican en este tutorial sobre TuxPaint.
Lo primero que hay que hacer es ejecutar el binario "fc-list.exe" sólo una vez, que creará el fichero "etc/fonts/.fonts-cache-1". Ese fichero es una lista de vuestras fuentes, así que aseguraros de borrarlo al distribuir lo que hagais con esta librería y añadir al instalador una orden de ejecución del fc-list.exe durante la instalación.
Después, debería poderse descomprimir, compilar y listo.
Lo he probado con la wip15c2 en un windows xp de 32 bits y va.
Si se queja de que faltan librerías, igual me he dejado algo por subir. Avisad y lo busco.

En fin, espero que haya merecido la pena el curro de compilar esto y que lo useis mucho :)