[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[paragui-cvs] CVS: paragui/plugins/pango pango.cpp,1.1.2.1,1.1.2.2
From: |
Teunis Peters <address@hidden> |
Subject: |
[paragui-cvs] CVS: paragui/plugins/pango pango.cpp,1.1.2.1,1.1.2.2 |
Date: |
Fri, 08 Nov 2002 06:22:04 -0500 |
Update of /cvsroot/paragui/paragui/plugins/pango
In directory subversions:/tmp/cvs-serv13762/plugins/pango
Modified Files:
Tag: devel-opengl
pango.cpp
Log Message:
Add in greyscale and bitmap images (still largely untested)
also now pango future plugin now renders... :)
Index: pango.cpp
===================================================================
RCS file: /cvsroot/paragui/paragui/plugins/pango/Attic/pango.cpp,v
retrieving revision 1.1.2.1
retrieving revision 1.1.2.2
diff -C2 -r1.1.2.1 -r1.1.2.2
*** pango.cpp 6 Nov 2002 22:18:46 -0000 1.1.2.1
--- pango.cpp 8 Nov 2002 11:22:01 -0000 1.1.2.2
***************
*** 5,10 ****
--- 5,417 ----
#include "paragui.h"
+ #include "pgapplication.h"
+ #include "pgbutton.h"
+ #include "pgthemewidget.h"
+ #include "pglog.h"
+ #include "pgdraw.h"
+ #include "pgdriver.h"
+
+ extern "C" {
+ #include <pango/pango.h>
+ #include <pango/pangoft2.h>
+ };
+
+ char *prog_name = NULL;
+
+ bool exit_handler(PG_Button* button) {
+ PG_Application::GetInstance().Quit();
+ return true;
+ }
+
+ typedef struct _Paragraph Paragraph;
+ struct _Paragraph {
+ string text;
+ int length;
+ int height; /* Height, in pixels */
+ PangoLayout *layout;
+ };
+ typedef vector<Paragraph*> paralist;
+ // typedef GList paralist;
+
+ static PangoFontDescription *font_description;
+ PangoContext *context;
+ paralist paragraphs;
+
+ class PangoWidget : public PG_ThemeWidget {
+ public:
+ PangoWidget(PG_Widget* parent, PG_Rect r, string data, string lang);
+ ~PangoWidget();
+
+ protected:
+ // our custom event handler to redraw our stuff
+ void eventBlit(PG_Draw::PG_DrawableSurface* surface, const PG_Rect& src,
const PG_Rect& dst);
+
+ private:
+ string data;
+ string lang;
+ PG_Draw::PG_DrawableSurface* surf;
+
+ void updateRender();
+ };
+
+ /* Take a UTF8 string and break it into paragraphs on \n characters
+ */
+ static paralist split_paragraphs(const char *text)
+ {
+ const char *p = text;
+ const char *next;
+ gunichar wc;
+ paralist result;
+ // GList *result = NULL;
+ const char *last_para = text;
+
+ // fprintf(stderr, "%s:%i data \'%s\'\n", __FUNCTION__, __LINE__, text);
+ while (*p)
+ {
+ wc = g_utf8_get_char (p);
+ next = g_utf8_next_char (p);
+ if (wc == (gunichar)-1)
+ {
+ fprintf (stderr, "%s: Invalid character in input\n", g_get_prgname
());
+ wc = 0;
+ }
+ // fprintf(stderr, "%s:%i data [%p]=%i\n", __FUNCTION__, __LINE__, p,
wc);
+ if (!*p || !wc || wc == '\n' || !*next)
+ {
+ /* Paragraph *para = g_new(Paragraph, 1); */
+ Paragraph *para = new Paragraph;
+ para->length = (int)(p - last_para);
+ // fprintf(stderr, "%s:%i data [%i]=\'%s\'\n", __FUNCTION__,
__LINE__, para->length, last_para);
+ para->text = std::string(last_para, para->length);
+ para->layout = pango_layout_new(context);
+ pango_layout_set_text(para->layout, para->text.c_str(), para->length);
+ para->height = 0;
+
+ last_para = next;
+
+ // result = g_list_prepend (result, para);
+ result.push_back(para);
+ }
+ if (!wc) /* incomplete character at end */
+ break;
+ p = next;
+ // fprintf(stderr, "%s:%i data [%p]\n", __FUNCTION__, __LINE__, p);
+ }
+
+ // fprintf(stderr, "%s:%i data %i\n", __FUNCTION__, __LINE__,
result.size());
+ // return g_list_reverse (result);
+ return result;
+ }
+
+ void PangoWidget::updateRender() {
+ /* Paragraph *para = (Paragraph *)(paragraphs->data); */
+ if (paragraphs.size() == 0) {
+ PG_LogERR("ParaGUI[%s]: %s:%i no data", __FILE__, __FUNCTION__, __LINE__);
+ return;
+ };
+ int x_start = 0;
+ int y_start = 0;
+ int height = 0;
+ int width = 0;
+ FT_Bitmap bitmap;
+ Paragraph* para;
+ para = paragraphs[0];
+ PangoDirection base_dir = pango_context_get_base_dir(context);
+ PangoRectangle logical_rect;
+
+ /* first run - obtain heights on everything */
+ for (paralist::iterator v=paragraphs.begin(); v!=paragraphs.end(); v++) {
+ para = *v;
+ pango_layout_set_alignment (para->layout,
+ base_dir == PANGO_DIRECTION_LTR ?
PANGO_ALIGN_LEFT : PANGO_ALIGN_RIGHT);
+ pango_layout_set_width(para->layout, Width() * PANGO_SCALE);
+
+ pango_layout_get_extents (para->layout, NULL, &logical_rect);
+
+ width = PANGO_PIXELS(logical_rect.width);
+ height = PANGO_PIXELS(logical_rect.height);
+
+ para->height = height;
+ };
+ PG_LogMSG("%s:%s:%i size %ix%i\n", __FILE__, __FUNCTION__, __LINE__, width,
height);
+
+ #if 0
+ if (surf == NULL) {
+ surf = app.GetDrawingEnvironment()->CreateGrey(width, height);
+ } else if ((surf->GetWidth() < width) || (surf->GetHeight() < height)) {
+ delete surf;
+ surf = app.GetDrawingEnvironment()->CreateGrey(width, height);
+ };
+ #endif
+
+ /* if (height + para->height >= y_start) */
+ surf->Lock();
+ bitmap.rows = surf->GetHeight(); /* para->height; */
+ bitmap.width = surf->GetWidth();
+ bitmap.pitch = surf->GetPitch();
+ bitmap.buffer = (unsigned char*)surf->GetPixels();
+ bitmap.num_grays = 256;
+ bitmap.pixel_mode = ft_pixel_mode_grays; /* mono */
+ for (paralist::iterator v=paragraphs.begin(); v!=paragraphs.end(); v++) {
+ para = *v;
+ // PG_LogERR("ParaGUI[%s]: %s:%i rendering %s height %i", __FILE__,
__FUNCTION__, __LINE__, para->text.c_str(), para->height);
+ pango_ft2_render_layout (&bitmap, para->layout, x_start, y_start);
+ // PG_LogERR("ParaGUI[%s]: %s:%i rendering done...", __FILE__,
__FUNCTION__, __LINE__);
+ y_start += para->height + 1;
+ }
+ surf->Unlock();
+ };
+
+ PangoWidget::PangoWidget(PG_Widget* parent, PG_Rect r, string s, string l)
+ : PG_ThemeWidget(parent, r), data(s), lang(l) {
+ // surf = NULL;
+ PG_Application& app = PG_Application::GetInstance();
+ surf = app.GetDrawingEnvironment()->CreateGrey(Width(), Height());
+
+ updateRender();
+ }
+
+ PangoWidget::~PangoWidget() {
+ if (surf != NULL) delete surf;
+ surf = NULL;
+ }
+
+ void PangoWidget::eventBlit(PG_Draw::PG_DrawableSurface* surface,
+ const PG_Rect& src, const PG_Rect& dst) {
+ my_srfScreen->FillRect(dst, 0);
+ if (surf == NULL) { return; };
+
+ // PG_LogDBG("ParaGUI[%s]: %s:%i", __FILE__, __FUNCTION__, __LINE__);
+ PG_Rect my_src;
+ PG_Rect my_dst;
+
+ GetClipRects(my_src, my_dst, *this);
+ PG_Widget::eventBlit(surf, my_src, my_dst);
+ }
+
+ char* read_file(char *name)
+ {
+ GString *inbuf;
+ FILE *file;
+ char *text;
+ #define BUFSIZE 1024
+ char buffer[BUFSIZE];
+
+ file = fopen (name, "r");
+ if (!file)
+ {
+ fprintf (stderr, "%s: Cannot open %s\n", g_get_prgname (), name);
+ return NULL;
+ }
+
+ inbuf = g_string_new(NULL);
+ while (1)
+ {
+ char *bp = fgets(buffer, BUFSIZE-1, file);
+ if (ferror (file))
+ {
+ fprintf(stderr, "%s: Error reading %s\n", g_get_prgname (), name);
+ g_string_free (inbuf, TRUE);
+ return NULL;
+ }
+ else if (bp == NULL)
+ break;
+
+ g_string_append (inbuf, buffer);
+ }
+
+ fclose (file);
+
+ text = inbuf->str;
+ g_string_free (inbuf, FALSE);
+
+ #undef BUFSIZE
+ return text;
+ }
+
+ /* This is a way of telling whether or not to use hardware surfaces */
+ Uint32 FastestFlags(Uint32 flags, int width, int height, int bpp)
+ {
+ const SDL_VideoInfo *info;
+
+ /* Hardware acceleration is only used in fullscreen mode */
+ flags |= SDL_FULLSCREEN;
+
+ /* Check for various video capabilities */
+ info = SDL_GetVideoInfo();
+ if ( info->blit_hw_CC && info->blit_fill ) {
+ /* We use accelerated colorkeying and color filling */
+ flags |= SDL_HWSURFACE;
+ }
+ /* If we have enough video memory, and will use accelerated
+ blits directly to it, then use page flipping.
+ */
+ if ( (flags & SDL_HWSURFACE) == SDL_HWSURFACE ) {
+ /* Direct hardware blitting without double-buffering
+ causes really bad flickering.
+ */
+ if ( info->video_mem*1024 > (Uint32)(height*width*bpp/8) ) {
+ flags |= SDL_DOUBLEBUF;
+ } else {
+ flags &= ~SDL_HWSURFACE;
+ }
+ }
+
+ /* Return the flags */
+ return(flags);
+ }
int main(int argc, char* argv[]) {
+
+ int dpi_x = 100, dpi_y = 100;
+ string init_family = "sans";
+ int init_scale = 14; /* 24; */
+ PangoDirection init_dir = PANGO_DIRECTION_LTR;
+ string text;
+ string lang;
+
+ int width, height;
+ Uint8 video_bpp;
+ Uint32 videoflags;
+
+ char *prog_name = g_path_get_basename (argv[0]);
+ PG_Application& app = PG_Application::GetInstance();
+ app.SetEmergencyQuit(true);
+ PG_VideoDriver* gldriver = NULL;
+
+ text = std::string("Hello, World");
+ // Arabic
+ // text =
"�����������";
+ // Japanese
+ // text = "�����,
コï¾��¾��¾��¾� é¨��©�;
+ // Hebrew
+ // text = "����;
+ // Chinese (Cantonese)
+ // text = "��, 你好";
+
+ // lang = "en_US";
+ // lang = "jp";
+ // lang = "ar";
+ lang = g_strdup("en-US");
+
+ videoflags = SDL_SWSURFACE|SDL_DOUBLEBUF | SDL_ANYFORMAT;
+ width = 640;
+ height = 480;
+ video_bpp = 16;
+ while ( argc > 1 ) {
+ --argc;
+ if ( strcmp(argv[argc-1], "-width") == 0 ) {
+ width = atoi(argv[argc]);
+ --argc;
+ } else if ( strcmp(argv[argc-1], "-height") == 0 ) {
+ height = atoi(argv[argc]);
+ --argc;
+ } else if ( strcmp(argv[argc-1], "-bpp") == 0 ) {
+ video_bpp = atoi(argv[argc]);
+ videoflags &= ~SDL_ANYFORMAT;
+ --argc;
+ } else if ( strcmp(argv[argc], "-fast") == 0 ) {
+ videoflags = FastestFlags(videoflags, width, height, video_bpp);
+ } else if ( strcmp(argv[argc], "-hw") == 0 ) {
+ videoflags ^= SDL_HWSURFACE;
+ } else if ( strcmp(argv[argc], "-flip") == 0 ) {
+ videoflags ^= SDL_DOUBLEBUF;
+ } else if ( strcmp(argv[argc], "-fullscreen") == 0 ) {
+ videoflags ^= SDL_FULLSCREEN;
+ } else if(strcmp(argv[argc], "-gl") == 0) {
+ #ifdef HAVE_OPENGL
+ PG_LogMSG("Initializing OpenGL driver\n");
+ gldriver = new PG_VideoDriver(app, PG_GLVIDEO);
+ #endif
+ } else if(strcmp(argv[argc], "-dummy") == 0) {
+ #ifdef HAVE_DUMMYVIDEO
+ PG_LogMSG("Initializing Dummy driver\n");
+ gldriver = new PG_VideoDriver(app, PG_DUMMYVIDEO);
+ #endif
+ } else if(strcmp(argv[argc], "-DX") == 0) {
+ #ifdef HAVE_DIRECTX
+ PG_LogMSG("Initializing DirectX driver\n");
+ gldriver = new PG_VideoDriver(app, PG_DXVIDEO);
+ #endif
+ } else if (strcmp(argv[argc-1], "--family") == 0) {
+ init_family = std::string(argv[argc]);
+ --argc;
+ } else if (strcmp(argv[argc-1], "--scale") == 0) {
+ init_scale = atoi(argv[argc]);
+ --argc;
+ } else if (strcmp(argv[argc-1], "-file") == 0) {
+ // PG_LogMSG("%s:%s:%i\n", __FILE__, __FUNCTION__, __LINE__);
+ text = std::string(read_file(argv[argc]));
+ --argc;
+ } else if (strcmp(argv[argc-1], "-text") == 0) {
+ // PG_LogMSG("%s:%s:%i\n", __FILE__, __FUNCTION__, __LINE__);
+ text = std::string(argv[argc]);
+ --argc;
+ } else if (strcmp(argv[argc-1], "-lang") == 0) {
+ // PG_LogMSG("%s:%s:%i\n", __FILE__, __FUNCTION__, __LINE__);
+ lang = std::string(argv[argc]);
+ --argc;
+ } else {
+ PG_LogMSG(
+ "Usage: %s [-bpp N] [-hw] [-flip] [-fast] [-fullscreen]
[numsprites]",
+ argv[0]);
+ exit(1);
+ }
+ }
+ if (gldriver != NULL) {
+ if (gldriver->valid()) {
+ PG_LogMSG("Initializing provided graphics driver\n");
+ gldriver->attach();
+ } else {
+ PG_LogERR("graphics driver failed to initialize! - Quitting...");
+ return -1;
+ };
+ };
+
+ /* libgdk init */
+ g_type_init();
+
+ /* init_dir = PANGO_DIRECTION_RTL; */
+ context = pango_ft2_get_context(dpi_x, dpi_y);
+ paragraphs = split_paragraphs(text.c_str());
+
+ pango_context_set_language(context,
pango_language_from_string(lang.c_str()));
+ pango_context_set_base_dir(context, init_dir);
+
+ font_description = pango_font_description_new ();
+ {
+ pango_font_description_set_family (font_description, g_strdup
(init_family.c_str()));
+ pango_font_description_set_style (font_description, PANGO_STYLE_NORMAL);
+ pango_font_description_set_variant (font_description,
PANGO_VARIANT_NORMAL);
+ pango_font_description_set_weight (font_description, PANGO_WEIGHT_NORMAL);
+ pango_font_description_set_stretch (font_description,
PANGO_STRETCH_NORMAL);
+ pango_font_description_set_size (font_description, init_scale *
PANGO_SCALE);
+
+ pango_context_set_font_description (context, font_description);
+ };
+
+ if(!app.InitScreen(width, height, video_bpp, videoflags)) {
+ PG_LogERR("Couldn't set %dx%d video mode: %s",
+ width, height, SDL_GetError());
+ exit(2);
+ }
+ app.LoadTheme("default");
+ //app.LoadTheme("simple");
+ PG_Rect rect(0, 0, 80, 30);
+ PG_Button quitButton(
+ NULL, // an optional parent widget for our
button - NULL for no parent
+ 1, // the widget id (used to identify
events)
+ rect, // the screen position where the button
should appear
+ "Quit" // some textlabel for the button
+ );
+ quitButton.sigButtonClick.connect(slot(exit_handler));
+ quitButton.Show();
+
+ PangoWidget pango_test(NULL,PG_Rect(0,40,500,500),text,lang);
+ pango_test.Show();
+
+ app.Run();
+ /* g_string_free(text, TRUE); */
+ /* g_string_free(lang, TRUE); */
return 0;
};
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [paragui-cvs] CVS: paragui/plugins/pango pango.cpp,1.1.2.1,1.1.2.2,
Teunis Peters <address@hidden> <=
- Prev by Date:
[paragui-cvs] CVS: paragui/src/draw draw.cpp,1.1.2.12,1.1.2.13
- Next by Date:
[paragui-cvs] CVS: paragui/src/draw/opengl pgglcore.cpp,1.1.2.4,1.1.2.5 pggloper.cpp,1.1.2.5,1.1.2.6 pgglsurf.cpp,1.1.2.7,1.1.2.8
- Previous by thread:
[paragui-cvs] CVS: paragui/src/draw draw.cpp,1.1.2.12,1.1.2.13
- Next by thread:
[paragui-cvs] CVS: paragui/src/draw/opengl pgglcore.cpp,1.1.2.4,1.1.2.5 pggloper.cpp,1.1.2.5,1.1.2.6 pgglsurf.cpp,1.1.2.7,1.1.2.8
- Index(es):