Exemplo n.º 1
0
static wchar_t* bidi_string(wchar_t *logical) {

   FriBidiCharType base = FRIBIDI_TYPE_ON;
   size_t len;

   len = wcslen(logical);

   FriBidiChar *visual;

   FriBidiStrIndex *ltov, *vtol;
   FriBidiLevel *levels;
   FriBidiStrIndex new_len;
   fribidi_boolean log2vis;

   visual = (FriBidiChar *) malloc (sizeof (FriBidiChar) * (len + 1));
   ltov = NULL;
   vtol = NULL;
   levels = NULL;

   /* Create a bidi string. */
   log2vis = fribidi_log2vis ((FriBidiChar *)logical, len, &base,
      /* output */
      visual, ltov, vtol, levels);
   visual[len] = 0;
   if (!log2vis) {
      //msSetError(MS_IDENTERR, "Failed to create bidi string.",
      //"msGetFriBidiEncodedString()");
      return NULL;
   }
   visual[len] = 0;
   new_len = len;
   visual[len] = 0;
   return (wchar_t *)visual;

}
Exemplo n.º 2
0
static Variant HHVM_FUNCTION(
    fribidi_log2vis,
    const String& logical_str,
    int64_t direction,
    int64_t charset
  ) {

  char * visual_str;
  int logical_str_len, visual_str_len, ustr_len;
  FriBidiParType base_direction;
  FriBidiLevel status;
  FriBidiChar *logical_ustr, *visual_ustr;

  logical_str_len = logical_str.length();

  if (!_direction_is_valid(direction)) {
    raise_warning("Uknown direction.");
    return false;
  }

  if (!_charset_is_valid(charset)) {
    raise_warning("Uknown charset.");
    return false;
  }

  // Convert input string to internal Unicode
  logical_ustr = (FriBidiChar*) emalloc(sizeof(FriBidiChar) * logical_str_len);
  ustr_len = fribidi_charset_to_unicode(
    (FriBidiCharSet)charset,
    logical_str.c_str(),
    logical_str_len,
    logical_ustr
  );

  // Visualize the Unicode string
  base_direction = direction;
  visual_ustr = (FriBidiChar*) emalloc(sizeof(FriBidiChar) * ustr_len);
  status = fribidi_log2vis(
    logical_ustr, ustr_len, &base_direction,
    visual_ustr, nullptr, nullptr, nullptr);
  efree(logical_ustr);

  // Return false if FriBidi failed
  if (status == 0) {
    efree(visual_ustr);
    return false;
  }

  // Convert back from internal Unicode to original character set
  visual_str_len = 4 * ustr_len;
  visual_str = (char *) emalloc(sizeof(char) * visual_str_len);
  visual_str_len = fribidi_unicode_to_charset(
    (FriBidiCharSet)charset, visual_ustr, ustr_len, visual_str);
  efree(visual_ustr);

  String result(visual_str, visual_str_len, CopyString);
  efree(visual_str);

  return result;
}
Exemplo n.º 3
0
/** Get the width of a string. */
int GetStringWidth(FontType ft, const char *str)
{
#ifdef USE_XFT
   XGlyphInfo extents;
#endif
#ifdef USE_FRIBIDI
   FriBidiChar *temp_i;
   FriBidiChar *temp_o;
   FriBidiParType type = FRIBIDI_PAR_ON;
   int unicodeLength;
#endif
   int len;
   char *output;
   int result;
   char *utf8String;

   /* Convert to UTF-8 if necessary. */
   utf8String = GetUTF8String(str);

   /* Length of the UTF-8 string. */
   len = strlen(utf8String);

   /* Apply the bidi algorithm if requested. */
#ifdef USE_FRIBIDI
   temp_i = AllocateStack((len + 1) * sizeof(FriBidiChar));
   temp_o = AllocateStack((len + 1) * sizeof(FriBidiChar));
   unicodeLength = fribidi_charset_to_unicode(FRIBIDI_CHAR_SET_UTF8,
                                              utf8String, len, temp_i);
   fribidi_log2vis(temp_i, unicodeLength, &type, temp_o, NULL, NULL, NULL);
   output = AllocateStack(4 * len + 1);
   fribidi_unicode_to_charset(FRIBIDI_CHAR_SET_UTF8, temp_o, unicodeLength,
                              (char*)output);
   len = strlen(output);
#else
   output = utf8String;
#endif

   /* Get the width of the string. */
#ifdef USE_XFT
   JXftTextExtentsUtf8(display, fonts[ft], (const unsigned char*)output,
                       len, &extents);
   result = extents.xOff;
#else
   result = XTextWidth(fonts[ft], output, len);
#endif

   /* Clean up. */
#ifdef USE_FRIBIDI
   ReleaseStack(temp_i);
   ReleaseStack(temp_o);
   ReleaseStack(output);
#endif
   ReleaseUTF8String(utf8String);

   return result;
}
Exemplo n.º 4
0
bool Language::update()
{
	canvas.clear(clan::Colorf(0.0f,0.0f,0.2f));
		
	std::string text;
		
	text = document_element.get_child_string("ENGLISH");
	font_english.draw_text(canvas, 10, 60, text);

	text = document_element.get_child_string("CHINESE");
	font_chinese.draw_text(canvas, 10, 130, text);

#ifdef ENABLE_THIS_IF_YOU_WANT_TO_USE_FRIBIDI
	text = document_element.get_child_string("ARABIC");

	/* input */
	std::wstring text_16 = clan::StringHelp::utf8_to_ucs2(text);
	FriBidiChar *fri_str = (FriBidiChar *) text_16.c_str();
	FriBidiStrIndex fri_len = text_16.length();
	FriBidiCharType fri_base_dir = FRIBIDI_TYPE_ON;
	FriBidiCharType *fri_pbase_dir = &fri_base_dir;

	/* output */
	std::vector<wchar_t> output_buffer;
	output_buffer.resize(text_16.length() + 1);
	FriBidiChar *fri_visual_str = &output_buffer[0];
	FriBidiStrIndex *fri_position_L_to_V_list = NULL;
	FriBidiStrIndex *fri_position_V_to_L_list = NULL;
	FriBidiLevel    *fri_embedding_level_list = NULL;
	fribidi_boolean fri_result;
	fri_result = fribidi_log2vis(fri_str,  fri_len, fri_pbase_dir, fri_visual_str, fri_position_L_to_V_list, fri_position_V_to_L_list, fri_embedding_level_list);
	if (fri_result)
	{
		output_buffer[text_16.length()] = 0;
		std::string new_text = clan::StringHelp::ucs2_to_utf8(&output_buffer[0]);
		font_arabic.draw_text(canvas, 10, 230, new_text);
	}
#endif
	window.flip(1);

	return !quit;
}
Exemplo n.º 5
0
    std::wstring getVisualLine(const std::wstring&instring) {
      std::wstring outstring;

      const FriBidiCharSet enc= FRIBIDI_CHAR_SET_UTF8;
      FriBidiParType direction=FRIBIDI_PAR_ON;
      size_t len2=instring.size()*2;

      const FriBidiChar*str_in  = (const FriBidiChar*)instring.c_str();
      FriBidiChar*str_out = new FriBidiChar[len2];

      /* reshape the UTF32 string */
      FriBidiLevel lvl = fribidi_log2vis(str_in, instring.size(), &direction, str_out, 0, 0, 0);
      if(lvl) {
        wchar_t*output=(wchar_t*)str_out;
        outstring=std::wstring(output, instring.size());
      } else {
        outstring=instring;
      }
      delete[]str_out;

      return outstring;
    }
