/* Example code to show how to use pangocairo to render arbitrary shapes
 * inside a text layout, positioned by Pango.  This has become possibly
 * using the following API added in Pango 1.18:
 * 
 * 	pango_cairo_context_set_shape_renderer ()
 *
 * This examples uses a small parser to convert shapes in the format of
 * SVG paths to cairo instructions.  You can typically extract these from
 * the SVG file's <path> elements directly.
 *
 * The code then searches for the Unicode bullet character in the layout
 * text and automatically adds PangoAttribtues to the layout to replace
 * each of the with a rendering of the GNOME Foot logo.
 *
 *
 * Written by Behdad Esfahbod, 2007
 *
 * Permission to use, copy, modify, distribute, and sell this example
 * for any purpose is hereby granted without fee.
 * It is provided "as is" without express or implied warranty.
 */

// #define DFB

#include <stdio.h>
#include <string.h>

#ifdef DFB
#include <directfb.h>
#include <unistd.h>
#include <cairo-directfb.h>
#endif

#include <pango/pangocairo.h>

#define BULLET "•"

int iiii=0;
char atext[100000];

char *text[] = {
"<span  face=\"Arial\"  size=\"18432\"  foreground=\"#003366\" ></span>",
"<span  face=\"Arial\"  size=\"18432\"  foreground=\"#003366\" ></span>",
"<span  face=\"Arial\"  size=\"36864\"  foreground=\"#003366\" ><b>「ホテルPC21」様ウェブサイトご提案書\n</b></span>",
"<span  face=\"Arial\"  size=\"28672\"  foreground=\"#006666\" >インターネット事業部 \
斉藤</span>",
"<span  face=\"Arial\"  size=\"26624\"  foreground=\"#ffffff\" ><b></b></span>",
"<span  face=\"Arial\"  size=\"14336\"  foreground=\"#003366\" >「ホテルPC21」様ご提案書\n</span>",
"<span  face=\"Arial\"  size=\"14336\"  foreground=\"#003366\" >3/4/2011\n</span>",
"<span  face=\"Arial\"  size=\"36864\"  foreground=\"#006666\" ><b>目次\n</b></span>",
"<span  face=\"Arial\"  size=\"28672\"  foreground=\"#003366\" ><span  face=\"Wingdings\"  size=\"21504\"  foreground=\"#003366\" > l</span> ウェブサイトの効果\n\
<span  face=\"Wingdings\"  size=\"21504\"  foreground=\"#003366\" > l</span> サービス利用の利点\n\
<span  face=\"Wingdings\"  size=\"21504\"  foreground=\"#003366\" > l</span> ユーザー数は順調に増加\n\
<span  face=\"Wingdings\"  size=\"21504\"  foreground=\"#003366\" > l</span> サービス参加企業数も増加\n\
<span  face=\"Wingdings\"  size=\"21504\"  foreground=\"#003366\" > l</span> 各宿泊施設のコンテンツ例\n</span>",
"<span  face=\"Arial\"  size=\"26624\"  foreground=\"#ffffff\" ><b></b></span>",
"<span  face=\"Arial\"  size=\"14336\"  foreground=\"#003366\" >「ホテルPC21」様ご提案書\n</span>",
"<span  face=\"Arial\"  size=\"14336\"  foreground=\"#003366\" >3/4/2011\n</span>",
"<span  face=\"Arial\"  size=\"36864\"  foreground=\"#006666\" ><b>ウェブサイトの効果\n</b></span>",
"<span  face=\"Arial\"  size=\"28672\"  foreground=\"#003366\" ><span  face=\"Wingdings\"  size=\"21504\"  foreground=\"#003366\" > l</span> 「旅行に行きたい」「ホテル、旅館に宿泊したい」というあらゆるユーザーに対してアプローチ\n\
できる\n\
<span  face=\"Wingdings\"  size=\"21504\"  foreground=\"#003366\" > l</span> リアルタイムの空室状況把握で空き部屋を\
押さえる\n\
<span  face=\"Wingdings\"  size=\"21504\"  foreground=\"#003366\" > l</span> 口コミ情報により、紹介、リピーター客の増加が見込める\n</span>",
"<span  face=\"Arial\"  size=\"26624\"  foreground=\"#ffffff\" ><b></b></span>",
"<span  face=\"Arial\"  size=\"14336\"  foreground=\"#003366\" >「ホテルPC21」様ご提案書\n</span>",
"<span  face=\"Arial\"  size=\"14336\"  foreground=\"#003366\" >3/4/2011\n</span>",
"<span  face=\"Arial\"  size=\"36864\"  foreground=\"#006666\" ><b>サービス利用の利点\n</b></span>",
"<span  face=\"Arial\"  size=\"28672\"  foreground=\"#003366\" ><span  face=\"Wingdings\"  size=\"21504\"  foreground=\"#003366\" > l</span> 客室や設備の詳細な情報を紹介\n\
    <span  face=\"Wingdings\"  size=\"21504\"  foreground=\"#003366\" > l</span> さまざまな条件から宿泊施設を検索\n\
できる\n\
<span  face=\"Wingdings\"  size=\"21504\"  foreground=\"#003366\" > l</span> リアルタイムでの空室照会、予約も可能\n</span>",
"<span  face=\"Arial\"  size=\"28672\"  foreground=\"#003366\" ><span  face=\"Wingdings\"  size=\"21504\"  foreground=\"#003366\" > l</span> 独自の口コミ情報掲示板を設置、ソフト面を評価されやすい\n\
    </span>",
"<span  face=\"Arial\"  size=\"28672\"  foreground=\"#003366\" >\
    </span>",
"<span  face=\"Arial\"  size=\"28672\"  foreground=\"#003366\" ><span  face=\"Wingdings\"  size=\"21504\"  foreground=\"#003366\" > l</span> 利用料金に応じて\n\
ポイント蓄積、リピーターにつながる\n</span>",
"<span  face=\"Arial\"  size=\"26624\"  foreground=\"#ffffff\" ><b></b></span>",
"<span  face=\"Arial\"  size=\"14336\"  foreground=\"#003366\" >「ホテルPC21」様ご提案書\n</span>",
"<span  face=\"Arial\"  size=\"14336\"  foreground=\"#003366\" >3/4/2011\n</span>",
"<span  face=\"Arial\"  size=\"36864\"  foreground=\"#006666\" ><b>ユーザー数は順調に増加\n</b></span>",
"<span  face=\"Arial\"  size=\"28672\"  foreground=\"#003366\" ><span  face=\"Wingdings\"  size=\"21504\"  foreground=\"#003366\" > l</span> 2002年には18,000人だったユーザー数が、\n2004年には50,000人を超える見込み</span>",
"<span  face=\"Arial\"  size=\"26624\"  foreground=\"#ffffff\" ><b></b></span>",
"<span  face=\"Arial\"  size=\"14336\"  foreground=\"#003366\" >「ホテルPC21」様ご提案書\n</span>",
"<span  face=\"Arial\"  size=\"14336\"  foreground=\"#003366\" >3/4/2011\n</span>",
"<span  face=\"Arial\"  size=\"36864\"  foreground=\"#006666\" ><b>サービス参加企業数も増加\n</b></span>",
"<span  face=\"Arial\"  size=\"28672\"  foreground=\"#003366\" ><span  face=\"Wingdings\"  size=\"21504\"  foreground=\"#003366\" > l</span> サービス参加企業数は、2001年は300程度\n\
    <span  face=\"Wingdings\"  size=\"21504\"  foreground=\"#003366\" > l</span> 2004年は3000を超える見込み\n</span>",
"<span  face=\"Arial\"  size=\"18432\"  foreground=\"#003366\" ></span>"
};

typedef struct {
  double width, height;
  const char *path;
} MiniSvg;

#if 0
static MiniSvg GnomeFootLogo = {
  96.2152, 118.26,
  "M 86.068,1 C 61.466,0 56.851,35.041 70.691,35.041 C 84.529,35.041 110.671,0 86.068,0 z "
  "M 45.217,30.699 C 52.586,31.149 60.671,2.577 46.821,4.374 C 32.976,6.171 37.845,30.249 45.217,30.699 z "
  "M 11.445,48.453 C 16.686,46.146 12.12,23.581 3.208,29.735 C -5.7,35.89 6.204,50.759 11.445,48.453 z "
  "M 26.212,36.642 C 32.451,35.37 32.793,9.778 21.667,14.369 C 10.539,18.961 19.978,37.916 26.212,36.642 L 26.212,36.642 z "
  "M 58.791,93.913 C 59.898,102.367 52.589,106.542 45.431,101.092 C 22.644,83.743 83.16,75.088 79.171,51.386 C 75.86,31.712 15.495,37.769 8.621,68.553 C 3.968,89.374 27.774,118.26 52.614,118.26 C 64.834,118.26 78.929,107.226 81.566,93.248 C 83.58,82.589 57.867,86.86 58.791,93.913 L 58.791,93.913 z "
  "\0"
};