Exemplo n.º 6
0
    std::wstring getVisualLine(const std::string&instring) {
      std::wstring outstring;
      const FriBidiCharSet enc= FRIBIDI_CHAR_SET_UTF8;
      FriBidiParType direction=FRIBIDI_PAR_ON;
      size_t len2=instring.size()*2;

      FriBidiChar*str_in  = new FriBidiChar[len2];
      FriBidiChar*str_out = new FriBidiChar[len2];

      /* convert UTF8 to UTF32 */
      FriBidiStrIndex ulen = fribidi_charset_to_unicode(enc, instring.c_str(), instring.size(), str_in);
      /* reshape the UTF32 string */
      FriBidiLevel lvl = fribidi_log2vis(str_in, ulen, &direction, str_out, 0, 0, 0);
      if(lvl) {
        outstring=std::wstring((wchar_t*)str_out);
      } else {
        //outstring=instring;
      }
      delete[]str_in;
      delete[]str_out;
      return outstring;
    }
Exemplo n.º 7
0
int
bjoining_log2cuni (
  unichar *str,
  int ulen,
  unichar *cstr,
  int *clen,
  int options)
{
  int f = 1;
  int len = ulen;
  FriBidiCharType ptype = FRIBIDI_TYPE_ON;

  unichar *vis = malloc ((len + 1) * sizeof (unichar));

  f = f && bjoining_compose (str, &len);
  if (0 == (options & (B_LOGICAL_OUTPUT | B_LOGICAL_OUTPUT_LOG2CUNI)))
    {
      f = f
	&& fribidi_log2vis ((FriBidiChar *) str, len, &ptype,
			    (FriBidiChar *) vis, NULL, NULL, NULL);
    }
  else
    {
      memmove (vis, str, len * sizeof str[0]);
    }
  if (0 == (options & B_KEEP_BIDI_MARKS))
    len = fribidi_remove_bidi_marks (vis, len, NULL, NULL, NULL);
  f = f && bjoining_vis2cuni (vis, len, cstr, clen, options);
  if (f)
    cstr[*clen] = '\0';
  else
    clen = 0;
  free (vis);

  return f;
}
Exemplo n.º 8
0
static void
benchmark (
  const char *S_,
  int niter
)
{
  int len, i;
  FriBidiChar us[MAX_STR_LEN], out_us[MAX_STR_LEN];
  FriBidiStrIndex positionLtoV[MAX_STR_LEN], positionVtoL[MAX_STR_LEN];
  FriBidiLevel embedding_list[MAX_STR_LEN];
  FriBidiParType base;
  double time0, time1;

  {
    int j;
    len = strlen (S_);
    for (i = 0, j = 0; i < len; i++)
      {
	if (S_[i] == '_')
	  switch (S_[++i])
	    {
	    case '>':
	      us[j++] = FRIBIDI_CHAR_LRM;
	      break;
	    case '<':
	      us[j++] = FRIBIDI_CHAR_RLM;
	      break;
	    case 'l':
	      us[j++] = FRIBIDI_CHAR_LRE;
	      break;
	    case 'r':
	      us[j++] = FRIBIDI_CHAR_RLE;
	      break;
	    case 'L':
	      us[j++] = FRIBIDI_CHAR_LRO;
	      break;
	    case 'R':
	      us[j++] = FRIBIDI_CHAR_RLO;
	      break;
	    case 'o':
	      us[j++] = FRIBIDI_CHAR_PDF;
	      break;
	    case '_':
	      us[j++] = '_';
	      break;
	    default:
	      us[j++] = '_';
	      i--;
	      break;
	    }
	else
	  us[j++] = S_[i];
	if (us[j] >= 'A' && us[j] <= 'F')
	  us[j] += FRIBIDI_CHAR_ARABIC_ALEF - 'A';
	else if (us[j] >= 'G' && us[j] <= 'Z')
	  us[j] += FRIBIDI_CHAR_HEBREW_ALEF - 'G';
	else if (us[j] >= '6' && us[j] <= '9')
	  us[j] += FRIBIDI_CHAR_ARABIC_ZERO - '0';
      }
    len = j;
  }

  /* Start timer */
  time0 = utime ();

  for (i = 0; i < niter; i++)
    {
      /* Create a bidi string */
      base = FRIBIDI_PAR_ON;
      if (!fribidi_log2vis (us, len, &base,
			    /* output */
			    out_us, positionVtoL, positionLtoV,
			    embedding_list))
	die2
	  ("something failed in fribidi_log2vis.\n"
	   "perhaps memory allocation failure.", NULL);
    }

  /* stop timer */
  time1 = utime ();

  /* output result */
  printf ("Length = %d\n", len);
  printf ("Iterations = %d\n", niter);
  printf ("%d len*iterations in %f seconds\n", len * niter, time1 - time0);
  printf ("= %.0f kilo.length.iterations/second\n",
	  1.0 * len * niter / 1000 / (time1 - time0));

  return;
}
Exemplo n.º 9
0
GenericBitmap *FT2Font::drawString( const UString &rString, uint32_t color,
                                    int maxWidth ) const
{
    uint32_t code;
    int n;
    int penX = 0;
    int width1 = 0, width2 = 0;
    int yMin = 0, yMax = 0;
    uint32_t *pString = (uint32_t*)rString.u_str();

    // Check if freetype has been initialized
    if( !m_face )
    {
        return NULL;
    }

    // Get the length of the string
    int len = rString.length();

    // Use fribidi if available
#ifdef HAVE_FRIBIDI
    uint32_t *pFribidiString = NULL;
    if( len > 0 )
    {
        pFribidiString = new uint32_t[len+1];
        FriBidiCharType baseDir = FRIBIDI_TYPE_ON;
        fribidi_log2vis( (FriBidiChar*)pString, len, &baseDir,
                         (FriBidiChar*)pFribidiString, 0, 0, 0 );
        pString = pFribidiString;
    }
#endif

    // Array of glyph bitmaps and position
    FT_BitmapGlyphRec **glyphs = new FT_BitmapGlyphRec*[len];
    int *pos = new int[len];

    // Does the font support kerning ?
    FT_Bool useKerning = FT_HAS_KERNING( m_face );
    int previous = 0;

    // Index of the last glyph when the text is truncated with trailing ...
    int maxIndex = 0;
    // Position of the first trailing dot
    int firstDotX = 0;
    /// Get the dot glyph
    Glyph_t &dotGlyph = getGlyph( '.' );

    // First, render all the glyphs
    for( n = 0; n < len; n++ )
    {
        code = *(pString++);
        // Get the glyph for this character
        Glyph_t &glyph = getGlyph( code );
        glyphs[n] = (FT_BitmapGlyphRec*)(glyph.m_glyph);

        // Retrieve kerning distance and move pen position
        if( useKerning && previous && glyph.m_index )
        {
            FT_Vector delta;
            FT_Get_Kerning( m_face, previous, glyph.m_index,
                            ft_kerning_default, &delta );
            penX += delta.x >> 6;
        }

        pos[n] = penX;
        width1 = penX + glyph.m_size.xMax - glyph.m_size.xMin;
        yMin = __MIN( yMin, glyph.m_size.yMin );
        yMax = __MAX( yMax, glyph.m_size.yMax );

        // Next position
        penX += glyph.m_advance;

        // Save glyph index
        previous = glyph.m_index;

        if( maxWidth != -1 )
        {
            // Check if the truncated text with the '...' fit in the maxWidth
            int curX = penX;
            if( useKerning )
            {
                FT_Vector delta;
                FT_Get_Kerning( m_face, glyph.m_index, dotGlyph.m_index,
                                ft_kerning_default, &delta );
                curX += delta.x >> 6;
            }
            int dotWidth = 2 * dotGlyph.m_advance +
                dotGlyph.m_size.xMax - dotGlyph.m_size.xMin;
            if( curX + dotWidth < maxWidth )
            {
                width2 = curX + dotWidth;
                maxIndex++;
                firstDotX = curX;
            }
        }
Exemplo n.º 10
0
/**
 * This function receives a string and creates a subpicture for it. It
 * also calculates the size needed for this string, and renders the
 * needed glyphs into memory. It is used as pf_add_string callback in
 * the vout method by this module
 */
static subpicture_t *RenderText( filter_t *p_filter, block_t *p_block )
{
    filter_sys_t *p_sys = p_filter->p_sys;
    subpicture_t *p_subpic = 0;
    subpicture_data_t *p_string = 0;
    line_desc_t  *p_line = 0, *p_next = 0, *p_prev = 0;
    int i, i_pen_y, i_pen_x, i_error, i_glyph_index, i_previous;
    uint32_t *psz_unicode, *psz_unicode_orig = 0, i_char, *psz_line_start;
    int i_string_length;
    char *psz_string;
    vlc_iconv_t iconv_handle = (vlc_iconv_t)(-1);

    FT_BBox line;
    FT_BBox glyph_size;
    FT_Vector result;
    FT_Glyph tmp_glyph;

    /* Sanity check */
    if( !p_block ) return NULL;
    psz_string = p_block->p_buffer;
    if( !psz_string || !*psz_string ) goto error;

    result.x = 0;
    result.y = 0;
    line.xMin = 0;
    line.xMax = 0;
    line.yMin = 0;
    line.yMax = 0;

    /* Create and initialize a subpicture */
    p_subpic = p_filter->pf_sub_buffer_new( p_filter );
    if( !p_subpic ) goto error;

    p_subpic->i_start = p_block->i_pts;
    p_subpic->i_stop = p_block->i_pts + p_block->i_length;
    p_subpic->b_ephemer = (p_block->i_length == 0);
    p_subpic->b_absolute = VLC_FALSE;

    /* Create and initialize private data for the subpicture */
    p_string = malloc( sizeof(subpicture_data_t) );
    if( !p_string )
    {
        msg_Err( p_filter, "out of memory" );
        goto error;
    }
    p_string->p_lines = 0;
    p_string->psz_text = strdup( psz_string );

    psz_unicode = psz_unicode_orig =
        malloc( ( strlen(psz_string) + 1 ) * sizeof(uint32_t) );
    if( psz_unicode == NULL )
    {
        msg_Err( p_filter, "out of memory" );
        goto error;
    }
#if defined(WORDS_BIGENDIAN)
    iconv_handle = vlc_iconv_open( "UCS-4BE", "UTF-8" );
#else
    iconv_handle = vlc_iconv_open( "UCS-4LE", "UTF-8" );
#endif
    if( iconv_handle == (vlc_iconv_t)-1 )
    {
        msg_Warn( p_filter, "unable to do convertion" );
        goto error;
    }

    {
        char *p_in_buffer, *p_out_buffer;
        size_t i_in_bytes, i_out_bytes, i_out_bytes_left, i_ret;
        i_in_bytes = strlen( psz_string );
        i_out_bytes = i_in_bytes * sizeof( uint32_t );
        i_out_bytes_left = i_out_bytes;
        p_in_buffer = psz_string;
        p_out_buffer = (char *)psz_unicode;
        i_ret = vlc_iconv( iconv_handle, &p_in_buffer, &i_in_bytes,
                           &p_out_buffer, &i_out_bytes_left );

        vlc_iconv_close( iconv_handle );

        if( i_in_bytes )
        {
            msg_Warn( p_filter, "failed to convert string to unicode (%s), "
                      "bytes left %d", strerror(errno), i_in_bytes );
            goto error;
        }
        *(uint32_t*)p_out_buffer = 0;
        i_string_length = (i_out_bytes - i_out_bytes_left) / sizeof(uint32_t);
    }

#if defined(HAVE_FRIBIDI)
    {
        uint32_t *p_fribidi_string;
        FriBidiCharType base_dir = FRIBIDI_TYPE_ON;
        p_fribidi_string = malloc( (i_string_length + 1) * sizeof(uint32_t) );
        fribidi_log2vis( (FriBidiChar*)psz_unicode, i_string_length,
                         &base_dir, (FriBidiChar*)p_fribidi_string, 0, 0, 0 );
        free( psz_unicode_orig );
        psz_unicode = psz_unicode_orig = p_fribidi_string;
        p_fribidi_string[ i_string_length ] = 0;
    }
#endif

    /* Calculate relative glyph positions and a bounding box for the
     * entire string */
    p_line = NewLine( psz_string );
    if( p_line == NULL )
    {
        msg_Err( p_filter, "out of memory" );
        goto error;
    }
    p_string->p_lines = p_line;
    i_pen_x = 0;
    i_pen_y = 0;
    i_previous = 0;
    i = 0;
    psz_line_start = psz_unicode;

#define face p_sys->p_face
#define glyph face->glyph

    while( *psz_unicode )
    {
        i_char = *psz_unicode++;
        if( i_char == '\r' ) /* ignore CR chars wherever they may be */
        {
            continue;
        }

        if( i_char == '\n' )
        {
            psz_line_start = psz_unicode;
            p_next = NewLine( psz_string );
            if( p_next == NULL )
            {
                msg_Err( p_filter, "out of memory" );
                goto error;
            }
            p_line->p_next = p_next;
            p_line->i_width = line.xMax;
            p_line->i_height = face->size->metrics.height >> 6;
            p_line->pp_glyphs[ i ] = NULL;
            p_prev = p_line;
            p_line = p_next;
            result.x = __MAX( result.x, line.xMax );
            result.y += face->size->metrics.height >> 6;
            i_pen_x = 0;
            i_previous = 0;
            line.xMin = 0;
            line.xMax = 0;
            line.yMin = 0;
            line.yMax = 0;
            i_pen_y += face->size->metrics.height >> 6;
#if 0
            msg_Dbg( p_filter, "Creating new line, i is %d", i );
#endif
            i = 0;
            continue;
        }

        i_glyph_index = FT_Get_Char_Index( face, i_char );
        if( p_sys->i_use_kerning && i_glyph_index
            && i_previous )
        {
            FT_Vector delta;
            FT_Get_Kerning( face, i_previous, i_glyph_index,
                            ft_kerning_default, &delta );
            i_pen_x += delta.x >> 6;

        }
Exemplo n.º 11
0
// The start of the Application
int Language::start(const std::vector<std::string> &args)
{
	quit = false;

	// Set the window
	clan::DisplayWindowDescription desc;
	desc.set_title("ClanLib Language Example");
	desc.set_size(clan::Size(640, 480), true);
	desc.set_allow_resize(true);

	clan::DisplayWindow window(desc);

	// Connect the Window close event
	clan::Slot slot_quit = window.sig_window_close().connect(this, &Language::on_window_close);

	// Connect a keyboard handler to on_key_up()
	clan::Slot slot_input_up = (window.get_ic().get_keyboard()).sig_key_up().connect(this, &Language::on_input_up);

	// Get the graphic context
	clan::Canvas canvas(window);

	clan::File file("Resources/test.xml");
	clan::DomDocument document(file);
	clan::DomElement document_element = document.get_document_element();
	if (document_element.is_null())
		throw clan::Exception("Cannot obtain the document element");

	clan::Font font_english(canvas, "arial", 32);

	clan::FontDescription desc_chinese;
	desc_chinese.set_typeface_name("simsun");
	desc_chinese.set_height(48);
	desc_chinese.set_charset(clan::FontDescription::charset_chinesebig5);
	clan::Font font_chinese(canvas, desc_chinese);

	clan::FontDescription desc_arabic;
	desc_arabic.set_typeface_name("arial");
	desc_arabic.set_height(48);
	desc_arabic.set_charset(clan::FontDescription::charset_arabic);
	clan::Font font_arabic(canvas, desc_arabic);

	// Run until someone presses escape
	while (!quit)
	{

		canvas.clear(clan::Colorf(0.0f,0.0f,0.2f));
		
		std::string text;
		
		text = document_element.get_child_string("ENGLISH");
		font_english.draw_text(canvas, 10, 30, text);

		text = document_element.get_child_string("CHINESE");
		font_chinese.draw_text(canvas, 10, 130, text);

#ifdef ENABLE_THIS_IF_YOU_WANT_TO_USE_FRIBIDI
		text = document_element.get_child_string("ARABIC");

		/* input */
		std::wstring text_16 = StringHelp::utf8_to_ucs2(text);
		FriBidiChar *fri_str = (FriBidiChar *) text_16.c_str();
		FriBidiStrIndex fri_len = text_16.length();
		FriBidiCharType fri_base_dir = FRIBIDI_TYPE_ON;
		FriBidiCharType *fri_pbase_dir = &fri_base_dir;

		/* output */
		std::vector<wchar_t> output_buffer;
		output_buffer.resize(text_16.length() + 1);
		FriBidiChar *fri_visual_str = &output_buffer[0];
		FriBidiStrIndex *fri_position_L_to_V_list = NULL;
		FriBidiStrIndex *fri_position_V_to_L_list = NULL;
		FriBidiLevel    *fri_embedding_level_list = NULL;
		fribidi_boolean fri_result;
		fri_result = fribidi_log2vis(fri_str,  fri_len, fri_pbase_dir, fri_visual_str, fri_position_L_to_V_list, fri_position_V_to_L_list, fri_embedding_level_list);
		if (fri_result)
		{
			output_buffer[text_16.length()] = 0;
			std::string new_text = clan::StringHelp::ucs2_to_utf8(&output_buffer[0]);
			font_arabic.draw_text(gc, 10, 230, new_text);
		}
#endif
		window.flip(1);

		clan::KeepAlive::process(0);
	}

	return 0;
}
Exemplo n.º 12
0
/** Display a string. */
void RenderString(Drawable d, FontType font, ColorType color,
                  int x, int y, int width, const char *str)
{

#ifdef USE_ICONV
   static char isUTF8 = -1;
#endif
   XRectangle rect;
   Region renderRegion;
   int len;
   char *output;
#ifdef USE_FRIBIDI
   FriBidiChar *temp_i;
   FriBidiChar *temp_o;
   FriBidiParType type = FRIBIDI_PAR_ON;
   int unicodeLength;
#endif
#ifdef USE_XFT
   XGlyphInfo extents;
#endif
   char *utf8String;

   /* Early return for empty strings. */
   if(!str || !str[0]) {
      return;
   }

   /* Convert to UTF-8 if necessary. */
   utf8String = GetUTF8String(str);

   /* Get the length of the UTF-8 string. */
   len = strlen(utf8String);

   /* Apply the bidi algorithm if requested. */
#ifdef USE_FRIBIDI
   temp_i = AllocateStack((len + 1) * sizeof(FriBidiChar));
   temp_o = AllocateStack((len + 1) * sizeof(FriBidiChar));
   unicodeLength = fribidi_charset_to_unicode(FRIBIDI_CHAR_SET_UTF8,
                                              utf8String, len, temp_i);
   fribidi_log2vis(temp_i, unicodeLength, &type, temp_o, NULL, NULL, NULL);
   output = AllocateStack(4 * len + 1);
   fribidi_unicode_to_charset(FRIBIDI_CHAR_SET_UTF8, temp_o, unicodeLength,
                              (char*)output);
   len = strlen(output);
#else
   output = utf8String;
#endif

   /* Get the bounds for the string based on the specified width. */
   rect.x = x;
   rect.y = y;
   rect.height = GetStringHeight(font);
#ifdef USE_XFT
   JXftTextExtentsUtf8(display, fonts[font], (const unsigned char*)output,
                       len, &extents);
   rect.width = extents.xOff;
#else
   rect.width = XTextWidth(fonts[font], output, len);
#endif
   rect.width = Min(rect.width, width) + 2;

   /* Combine the width bounds with the region to use. */
   renderRegion = XCreateRegion();
   XUnionRectWithRegion(&rect, renderRegion, renderRegion);

   /* Display the string. */
#ifdef USE_XFT
   JXftDrawChange(xd, d);
   JXftDrawSetClip(xd, renderRegion);
   JXftDrawStringUtf8(xd, GetXftColor(color), fonts[font],
                      x, y + fonts[font]->ascent,
                      (const unsigned char*)output, len);
   JXftDrawChange(xd, rootWindow);
#else
   JXSetForeground(display, fontGC, colors[color]);
   JXSetRegion(display, fontGC, renderRegion);
   JXSetFont(display, fontGC, fonts[font]->fid);
   JXDrawString(display, d, fontGC, x, y + fonts[font]->ascent, output, len);
#endif

   /* Free any memory used for UTF conversion. */
#ifdef USE_FRIBIDI
   ReleaseStack(temp_i);
   ReleaseStack(temp_o);
   ReleaseStack(output);
#endif
   ReleaseUTF8String(utf8String);

   XDestroyRegion(renderRegion);

}
Exemplo n.º 13
0
void ZLTextParagraphCursor::Builder::processTextEntry(const ZLTextEntry &textEntry) {
	const std::size_t dataLength = textEntry.dataLength();
	if (dataLength == 0) {
		return;
	}

	myUcs4String.clear();
	ZLUnicodeUtil::utf8ToUcs4(myUcs4String, textEntry.data(), dataLength);
	int len = myUcs4String.size();
	myUcs4String.push_back(0);
	myBidiLevels.clear();
	myBidiLevels.assign(len + 1, 0);
	int firstNonSpace = 0;
	while ((firstNonSpace < len) &&
				 ZLUnicodeUtil::isSpace(myUcs4String[firstNonSpace])) {
		myBidiLevels[firstNonSpace++] = myLatestBidiLevel;
	}
	int lastNonSpace = len - 1;
	if (lastNonSpace > firstNonSpace - 1) {
		while (ZLUnicodeUtil::isSpace(myUcs4String[lastNonSpace])) {
			--lastNonSpace;
		}
		fribidi_log2vis((FriBidiChar*)&myUcs4String[firstNonSpace], lastNonSpace - firstNonSpace + 1, &myBidiCharType, 0, 0, 0, &myBidiLevels[firstNonSpace]);
	}
	myLatestBidiLevel = myBidiLevels[lastNonSpace];
	for (int i = lastNonSpace; i < len; ++i) {
		myBidiLevels[i] = myLatestBidiLevel;
	}

	myBreaksTable.clear();
	myBreaksTable.assign(dataLength, 0);
	const char *start = textEntry.data();
	const char *end = start + dataLength;
	set_linebreaks_utf8((const utf8_t*)start, dataLength, myLanguage.c_str(), &myBreaksTable[0]);

	ZLUnicodeUtil::Ucs4Char ch = 0, previousCh;
	enum { NO_SPACE, SPACE, NON_BREAKABLE_SPACE } spaceState = NO_SPACE;
	int charLength = 0;
	int index = 0;
	const char *wordStart = start;
	updateBidiLevel(myBidiLevels[0]);
	for (const char *ptr = start; ptr < end; ptr += charLength, ++index) {
		previousCh = ch;
		charLength = ZLUnicodeUtil::firstChar(ch, ptr);
		if (ZLUnicodeUtil::isSpace(ch)) {
			if ((spaceState == NO_SPACE) && (ptr != wordStart)) {
				addWord(wordStart, myOffset + (wordStart - start), ptr - wordStart);
			}
			spaceState = SPACE;
		} else if (ZLUnicodeUtil::isNBSpace(ch)) {
			if (spaceState == NO_SPACE) {
				if (ptr != wordStart) {
					addWord(wordStart, myOffset + (wordStart - start), ptr - wordStart);
				}
				spaceState = NON_BREAKABLE_SPACE;
			}
		} else {
			switch (spaceState) {
				case SPACE:
					if ((myBreaksTable[ptr - start - 1] == LINEBREAK_NOBREAK) || (previousCh == '-')) {
						myElements.push_back(ZLTextElementPool::Pool.NBHSpaceElement);
					} else {
						myElements.push_back(ZLTextElementPool::Pool.HSpaceElement);
					}
					wordStart = ptr;
					break;
				case NON_BREAKABLE_SPACE:
					myElements.push_back(ZLTextElementPool::Pool.NBHSpaceElement);
					wordStart = ptr;
					break;
				case NO_SPACE:
					if ((ptr > start) &&
							((((myBreaksTable[ptr - start - 1] != LINEBREAK_NOBREAK) && (previousCh != '-')) && (ptr != wordStart)) ||
							 (myBidiLevels[index - 1] != myBidiLevels[index]))) {
						addWord(wordStart, myOffset + (wordStart - start), ptr - wordStart);
						wordStart = ptr;
					}
					break;
			}
			spaceState = NO_SPACE;
		}
		updateBidiLevel(myBidiLevels[index]);
	}
	switch (spaceState) {
		case SPACE:
			myElements.push_back(ZLTextElementPool::Pool.HSpaceElement);
			break;
		case NON_BREAKABLE_SPACE:
			myElements.push_back(ZLTextElementPool::Pool.NBHSpaceElement);
			break;
		case NO_SPACE:
			addWord(wordStart, myOffset + (wordStart - start), end - wordStart);
			break;
	}
	myOffset += dataLength;
}
Exemplo n.º 14
0
int
main (int argc, char *argv[])
{
  int exit_val;
  fribidi_boolean file_found;
  char *s;
  FILE *IN;

  text_width = 80;
  do_break = FRIBIDI_TRUE;
  do_pad = FRIBIDI_TRUE;
  do_mirror = FRIBIDI_TRUE;
  do_clean = FRIBIDI_FALSE;
  do_reorder_nsm = FRIBIDI_FALSE;
  show_input = FRIBIDI_FALSE;
  show_visual = FRIBIDI_TRUE;
  show_basedir = FRIBIDI_FALSE;
  show_ltov = FRIBIDI_FALSE;
  show_vtol = FRIBIDI_FALSE;
  show_levels = FRIBIDI_FALSE;
  show_changes = FRIBIDI_FALSE;
  char_set = "UTF-8";
  bol_text = NULL;
  eol_text = NULL;
  input_base_direction = FRIBIDI_TYPE_ON;

  if ((s = getenv ("COLUMNS")))
    {
      int i;

      i = atoi (s);
      if (i > 0)
	text_width = i;
    }

#define CHARSETDESC 257
#define CAPRTL 258

  /* Parse the command line with getopt library */
  /* Must set argv[0], getopt uses it to generate error messages */
  argv[0] = appname;
  while (1)
    {
      int option_index = 0, c;
      static struct option long_options[] = {
	{"help", 0, 0, 'h'},
	{"version", 0, 0, 'V'},
	{"verbose", 0, 0, 'v'},
	{"debug", 0, 0, 'd'},
	{"test", 0, 0, 't'},
	{"charset", 1, 0, 'c'},
#ifndef FRIBIDI_NO_CHARSETS
	{"charsetdesc", 1, 0, CHARSETDESC},
	{"caprtl", 0, 0, CAPRTL},
#endif
	{"showinput", 0, &show_input, FRIBIDI_TRUE},
	{"nopad", 0, &do_pad, FRIBIDI_FALSE},
	{"nobreak", 0, &do_break, FRIBIDI_FALSE},
	{"width", 1, 0, 'w'},
	{"bol", 1, 0, 'B'},
	{"eol", 1, 0, 'E'},
	{"nomirror", 0, &do_mirror, FRIBIDI_FALSE},
	{"reordernsm", 0, &do_reorder_nsm, FRIBIDI_TRUE},
	{"clean", 0, &do_clean, FRIBIDI_TRUE},
	{"ltr", 0, (int *) &input_base_direction, FRIBIDI_TYPE_L},
	{"rtl", 0, (int *) &input_base_direction, FRIBIDI_TYPE_R},
	{"wltr", 0, (int *) &input_base_direction, FRIBIDI_TYPE_WL},
	{"wrtl", 0, (int *) &input_base_direction, FRIBIDI_TYPE_WR},
	{"basedir", 0, &show_basedir, FRIBIDI_TRUE},
	{"ltov", 0, &show_ltov, FRIBIDI_TRUE},
	{"vtol", 0, &show_vtol, FRIBIDI_TRUE},
	{"levels", 0, &show_levels, FRIBIDI_TRUE},
	{"changes", 0, &show_changes, FRIBIDI_TRUE},
	{"novisual", 0, &show_visual, FRIBIDI_FALSE},
	{0, 0, 0, 0}
      };

      c =
	getopt_long (argc, argv, "hVvdtc:w:B:E:", long_options,
		     &option_index);
      if (c == -1)
	break;

      switch (c)
	{
	case 0:
	  break;
	case 'h':
	  help ();
	  break;
	case 'V':
	  version ();
	  break;
	case 'v':
	  show_basedir = FRIBIDI_TRUE;
	  show_ltov = FRIBIDI_TRUE;
	  show_vtol = FRIBIDI_TRUE;
	  show_levels = FRIBIDI_TRUE;
	  show_changes = FRIBIDI_TRUE;
	  break;
	case 'w':
	  text_width = atoi (optarg);
	  if (text_width <= 0)
	    die ("invalid screen width `%s'\n", optarg);
	  break;
	case 'B':
	  bol_text = optarg;
	  break;
	case 'E':
	  eol_text = optarg;
	  break;
	case 'd':
	  if (!fribidi_set_debug (FRIBIDI_TRUE))
	    die
	      ("%s lib must be compiled with DEBUG option to enable\nturn debug info on.\n",
	       FRIBIDI_PACKAGE);
	  break;
	case 't':
	  do_clean = FRIBIDI_TRUE;
	  show_input = FRIBIDI_TRUE;
	  do_break = FRIBIDI_FALSE;
	  do_reorder_nsm = FRIBIDI_TRUE;
	  break;
	case 'c':
	  char_set = strdup (optarg);
	  break;
#ifndef FRIBIDI_NO_CHARSETS
	case CAPRTL:
	  char_set = "CapRTL";
	  break;
	case CHARSETDESC:
	  char_set = strdup (optarg);
	  char_set_num = fribidi_parse_charset (char_set);
	  if (!char_set_num)
	    die ("unrecognized character set `%s'\n", char_set);
	  if (!fribidi_char_set_desc (char_set_num))
	    die ("no description available for character set `%s'\n",
		 fribidi_char_set_name (char_set_num));
	  else
	    printf ("Descriptions for character set %s:\n"
		    "\n" "%s", fribidi_char_set_title (char_set_num),
		    fribidi_char_set_desc (char_set_num));
	  exit (0);
	  break;
#endif
	case ':':
	case '?':
	  die (NULL);
	  break;
	default:
	  break;
	}
    }

#ifdef FRIBIDI_NO_CHARSETS
  to_ucs4 = iconv_open ("WCHAR_T", char_set);
  from_ucs4 = iconv_open (char_set, "WCHAR_T");
#else
  char_set_num = fribidi_parse_charset (char_set);
#endif

#ifdef FRIBIDI_NO_CHARSETS
  if (to_ucs4 == (iconv_t) (-1) || from_ucs4 == (iconv_t) (-1))
#else
  if (!char_set_num)
#endif
    die ("unrecognized character set `%s'\n", char_set);

  fribidi_set_mirroring (do_mirror);
  fribidi_set_reorder_nsm (do_reorder_nsm);
  exit_val = 0;
  file_found = FRIBIDI_FALSE;
  while (optind < argc || !file_found)
    {
      char *S_;

      S_ = optind < argc ? argv[optind++] : "-";
      file_found = FRIBIDI_TRUE;

      /* Open the infile for reading */
      if (S_[0] == '-' && !S_[1])
	{
	  IN = stdin;
	}
      else
	{
	  IN = fopen (S_, "r");
	  if (!IN)
	    {
	      fprintf (stderr, "%s: %s: no such file or directory\n",
		       appname, S_);
	      exit_val = 1;
	      continue;
	    }
	}

      /* Read and process input one line at a time */
      {
	char S_[MAX_STR_LEN];
	int padding_width, break_width;

	padding_width = show_input ? (text_width - 10) / 2 : text_width;
	break_width = do_break ? padding_width : 3 * MAX_STR_LEN;

	while (fgets (S_, sizeof (S_) - 1, IN))
	  {
	    char *new_line, *nl_found;
	    FriBidiChar logical[MAX_STR_LEN];
	    char outstring[MAX_STR_LEN];
	    FriBidiCharType base;
	    FriBidiStrIndex len;

	    nl_found = "";
	    S_[sizeof (S_) - 1] = 0;
	    len = strlen (S_);
	    /* chop */
	    if (S_[len - 1] == '\n')
	      {
		len--;
		S_[len] = '\0';
		new_line = "\n";
	      }
	    else
	      new_line = "";

#ifdef FRIBIDI_NO_CHARSETS
	    {
	      char *st = S_, *ust = (char *) logical;
	      int in_len = (int) len;
	      len = sizeof logical;
	      iconv (to_ucs4, &st, &in_len, &ust, (int *) &len);
	      len = (FriBidiChar *) ust - logical;
	    }
#else
	    len = fribidi_charset_to_unicode (char_set_num, S_, len, logical);
#endif

	    {
	      FriBidiChar *visual;
	      FriBidiStrIndex *ltov, *vtol;
	      FriBidiLevel *levels;
	      FriBidiStrIndex new_len;
	      fribidi_boolean log2vis;

	      visual = show_visual ? ALLOCATE (FriBidiChar, len + 1) : NULL;
	      ltov = show_ltov ? ALLOCATE (FriBidiStrIndex, len + 1) : NULL;
	      vtol = show_vtol ? ALLOCATE (FriBidiStrIndex, len + 1) : NULL;
	      levels = show_levels ? ALLOCATE (FriBidiLevel, len + 1) : NULL;

	      /* Create a bidi string. */
	      base = input_base_direction;
	      log2vis = fribidi_log2vis (logical, len, &base,
					 /* output */
					 visual, ltov, vtol, levels);
	      if (log2vis)
		{

		  if (show_input)
		    printf ("%-*s => ", padding_width, S_);

		  new_len = len;

		  /* Remove explicit marks, if asked for. */
		  if (do_clean)
		    len =
		      fribidi_remove_bidi_marks (visual, len, ltov, vtol,
						 levels);

		  if (show_visual)
		    {
		      printf (nl_found);

		      if (bol_text)
			printf ("%s", bol_text);

		      /* Convert it to input charset and print. */
		      {
			FriBidiStrIndex idx, st;
			for (idx = 0; idx < len;)
			  {
			    FriBidiStrIndex wid, inlen;

			    wid = break_width;
			    st = idx;
#ifndef FRIBIDI_NO_CHARSETS
			    if (char_set_num != FRIBIDI_CHAR_SET_CAP_RTL)
#endif
			      while (wid > 0 && idx < len)
				wid -= fribidi_wcwidth (visual[idx++]);
#ifndef FRIBIDI_NO_CHARSETS
			    else
			      while (wid > 0 && idx < len)
				{
				  wid--;
				  idx++;
				}
#endif
			    if (wid < 0 && idx > st + 1)
			      idx--;
			    inlen = idx - st;

#ifdef FRIBIDI_NO_CHARSETS
			    {
			      char *str = outstring, *ust =
				(char *) (visual + st);
			      int in_len = inlen * sizeof visual[0];
			      new_len = sizeof outstring;
			      iconv (from_ucs4, &ust, &in_len, &str,
				     (int *) &new_len);
			      *str = '\0';
			      new_len = str - outstring;
			    }
#else
			    new_len =
			      fribidi_unicode_to_charset (char_set_num,
							  visual + st, inlen,
							  outstring);
#endif
			    if (FRIBIDI_IS_RTL (base))
			      printf ("%*s",
				      (int) (do_pad ? (padding_width +
						       strlen (outstring) -
						       (break_width -
							wid)) : 0),
				      outstring);
			    else
			      printf ("%s", outstring);
			    if (idx < len)
			      printf ("\n");
			  }
		      }
		      if (eol_text)
			printf ("%s", eol_text);

		      nl_found = "\n";
		    }
		  if (show_basedir)
		    {
		      printf (nl_found);
		      printf ("Base direction: %s",
			      (FRIBIDI_DIR_TO_LEVEL (base) ? "R" : "L"));
		      nl_found = "\n";
		    }
		  if (show_ltov)
		    {
		      FriBidiStrIndex i;

		      printf (nl_found);
		      for (i = 0; i < len; i++)
			printf ("%ld ", (long) ltov[i]);
		      nl_found = "\n";
		    }
		  if (show_vtol)
		    {
		      FriBidiStrIndex i;

		      printf (nl_found);
		      for (i = 0; i < len; i++)
			printf ("%ld ", (long) vtol[i]);
		      nl_found = "\n";
		    }
		  if (show_levels)
		    {
		      FriBidiStrIndex i;

		      printf (nl_found);
		      for (i = 0; i < len; i++)
			printf ("%d ", (int) levels[i]);
		      nl_found = "\n";
		    }
		  if (show_changes)
		    {
		      FriBidiStrIndex change_start, change_len;
		      fribidi_find_string_changes (logical, len,
						   visual, new_len,
						   &change_start,
						   &change_len);
		      printf ("%sChange start[length] = %d[%d]", nl_found,
			      change_start, change_len);
		      nl_found = "\n";
		    }
		}
	      else
		{
		  exit_val = 2;
		}

	      if (show_visual)
		free (visual);
	      if (show_ltov)
		free (ltov);
	      if (show_vtol)
		free (vtol);
	      if (show_levels)
		free (levels);
	    }

	    if (*nl_found)
	      printf (new_line);
	  }
      }
    }

  return exit_val;
}
Exemplo n.º 15
0
Arquivo: FBidi.c Projeto: fvwmorg/fvwm
char *FBidiConvert(
	const char *logical_str, const char *charset, int str_len,
	Bool *is_rtl, int *out_len, superimpose_char_t *comb_chars,
	int *l_to_v)
{
	char *visual_str;
	FriBidiCharSet fribidi_charset;
	FriBidiChar *logical_unicode_str;
	FriBidiChar *visual_unicode_str;
	FriBidiParType pbase_dir = FRIBIDI_TYPE_ON;
	FriBidiStrIndex *pos_l_to_v;
	int i;

	if (logical_str == NULL || charset == NULL)
	{
		return NULL;
	}
	if (str_len < 0)
	{
		str_len = strlen(logical_str);
	}
	if (is_rtl != NULL)
	{
		*is_rtl = False;
	}

	fribidi_charset = fribidi_parse_charset((char *)charset);
	if (fribidi_charset == FRIBIDI_CHAR_SET_NOT_FOUND)
	{
		return NULL;
	}

	/* it is possible that we allocate a bit more here, if utf-8 */
	logical_unicode_str =
		(FriBidiChar *)safemalloc((str_len + 1) * sizeof(FriBidiChar));

	/* convert to unicode first */
	str_len = fribidi_charset_to_unicode(
		fribidi_charset, (char *)logical_str, str_len,
		logical_unicode_str);

	visual_unicode_str =
		(FriBidiChar *)safemalloc((str_len + 1) * sizeof(FriBidiChar));

	/* apply bidi algorithm, convert logical string to visual string */
	/* also keep track of how characters are reordered here, to reorder
	   combing characters accordingly */
	pos_l_to_v =
		(FriBidiStrIndex *)safemalloc((str_len + 1) *
			sizeof(FriBidiStrIndex));
	fribidi_log2vis(
		logical_unicode_str, str_len, &pbase_dir,
		visual_unicode_str, pos_l_to_v, NULL, NULL);

	/* remap mapping from logical to visual to "compensate" for BIDI */
	if (comb_chars != NULL)
	{
		for (i = 0;
		    comb_chars[i].c.byte1 != 0 ||
		    comb_chars[i].c.byte2 != 0;
		    i++)
		{
			/* if input string is zero characters => only
			   combining chars, set position to zero */
			comb_chars[i].position =
				str_len != 0 ?
				pos_l_to_v[comb_chars[i].position] : 0;
		}
	}

	if (l_to_v != NULL)
	{
		/* values in the previuos mapping gives the position of
		   input characters after combining step */
		/* mapping from BIDI conversion maps from the positions in
		   the output from combining */
		int orig_len;
		int *l_to_v_temp;
		for (i = 0; l_to_v[i] != -1; i++)
		{
		}
		orig_len = i;
		l_to_v_temp = (int *)safemalloc(orig_len * sizeof(int));
		for (i = 0; i < orig_len; i++)
		{
			l_to_v_temp[i] = pos_l_to_v[l_to_v[i]];
		}
		for (i = 0; i < orig_len; i++)
		{
			l_to_v[i] = l_to_v_temp[i];
		}
		free(l_to_v_temp);
	}
	free(pos_l_to_v);


	/* character shape/join - will get pulled into fribidi with time */
	str_len = shape_n_join(visual_unicode_str, str_len);

	visual_str = (char *)safemalloc((4 * str_len + 1) * sizeof(char));

	/* convert from unicode finally */
	*out_len = fribidi_unicode_to_charset(
		fribidi_charset, visual_unicode_str, str_len, visual_str);

	if (is_rtl != NULL &&
		fribidi_get_bidi_type(*visual_unicode_str) == FRIBIDI_TYPE_RTL)
	{
		*is_rtl = True;
	}

	free(logical_unicode_str);
	free(visual_unicode_str);
	return visual_str;
}