static void
mini_svg_render (MiniSvg  *shape,
		 cairo_t  *cr,
		 gboolean  do_path)
{
  double x, y;
  const char *p;
  char op[2];
  int items, len;

  cairo_get_current_point (cr, &x, &y);
  cairo_translate (cr, x, y);

  for (p = shape->path; (items = sscanf (p, "%1s %n", op, &len)), p += len, *p;)
    switch (*op)
    {
      case 'M':
        {
	  sscanf (p, "%lf,%lf %n", &x, &y, &len); p += len;
	  cairo_move_to (cr, x, y);
	  break;
	}
      case 'L':
        {
	  sscanf (p, "%lf,%lf %n", &x, &y, &len); p += len;
	  cairo_line_to (cr, x, y);
	  break;
	}
      case 'C':
        {
	  double x1, y1, x2, y2, x3, y3;
	  sscanf (p, "%lf,%lf %lf,%lf %lf,%lf %n", &x1, &y1, &x2, &y2, &x3, &y3, &len); p += len;
	  cairo_curve_to (cr, x1, y1, x2, y2, x3, y3);
	  break;
	}
      case 'z':
        {
	  cairo_close_path (cr);
	  break;
	}
      default: 
        {
	  g_warning ("Invalid MiniSvg operation '%c'", *op);
	  break;
	}
    }

  if (!do_path)
    cairo_fill (cr);
}

static void
mini_svg_shape_renderer (cairo_t        *cr,
			 PangoAttrShape *attr,
			 gboolean        do_path,
			 gpointer        data G_GNUC_UNUSED)
{
  MiniSvg *shape = (MiniSvg *) attr->data;
  double scale_x, scale_y;

  scale_x = (double) attr->ink_rect.width  / (PANGO_SCALE * shape->width );
  scale_y = (double) attr->ink_rect.height / (PANGO_SCALE * shape->height);

  cairo_rel_move_to (cr,
		     (double) attr->ink_rect.x / PANGO_SCALE,
		     (double) attr->ink_rect.y / PANGO_SCALE);
  cairo_scale (cr, scale_x, scale_y);

  mini_svg_render (shape, cr, do_path);
}

#endif

static PangoLayout *
get_layout (cairo_t *cr)
{
  PangoLayout *layout;
#if 0
  PangoAttrList *attrs;
  PangoRectangle ink_rect     = {1 * PANGO_SCALE, -11 * PANGO_SCALE,  8 * PANGO_SCALE, 10 * PANGO_SCALE};
  PangoRectangle logical_rect = {0 * PANGO_SCALE, -12 * PANGO_SCALE, 10 * PANGO_SCALE, 12 * PANGO_SCALE};
  const char *p;
  static int a = 0;
#endif
  int i;	

  /* Create a PangoLayout, set the font and text */
  layout = pango_cairo_create_layout (cr);

#if 0
  pango_cairo_context_set_shape_renderer (pango_layout_get_context (layout),
					  mini_svg_shape_renderer, NULL, NULL);
  pango_layout_set_text (layout, text, -1);

  attrs = pango_attr_list_new ();

  /* Set gnome shape attributes for all bullets */
  for (p = text; (p = strstr (p, BULLET)); p += strlen (BULLET))
    {
      PangoAttribute *attr;
      
      attr = pango_attr_shape_new_with_data (&ink_rect,
					     &logical_rect,
					     &GnomeFootLogo,
					     NULL, NULL);

      attr->start_index = p - text;
      attr->end_index = attr->start_index + strlen (BULLET);
      
      pango_attr_list_insert (attrs, attr);

      attr = pango_attr_size_new (42*1024);	
      pango_attr_list_insert (attrs, attr);	
    }

  pango_layout_set_attributes (layout, attrs);
  pango_attr_list_unref (attrs);
#else
	atext[0] = '\0';

	for ( i =0; i < 5; i++ )
	{	
		strcat( atext, text[(iiii++)%30]);		
	}

	pango_layout_set_markup(layout, atext, -1);
#if 0
	if ( a < 2 )
	{
		pango_layout_set_markup(layout, text0, -1);
	}
	else if ( a > 1 && a <= 3)
	{
		
		 pango_layout_set_markup(layout, text1, -1);
	}
	else if ( a > 3 && a <= 5 )
	{
		pango_layout_set_markup(layout, text2, -1);
	}
	else if ( a > 5 && a <= 7 )
        {
                pango_layout_set_markup(layout, text3, -1);
        }
	else if ( a > 7 && a <= 9 )
        {
                pango_layout_set_markup(layout, text4, -1);
        }
	if ( a == 9 )
	{
		a = 0;
	}
	else
	{
        	a++;
	}
#endif
#endif

  return layout;
}

static void
draw_text (cairo_t *cr, int *width, int *height)
{

  PangoLayout *layout = get_layout (cr);

  /* Adds a fixed 10-pixel margin on the sides. */

  if (width || height)
    {
      pango_layout_get_pixel_size (layout, width, height);
      if (width)
        *width += 20;
      if (height)
        *height += 20;
    }

  cairo_move_to (cr, 10, 10);
  if ( width == NULL )
  {
	cairo_set_source_rgb(cr, 0,0,1);
  	pango_cairo_show_layout (cr, layout);
  	pango_cairo_layout_path (cr, layout);
	cairo_set_source_rgb(cr, 1,1,0);
  	cairo_fill(cr);
  }

  g_object_unref (layout);
}

int main (int argc, char **argv)
{
  cairo_t *cr;
  char filename[30];
  cairo_status_t status;
  cairo_surface_t *surface;
  int width, height;
  int i;
#ifdef DFB
  IDirectFB *pDfb = NULL;
  IDirectFBDisplayLayer   *pDfbDispLayer = NULL;
  IDirectFBWindow    *pWindow = NULL;
  DFBWindowDescription   wdsc;
  DFBDisplayLayerConfig  stDispLayerConf;
  IDirectFBSurface        *pDfbSurface;
#endif

  if (argc != 2)
    {
      g_printerr ("Usage: cairoshape OUTPUT_FILENAME\n");
      return 1;
    }

#ifdef DFB
  if ( DFB_OK != DirectFBInit(NULL, NULL) )
  {
      printf("\n Direct FB Initialization Error");
      return 0;
  } 

   if ( DFB_OK != DirectFBCreate(&pDfb) )
   {
            printf("Direct FB Error\n");
            return 0;
   } /* End if (DFB_OK != iRetStatus)*/

   pDfb->GetDisplayLayer(pDfb, DLID_PRIMARY, &pDfbDispLayer);
   pDfbDispLayer->SetCooperativeLevel(pDfbDispLayer, DLSCL_ADMINISTRATIVE);
   pDfbDispLayer->EnableCursor(pDfbDispLayer, 0);
        /* Get the Display Layer Configuration */
   pDfbDispLayer->GetConfiguration(pDfbDispLayer, &stDispLayerConf);

    wdsc.flags  = DWDESC_WIDTH | DWDESC_HEIGHT | DWDESC_POSX | DWDESC_POSY;
    wdsc.posx   = 0;
    wdsc.posy   = 0;
    wdsc.width  = stDispLayerConf.width;
    wdsc.height = stDispLayerConf.height;
    pDfbDispLayer->CreateWindow(pDfbDispLayer, &wdsc, &pWindow);

    pWindow ->GetSurface(pWindow, &pDfbSurface);
    surface = cairo_directfb_surface_create(pDfb, pDfbSurface);
#endif

  for ( i =0; i < 30; i++ )
  {
#ifndef DFB
  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
					0, 0);
#endif

    printf("\n LOOP %d\n", i);	
    sprintf(filename,"%s%d", argv[1], i );
  /* First create and use a 0x0 surface, to measure how large
   * the final surface needs to be */
  cr = cairo_create (surface);
  draw_text (cr, &width, &height);
  cairo_destroy (cr);

#ifndef DFB
  cairo_surface_destroy (surface);
  /* Now create the final surface and draw to it. */
  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
					1024, 768);
  printf("\n Width %d Height %d\n",  width, height );
#endif

  cr = cairo_create (surface);

  cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
  cairo_paint (cr);
  draw_text (cr, NULL, NULL);
  cairo_destroy (cr);



  /* Write out the surface as PNG */
  status = cairo_surface_write_to_png (surface, filename);
#ifndef DFB
  cairo_surface_destroy (surface);
#endif

  if (status != CAIRO_STATUS_SUCCESS)
    {
      g_printerr ("Could not save png to '%s'\n", filename);
      return 1;
    }

#ifdef DFB
    pWindow->SetOpacity(pWindow, 0xFF);	
    sleep(5);
    pWindow->SetOpacity(pWindow, 0);	
#endif
   }

#ifdef DFB
  cairo_surface_destroy (surface);
#endif

#ifdef DFB
   pDfbSurface ->Release(pDfbSurface);	
   pWindow ->Destroy(pWindow);
   pDfb ->Release(pDfb);
#endif

  return 0;
}
