Ejemplo n.º 1
0
	//-----------------------------------------------------------------//
	inline float compare(const std::string& srca, const std::string& srcb) {
		lstring a;
		utf8_to_utf32(srca, a);
		lstring b;
		utf8_to_utf32(srcb, b);
		return compare(a, b);
	}
Ejemplo n.º 2
0
float glf_get_string_len(gl_tex_font_p glf, const char *text, int n)
{
    float x = 0.0;

    if((glf != nullptr) && (glf->ft_face != nullptr))
    {
        uint8_t *nch;
        uint8_t *nch2;
        uint8_t *ch = (uint8_t*)text;
        uint32_t curr_utf32, next_utf32;
        int i;

        nch = utf8_to_utf32(ch, &curr_utf32);
        curr_utf32 = FT_Get_Char_Index(glf->ft_face, curr_utf32);

        for(i = 0; (*ch != 0) && !((n >= 0) && (i >= n)); i++)
        {
            FT_Vector kern;

            nch2 = utf8_to_utf32(nch, &next_utf32);
            next_utf32 = FT_Get_Char_Index(glf->ft_face, next_utf32);
            ch = nch;
            nch = nch2;

            FT_Get_Kerning(glf->ft_face, curr_utf32, next_utf32, FT_KERNING_UNSCALED, &kern);   // kern in 1/64 pixel
            curr_utf32 = next_utf32;
            x += static_cast<GLfloat>(kern.x + glf->glyphs[curr_utf32].advance_x) / 64.0;
        }
    }

    return x;
}
Ejemplo n.º 3
0
int32_t glf_get_string_len(gl_tex_font_p glf, const char *text, int n)
{
    int32_t x = 0;
    uint8_t *ch = (uint8_t*)text;

    if(glf && glf->ft_face && *ch)
    {
        uint32_t curr_utf32, next_utf32;
        int i = 0;
        FT_Vector kern;

        ch = utf8_to_utf32(ch, &curr_utf32);
        curr_utf32 = FT_Get_Char_Index(glf->ft_face, curr_utf32);
        for(; (n < 0) || (i < n); i++)
        {
            n = (*ch) ? (n) : (0);
            ch = utf8_to_utf32(ch, &next_utf32);
            next_utf32 = FT_Get_Char_Index(glf->ft_face, next_utf32);

            FT_Get_Kerning(glf->ft_face, curr_utf32, next_utf32, FT_KERNING_UNSCALED, &kern);   // kern in 1/64 pixel
            curr_utf32 = next_utf32;
            x += kern.x + glf->glyphs[curr_utf32].advance_x_pt;
        }
    }

    return x;
}
Ejemplo n.º 4
0
char *glf_get_string_for_width(gl_tex_font_p glf, char *text, int32_t w_pt, int *n_sym)
{
    int32_t x = 0;
    uint8_t *ch = (uint8_t*)text;
    char *ret = text;
    *n_sym = 0;

    if(glf && glf->ft_face && *ch)
    {
        uint32_t curr_utf32, next_utf32;
        FT_Vector kern;

        ch = utf8_to_utf32(ch, &curr_utf32);
        curr_utf32 = FT_Get_Char_Index(glf->ft_face, curr_utf32);
        w_pt -= glf->glyphs[curr_utf32].advance_x_pt;
        do
        {
            ret = (char*)ch;
            (*n_sym)++;
            w_pt = (*ch) ? (w_pt) : (0);
            ch = utf8_to_utf32(ch, &next_utf32);
            next_utf32 = FT_Get_Char_Index(glf->ft_face, next_utf32);

            FT_Get_Kerning(glf->ft_face, curr_utf32, next_utf32, FT_KERNING_UNSCALED, &kern);   // kern in 1/64 pixel
            curr_utf32 = next_utf32;
            x += kern.x + glf->glyphs[curr_utf32].advance_x_pt;
        }
        while(x < w_pt);
    }

    return ret;
}
Ejemplo n.º 5
0
void glf_get_string_bb(gl_tex_font_p glf, const char *text, int n, GLfloat *x0, GLfloat *y0, GLfloat *x1, GLfloat *y1)
{
    *x0 = 0.0;
    *x1 = 0.0;
    *y0 = 0.0;
    *y1 = 0.0;

    if((glf != nullptr) && (glf->ft_face != nullptr))
    {
        uint8_t *nch;
        uint8_t *nch2;
        uint8_t *ch = (uint8_t*)text;
        float x = 0.0;
        float y = 0.0;
        float xx0, xx1, yy0, yy1;
        int i;
        uint32_t curr_utf32, next_utf32;

        nch = utf8_to_utf32(ch, &curr_utf32);
        curr_utf32 = FT_Get_Char_Index(glf->ft_face, curr_utf32);

        for(i = 0; (*ch != 0) && !((n >= 0) && (i >= n)); i++)
        {
            FT_Vector kern;
            char_info_p g = glf->glyphs + curr_utf32;

            nch2 = utf8_to_utf32(nch, &next_utf32);

            next_utf32 = FT_Get_Char_Index(glf->ft_face, next_utf32);
            ch = nch;
            nch = nch2;

            FT_Get_Kerning(glf->ft_face, curr_utf32, next_utf32, FT_KERNING_UNSCALED, &kern);   // kern in 1/64 pixel
            curr_utf32 = next_utf32;

            xx0 = x + g->left;
            xx1 = xx0 + g->width;
            yy0 = y + g->top;
            yy1 = yy0 - g->height;
            bbox_add(&xx0, &xx1, &yy0, &yy1, x0, x1, y0, y1);

            x += static_cast<GLfloat>(kern.x + g->advance_x) / 64.0;
            y += static_cast<GLfloat>(kern.y + g->advance_y) / 64.0;
        }
    }
}
Ejemplo n.º 6
0
static int
befs_utf2nls(struct super_block *sb, const char *in,
	     int in_len, char **out, int *out_len)
{
	struct nls_table *nls = BEFS_SB(sb)->nls;
	int i, o;
	unicode_t uni;
	int unilen, utflen;
	char *result;
	/* The utf8->nls conversion won't make the final nls string bigger
	 * than the utf one, but if the string is pure ascii they'll have the
	 * same width and an extra char is needed to save the additional \0
	 */
	int maxlen = in_len + 1;

	befs_debug(sb, "---> utf2nls()");

	if (!nls) {
		befs_error(sb, "befs_utf2nls called with no NLS table loaded");
		return -EINVAL;
	}

	*out = result = kmalloc(maxlen, GFP_NOFS);
	if (!*out) {
		befs_error(sb, "befs_utf2nls() cannot allocate memory");
		*out_len = 0;
		return -ENOMEM;
	}

	for (i = o = 0; i < in_len; i += utflen, o += unilen) {

		/* convert from UTF-8 to Unicode */
		utflen = utf8_to_utf32(&in[i], in_len - i, &uni);
		if (utflen < 0)
			goto conv_err;

		/* convert from Unicode to nls */
		if (uni > MAX_WCHAR_T)
			goto conv_err;
		unilen = nls->uni2char(uni, &result[o], in_len - o);
		if (unilen < 0)
			goto conv_err;
	}
	result[o] = '\0';
	*out_len = o;

	befs_debug(sb, "<--- utf2nls()");

	return o;

      conv_err:
	befs_error(sb, "Name using character set %s contains a character that "
		   "cannot be converted to unicode.", nls->charset);
	befs_debug(sb, "<--- utf2nls()");
	kfree(result);
	return -EILSEQ;
}
Ejemplo n.º 7
0
ssize_t encoder_read(struct file *filp, char __user *buf, size_t count,
                   loff_t *f_pos)
{
    struct encoder_dev *dev = filp->private_data;
    int quantum = dev->quantum;
    int s_pos, q_pos;
    ssize_t retval = 0;

    if (down_interruptible(&dev->sem))
        return -ERESTARTSYS;
    if (*f_pos >= dev->size)
        goto out;
    if (*f_pos + count > dev->size)
        count = dev->size - *f_pos;

    s_pos = (long) *f_pos / quantum;
    q_pos = (long) *f_pos % quantum;

    if (dev->data == NULL || ! dev->data[s_pos])
        goto out;
	if (count > quantum - q_pos)
        count = quantum - q_pos;
	
	char* decoded_new_data;
    /* read only up to the end of this quantum */
	switch(current_output_encoding){
		case ENC_UTF8:
			/*do nothing*/
			break;
		case ENC_UTF16:
			count = utf8_to_utf16(dev->data[s_pos] + q_pos, count, decoded_new_data); 
			break;
		case ENC_UTF32:
			count = utf8_to_utf32(dev->data[s_pos] + q_pos, count, decoded_new_data);
			break;
		case ENC_88591:
			count = utf8_to_iso88591(dev->data[s_pos] + q_pos, count, decoded_new_data);
			break;	
		case ENC_88599:
			count = utf8_to_iso88599(dev->data[s_pos] + q_pos, count, decoded_new_data);
			break;
	}	
    
    if (copy_to_user(buf, decoded_new_data, count)) {
        retval = -EFAULT;
        goto out;
    }
    *f_pos += count;
    retval = count;

  out:
    up(&dev->sem);
    return retval;
}
Ejemplo n.º 8
0
void glf_get_string_bb(gl_tex_font_p glf, const char *text, int n, int32_t *x0, int32_t *y0, int32_t *x1, int32_t *y1)
{
    uint8_t *ch = (uint8_t*)text;
    *x0 = 0;
    *x1 = 0;
    *y0 = 0;
    *y1 = 0;

    if(glf && glf->ft_face && *ch)
    {
        FT_Vector kern;
        int32_t x_pt = 0;
        int32_t y_pt = 0;
        int32_t xx0, xx1, yy0, yy1;
        uint32_t curr_utf32, next_utf32;

        ch = utf8_to_utf32(ch, &curr_utf32);
        curr_utf32 = FT_Get_Char_Index(glf->ft_face, curr_utf32);
        for(int i = 0; (n < 0) || (i < n); i++)
        {
            char_info_p g = glf->glyphs + curr_utf32;
            n = (*ch) ? (n) : (0);

            ch = utf8_to_utf32(ch, &next_utf32);
            next_utf32 = FT_Get_Char_Index(glf->ft_face, next_utf32);
            FT_Get_Kerning(glf->ft_face, curr_utf32, next_utf32, FT_KERNING_UNSCALED, &kern);   // kern in 1/64 pixel
            curr_utf32 = next_utf32;

            xx0 = x_pt + g->left * 64;
            xx1 = xx0 + g->width * 64;
            yy0 = y_pt + g->top * 64;
            yy1 = yy0 - g->height * 64;
            bbox_add(&xx0, &xx1, &yy0, &yy1, x0, x1, y0, y1);

            x_pt += kern.x + g->advance_x_pt;
            y_pt += kern.y + g->advance_y_pt;
        }
    }
}
Ejemplo n.º 9
0
static int char2uni(const unsigned char *rawstring, int boundlen, wchar_t *uni)
{
	int n;
	unicode_t u;

	n = utf8_to_utf32(rawstring, boundlen, &u);
	if (n < 0 || u > MAX_WCHAR_T) {
		*uni = 0x003f;	/* ? */
		return -EINVAL;
	}
	*uni = (wchar_t) u;
	return n;
}
Ejemplo n.º 10
0
/*
 * utf-8文字列の文字数を返す
 */
int utf8_chars(const char *mbs)
{
	int count;
	int mblen;

	count = 0;
	while (*mbs != '\0') {
		mblen = utf8_to_utf32(mbs, NULL);
		if (mblen == -1)
			return -1;
		count++;
		mbs += mblen;
	}
	return count;
}
Ejemplo n.º 11
0
//------------------------------------------------------------------------------------
// получаем размер строки
//------------------------------------------------------------------------------------
int vw_FontSize(const char *Text, ...)
{
	if (Text == 0) return 0;

	// смотрим значения параметров в строке
	char	text[1024];
	va_list		ap;

	va_start(ap, Text);
	vsprintf(text, Text, ap);
	va_end(ap);
	// в text уже полная строка
	if (strlen(text) == 0) return 0;

	const char *textdraw = text;
	// сразу определяем "базовую" ширину пробела
	if (vw_FindFontCharByUTF32(0x020) == 0) vw_LoadFontChar(0x020);
	float SpaceWidth = vw_FindFontCharByUTF32(0x020)->AdvanceX;
	// чтобы было более читаемо - делаем пробел не менее 2/3 ширины
	if (SpaceWidth < (InternalFontSize * 0.65f)) SpaceWidth = InternalFontSize * 0.65f;
	float LineWidth = 0;

	while (strlen(textdraw) > 0)
	{
		unsigned UTF32;
		// преобразуем в утф32 и "сдвигаемся" на следующий символ в строке
		textdraw = utf8_to_utf32(textdraw, &UTF32);
		// находим наш текущий символ
		eFontChar* DrawChar = vw_FindFontCharByUTF32(UTF32);
		if (DrawChar == 0) DrawChar = vw_LoadFontChar(UTF32);

		// считаем кол-во пробелов
		if (UTF32 == 0x020)
			LineWidth += SpaceWidth;
		else
			LineWidth += DrawChar->AdvanceX;
	}


	return (int)LineWidth;
}
Ejemplo n.º 12
0
/*
 * utf-8文字列を描画した際の幅を取得する
 */
int get_utf8_width(const char *mbs)
{
	uint32_t c;
	int mblen, w;

	/* 1文字ずつ描画する */
	w = 0;
	c = 0; /* warning avoidance on gcc 5.3.1 */
	while (*mbs != '\0') {
		/* 文字を取得する */
		mblen = utf8_to_utf32(mbs, &c);
		if (mblen == -1)
			return -1;

		/* 幅を取得する */
		w += get_glyph_width(c);

		/* 次の文字へ移動する */
		mbs += mblen;
	}
	return w;
}
Ejemplo n.º 13
0
Tree::Expr
ConsDefWS::group(const std::list<EquationDefinition>& defs)
{
  if (defs.size() != 1)
  {
    throw "too many definitions";
  }

  auto& cons = get<Parser::ConstructorDecl>(*defs.front().parsed());

  Tree::TupleExpr::TuplePairs pairs
  {
    {Tree::DimensionExpr{DIM_TYPE}, cons.type},
    {Tree::DimensionExpr{DIM_CONS}, cons.name}
  };

  std::map<u32string, dimension_index> rewrites;
  std::vector<dimension_index> dims;

  for (size_t i = 0; i != cons.args.size(); ++i)
  {
    std::ostringstream argos;
    argos << "arg" << i;
    pairs.push_back(std::make_pair(
      Tree::DimensionExpr(utf8_to_utf32(argos.str())),
      Tree::IdentExpr(cons.args[i])
    ));

    auto dim = m_system.nextHiddenDim();

    dims.push_back(dim);

    rewrites.insert({cons.args[i], dim});
  }

  Tree::Expr guard = fixupGuardArgs(cons.guard, rewrites);

  Tree::ConditionalBestfitExpr cond;
  cond.declarations.push_back(std::make_tuple
  (
    defs.front().start(),
    guard,
    Tree::Expr(),
    Tree::TupleExpr{pairs}
  ));

  Tree::Expr abstractions = cond;

  auto dimIter = dims.rbegin();
  for (auto argsIter = cons.args.rbegin();
       argsIter != cons.args.rend();
       ++argsIter, ++dimIter)
  {
    auto base = Tree::BaseAbstractionExpr(*argsIter, abstractions);
    base.dims.push_back(*dimIter);

    abstractions = std::move(base);
  }

  return abstractions;
}
Ejemplo n.º 14
0
void String8::getUtf32(char32_t* dst) const
{
    utf8_to_utf32(mString, length(), dst);
}
Ejemplo n.º 15
0
void glf_render_str(gl_tex_font_p glf, GLfloat x, GLfloat y, const char *text)
{
    uint8_t *nch;
    uint8_t *ch = (uint8_t*)text;
    FT_Vector kern;

    if((glf == nullptr) || (glf->ft_face == nullptr) || (text == nullptr) || (text[0] == '\0'))
    {
        return;
    }

    FontBuffer_Bind();

    if(glf->gl_real_tex_indexes_count == 1)
    {
        GLfloat *p = FontBuffer_ResizeAndMap(48 * utf8_strlen(text) * sizeof(GLfloat));
        GLuint elements_count = 0;
        uint32_t curr_utf32, next_utf32;
        nch = utf8_to_utf32(ch, &curr_utf32);
        curr_utf32 = FT_Get_Char_Index(glf->ft_face, curr_utf32);

        while(*ch)
        {
            char_info_p g;
            uint8_t *nch2 = utf8_to_utf32(nch, &next_utf32);

            next_utf32 = FT_Get_Char_Index(glf->ft_face, next_utf32);
            ch = nch;
            nch = nch2;

            g = glf->glyphs + curr_utf32;
            FT_Get_Kerning(glf->ft_face, curr_utf32, next_utf32, FT_KERNING_UNSCALED, &kern);   // kern in 1/64 pixel
            curr_utf32 = next_utf32;

            if(g->tex_index != 0)
            {
                GLfloat x0 = x + g->left;
                GLfloat x1 = x0 + g->width;
                GLfloat y0 = y + g->top;
                GLfloat y1 = y0 - g->height;

                *p = x0;            p++;
                *p = y0;            p++;
                *p = g->tex_x0;     p++;
                *p = g->tex_y0;     p++;
                vec4_copy(p, glf->gl_font_color);   p += 4;

                *p = x1;            p++;
                *p = y0;            p++;
                *p = g->tex_x1;     p++;
                *p = g->tex_y0;     p++;
                vec4_copy(p, glf->gl_font_color);   p += 4;

                *p = x1;            p++;
                *p = y1;            p++;
                *p = g->tex_x1;     p++;
                *p = g->tex_y1;     p++;
                vec4_copy(p, glf->gl_font_color);   p += 4;
                elements_count++;

                *p = x0;            p++;
                *p = y0;            p++;
                *p = g->tex_x0;     p++;
                *p = g->tex_y0;     p++;
                vec4_copy(p, glf->gl_font_color);   p += 4;

                *p = x1;            p++;
                *p = y1;            p++;
                *p = g->tex_x1;     p++;
                *p = g->tex_y1;     p++;
                vec4_copy(p, glf->gl_font_color);   p += 4;

                *p = x0;            p++;
                *p = y1;            p++;
                *p = g->tex_x0;     p++;
                *p = g->tex_y1;     p++;
                vec4_copy(p, glf->gl_font_color);   p += 4;
                elements_count++;
            }
            x += static_cast<GLfloat>(kern.x + g->advance_x) / 64.0;
            y += static_cast<GLfloat>(kern.y + g->advance_y) / 64.0;
        }
        FontBuffer_Unmap();
        ///RENDER
        if(elements_count != 0)
        {
            glBindTexture(GL_TEXTURE_2D, glf->gl_tex_indexes[0]);
            glDrawArrays(GL_TRIANGLES, 0, elements_count * 3);
        }
    }
    else
    {
        GLuint active_texture = 0;
        uint32_t curr_utf32, next_utf32;
        nch = utf8_to_utf32(ch, &curr_utf32);
        curr_utf32 = FT_Get_Char_Index(glf->ft_face, curr_utf32);
        for(; *ch;)
        {
            GLfloat *p = FontBuffer_ResizeAndMap(sizeof(GLfloat[32]));
            char_info_p g;
            uint8_t *nch2 = utf8_to_utf32(nch, &next_utf32);

            next_utf32 = FT_Get_Char_Index(glf->ft_face, next_utf32);
            ch = nch;
            nch = nch2;

            g = glf->glyphs + curr_utf32;
            FT_Get_Kerning(glf->ft_face, curr_utf32, next_utf32, FT_KERNING_UNSCALED, &kern);   // kern in 1/64 pixel
            curr_utf32 = next_utf32;

            if(g->tex_index != 0)
            {
                if(active_texture != g->tex_index)
                {
                    glBindTexture(GL_TEXTURE_2D, g->tex_index);
                    active_texture = g->tex_index;
                }
                ///RENDER
                GLfloat x0 = x + g->left;
                GLfloat x1 = x0 + g->width;
                GLfloat y0 = y + g->top;
                GLfloat y1 = y0 - g->height;

                *p = x0;            p++;
                *p = y0;            p++;
                *p = g->tex_x0;     p++;
                *p = g->tex_y0;     p++;
                vec4_copy(p, glf->gl_font_color);   p += 4;

                *p = x1;            p++;
                *p = y0;            p++;
                *p = g->tex_x1;     p++;
                *p = g->tex_y0;     p++;
                vec4_copy(p, glf->gl_font_color);   p += 4;

                *p = x1;            p++;
                *p = y1;            p++;
                *p = g->tex_x1;     p++;
                *p = g->tex_y1;     p++;
                vec4_copy(p, glf->gl_font_color);   p += 4;

                *p = x0;            p++;
                *p = y1;            p++;
                *p = g->tex_x0;     p++;
                *p = g->tex_y1;     p++;
                vec4_copy(p, glf->gl_font_color);

                FontBuffer_Unmap();

                glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
            }
            x += static_cast<GLfloat>(kern.x + g->advance_x) / 64.0;
            y += static_cast<GLfloat>(kern.y + g->advance_y) / 64.0;
        }
    }
}
Ejemplo n.º 16
0
	//-----------------------------------------------------------------//
	inline lstring utf8_to_utf32(const std::string& src) noexcept {
		lstring dst;
		utf8_to_utf32(src, dst);
		return dst;
	}
Ejemplo n.º 17
0
//-----------------------------------------------------------------------------
// делаем генерацию нужных символов по списку генерируя одну текстуру
//-----------------------------------------------------------------------------
void vw_GenerateFontChars(int FontTextureWidth, int FontTextureHeight, const char * CharsList)
{

	printf("Font characters generation start.\n");

	// будем использовать последовательность как имя текстуры
	const char *TextureName = CharsList;
	// временный массив
	BYTE * DIB;
	DIB = new BYTE[FontTextureWidth*FontTextureHeight*4]; // всегда делаем rgba
	// устанавливаем 0 везде, чтобы потом не краcить rgb, а только формировать альфу
	memset(DIB, 0, FontTextureWidth*FontTextureHeight*4);

	// данные для работы с вклеиванием в текстуру
	int CurrentDIBX = 0;
	int CurrentDIBY = 0;
	int EdgingSpace = 2;
	int MaxHeightInCurrentLine = 0;


	// первый проход, формируем одну большую текстуру
	const char *CharsList2 = CharsList;
	while (strlen(CharsList) > 0)
	{
		unsigned CurrentChar;
		// преобразуем в утф32 и "сдвигаемся" на следующий символ в строке
		CharsList = utf8_to_utf32(CharsList, &CurrentChar);


		// загрузка глифа нужного нам символа
		if (FT_Load_Char( InternalFace, CurrentChar, FT_LOAD_RENDER | FT_LOAD_NO_HINTING | FT_LOAD_NO_AUTOHINT))
		{
			fprintf(stderr, "Can't load Char: %u\n", CurrentChar);
			return;
		}

		// создаем структуру FontChar
		eFontChar* NewChar;
		NewChar = new eFontChar;

		NewChar->UTF32 = CurrentChar;
		NewChar->CharTexture = 0;
		NewChar->TexturePositionLeft = 0;
		NewChar->TexturePositionRight = 0;
		NewChar->TexturePositionTop = 0;
		NewChar->TexturePositionBottom = 0;
		NewChar->Width = InternalFace->glyph->bitmap.width;
		NewChar->Height = InternalFace->glyph->bitmap.rows;
		NewChar->Left = InternalFace->glyph->bitmap_left;
		NewChar->Top = InternalFace->glyph->bitmap_top;
		NewChar->AdvanceX = InternalFace->glyph->advance.x / 64.0f;
		NewChar->Prev = 0;
		NewChar->Next = 0;

		// делаем установку параметров для вклеивания

		// если в текущую строку символов уже не можем вписывать - смещаемся на новую, ниже
		if (CurrentDIBX + NewChar->Width > FontTextureWidth)
		{
			CurrentDIBX = 0;
			CurrentDIBY += MaxHeightInCurrentLine + EdgingSpace;
			MaxHeightInCurrentLine = 0;
		}
		// если в текущую строку не влазит уже по высоте - значит это фейл... кричим чтоб дали больше текстуру
		if (CurrentDIBY + NewChar->Height > FontTextureHeight)
		{
			fprintf(stderr, "!!! Can't generate all font chars in one texture. Too many chars or too small texture size!\n");
			delete NewChar;
			break;
		}

		// "вклеиваем" новый символ в массив
		BYTE ColorRGB[3]={255,255,255};
		for (int j=0; j<NewChar->Height; j++)
		for (int i=0; i<NewChar->Width; i++)
		{
			memcpy(DIB + (FontTextureHeight-CurrentDIBY-j-1)*FontTextureWidth*4 + (CurrentDIBX+i)*4,
					ColorRGB,
					3);
			memcpy(DIB + (FontTextureHeight-CurrentDIBY-j-1)*FontTextureWidth*4 + (CurrentDIBX+i)*4 + 3,
					InternalFace->glyph->bitmap.buffer+j*NewChar->Width+i,
					1);
		}

		// устанавливаем параметры текстуры для прорисовки нашему символу
		NewChar->TexturePositionLeft = CurrentDIBX;
		NewChar->TexturePositionRight = CurrentDIBX + NewChar->Width;
		NewChar->TexturePositionTop = CurrentDIBY;
		NewChar->TexturePositionBottom = CurrentDIBY + NewChar->Height;

		// выбираем наибольшую высоту символов
		if (MaxHeightInCurrentLine < NewChar->Height) MaxHeightInCurrentLine = NewChar->Height;
		// смещаем указатель
		CurrentDIBX += NewChar->Width + EdgingSpace;

		// подключаем к менеджеру
		vw_AttachFontChar(NewChar);
	}


/////////////////////////////////
/*
		// выводим в bmp файл сгенерированный DIB, если нужно проверить

        SDL_Surface *temp;
        temp = SDL_CreateRGBSurface(SDL_SWSURFACE, FontTextureWidth, FontTextureHeight, 32,
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
        0x000000FF, 0x0000FF00, 0x00FF0000, 0
#else
        0x00FF0000, 0x0000FF00, 0x000000FF, 0
#endif
        );
		memcpy(temp->pixels, DIB, FontTextureWidth*FontTextureHeight*4);
        SDL_SaveBMP(temp, "fontgenerationtest.bmp");
        SDL_FreeSurface(temp);
*/
/////////////////////////////////


	// создаем текстуру
	vw_SetTextureProp(RI_MAGFILTER_LINEAR | RI_MINFILTER_LINEAR | RI_MIPFILTER_NONE, RI_CLAMP_TO_EDGE, true, TX_ALPHA_GREYSC, false);
	eTexture* FontTexture = vw_CreateTextureFromMemory(TextureName, DIB, FontTextureWidth, FontTextureHeight, 4, false);
	// освобождаем память
	delete [] DIB;
	if (FontTexture == 0)
	{
		fprintf(stderr, "Can't create font texture.\n");
		return;
	}


	// второй проход, всем FontChars из списка, присваиваем сгенерированную текстуру
	while (strlen(CharsList2) > 0)
	{
		unsigned CurrentChar;
		// преобразуем в утф32 и "сдвигаемся" на следующий символ в строке
		CharsList2 = utf8_to_utf32(CharsList2, &CurrentChar);
		// ставим нашу общую текстуру
		eFontChar* TMPChar = vw_FindFontCharByUTF32(CurrentChar);
		if (TMPChar != 0) TMPChar->CharTexture = FontTexture;
	}


	printf("Font characters generation end.\n\n");
}
// ------------------------------------------------------------- load_glyph ---
texture_glyph_t *
load_glyph( const char *  filename,     const char* charcode,
            const float   highres_size, const float   lowres_size,
            const float   padding )
{
    size_t i, j;
    FT_Library library;
    FT_Face face;

    FT_Init_FreeType( &library );
    FT_New_Face( library, filename, 0, &face );
    FT_Select_Charmap( face, FT_ENCODING_UNICODE );
    FT_UInt glyph_index = FT_Get_Char_Index( face, utf8_to_utf32( charcode ) );

    // Render glyph at high resolution (highres_size points)
    FT_Set_Char_Size( face, highres_size*64, 0, 72, 72 );
    FT_Load_Glyph( face, glyph_index,
                   FT_LOAD_RENDER | FT_LOAD_NO_HINTING | FT_LOAD_NO_AUTOHINT);
    FT_GlyphSlot slot = face->glyph;
    FT_Bitmap bitmap = slot->bitmap;

    // Allocate high resolution buffer
    size_t highres_width  = bitmap.width + 2*padding*highres_size;
    size_t highres_height = bitmap.rows + 2*padding*highres_size;
    double * highres_data = (double *) malloc( highres_width*highres_height*sizeof(double) );
    memset( highres_data, 0, highres_width*highres_height*sizeof(double) );

    // Copy high resolution bitmap with padding and normalize values
    for( j=0; j < bitmap.rows; ++j )
    {
        for( i=0; i < bitmap.width; ++i )
        {
            int x = i + padding;
            int y = j + padding;
            highres_data[y*highres_width+x] = bitmap.buffer[j*bitmap.width+i]/255.0;
        }
    }

    // Compute distance map
    highres_data = make_distance_mapd( highres_data, highres_width, highres_height );

    // Allocate low resolution buffer
    size_t lowres_width  = round(highres_width * lowres_size/highres_size);
    size_t lowres_height = round(highres_height * lowres_width/(float) highres_width);
    double * lowres_data = (double *) malloc( lowres_width*lowres_height*sizeof(double) );
    memset( lowres_data, 0, lowres_width*lowres_height*sizeof(double) );

    // Scale down highres buffer into lowres buffer
    resize( highres_data, highres_width, highres_height,
            lowres_data,  lowres_width,  lowres_height );

    // Convert the (double *) lowres buffer into a (unsigned char *) buffer and
    // rescale values between 0 and 255.
    unsigned char * data =
        (unsigned char *) malloc( lowres_width*lowres_height*sizeof(unsigned char) );
    for( j=0; j < lowres_height; ++j )
    {
        for( i=0; i < lowres_width; ++i )
        {
            double v = lowres_data[j*lowres_width+i];
            data[j*lowres_width+i] = (int) (255*(1-v));
        }
    }

    // Compute new glyph information from highres value
    float ratio = lowres_size / highres_size;
    size_t pitch  = lowres_width * sizeof( unsigned char );

    // Create glyph
    texture_glyph_t * glyph = texture_glyph_new( );
    glyph->offset_x = (slot->bitmap_left + padding*highres_width) * ratio;
    glyph->offset_y = (slot->bitmap_top + padding*highres_height) * ratio;
    glyph->width    = lowres_width;
    glyph->height   = lowres_height;
    glyph->charcode = utf8_to_utf32( charcode );
    /*
    printf( "Glyph width:  %ld\n", glyph->width );
    printf( "Glyph height: %ld\n", glyph->height );
    printf( "Glyph offset x: %d\n", glyph->offset_x );
    printf( "Glyph offset y: %d\n", glyph->offset_y );
    */
    ivec4 region = texture_atlas_get_region( atlas, glyph->width, glyph->height );
    /*
    printf( "Region x : %d\n", region.x );
    printf( "Region y : %d\n", region.y );
    printf( "Region width : %d\n", region.width );
    printf( "Region height : %d\n", region.height );
    */
    texture_atlas_set_region( atlas, region.x, region.y, glyph->width, glyph->height, data, pitch );
    glyph->s0       = region.x/(float)atlas->width;
    glyph->t0       = region.y/(float)atlas->height;
    glyph->s1       = (region.x + glyph->width)/(float)atlas->width;
    glyph->t1       = (region.y + glyph->height)/(float)atlas->height;

    FT_Load_Glyph( face, glyph_index,
                   FT_LOAD_RENDER | FT_LOAD_NO_HINTING | FT_LOAD_NO_AUTOHINT);
    glyph->advance_x = ratio * face->glyph->advance.x/64.0;
    glyph->advance_y = ratio * face->glyph->advance.y/64.0;
    /*
    printf( "Advance x : %f\n", glyph->advance_x );
    printf( "Advance y : %f\n", glyph->advance_y );
    */
    free( highres_data );
    free( lowres_data );
    free( data );

    return glyph;
}
Ejemplo n.º 19
0
//-----------------------------------------------------------------------------
// делаем генерацию нужных символов по списку генерируя одну текстуру
//-----------------------------------------------------------------------------
void vw_GenerateFontChars(int FontTextureWidth, int FontTextureHeight, const char * CharsList)
{

	printf("Font characters generation start.\n");

	// будем использовать последовательность как имя текстуры
	const char *TextureName = CharsList;
	// временный массив
	BYTE * DIB;
	DIB = new BYTE[FontTextureWidth*FontTextureHeight*4]; // всегда делаем rgba
	// устанавливаем 0 везде, чтобы потом не краcить rgb, а только формировать альфу
	memset(DIB, 0, FontTextureWidth*FontTextureHeight*4);

	// данные для работы с вклеиванием в текстуру
	int CurrentDIBX = 0;
	int CurrentDIBY = 0;
	int EdgingSpace = 2;
	int MaxHeightInCurrentLine = 0;

	// устанавливаем размеры
	if (FT_Set_Char_Size( InternalFace, InternalFontSize <<6, InternalFontSize <<6, 96, 96 ))
	{
		fprintf(stderr, "Can't set char size %i.", InternalFontSize);
		return;
	}

	// первый проход, формируем одну большую текстуру
	const char *CharsList2 = CharsList;
	while (strlen(CharsList) > 0)
	{
		unsigned CurrentChar;
		// преобразуем в утф32 и "сдвигаемся" на следующий символ в строке
		CharsList = utf8_to_utf32(CharsList, &CurrentChar);


		// загрузка глифа нужного нам символа
		if (FT_Load_Char( InternalFace, CurrentChar, FT_LOAD_RENDER | FT_LOAD_NO_HINTING | FT_LOAD_NO_AUTOHINT))
		{
			fprintf(stderr, "Can't load Char: %u\n", CurrentChar);
			return;
		}

		// создаем структуру FontChar
		eFontChar* NewChar;
		NewChar = new eFontChar;

		NewChar->UTF32 = CurrentChar;
		NewChar->CharTexture = 0;
		NewChar->FontSize = InternalFontSize;
		NewChar->TexturePositionLeft = 0;
		NewChar->TexturePositionRight = 0;
		NewChar->TexturePositionTop = 0;
		NewChar->TexturePositionBottom = 0;
		NewChar->Width = InternalFace->glyph->bitmap.width;
		NewChar->Height = InternalFace->glyph->bitmap.rows;
		NewChar->Left = InternalFace->glyph->bitmap_left;
		NewChar->Top = InternalFace->glyph->bitmap_top;
		NewChar->AdvanceX = InternalFace->glyph->advance.x / 64.0f;
		NewChar->Prev = 0;
		NewChar->Next = 0;

		// делаем установку параметров для вклеивания

		// если в текущую строку символов уже не можем вписывать - смещаемся на новую, ниже
		if (CurrentDIBX + NewChar->Width > FontTextureWidth)
		{
			CurrentDIBX = 0;
			CurrentDIBY += MaxHeightInCurrentLine + EdgingSpace;
			MaxHeightInCurrentLine = 0;
		}
		// если в текущую строку не влазит уже по высоте - значит это фейл... кричим чтоб дали больше текстуру
		if (CurrentDIBY + NewChar->Height > FontTextureHeight)
		{
			fprintf(stderr, "!!! Can't generate all font chars in one texture. Too many chars or too small texture size!\n");
			delete NewChar;
			break;
		}

		// "вклеиваем" новый символ в массив
		BYTE ColorRGB[3]={255,255,255};
		for (int j=0; j<NewChar->Height; j++)
		for (int i=0; i<NewChar->Width; i++)
		{
			memcpy(DIB + (FontTextureHeight-CurrentDIBY-j-1)*FontTextureWidth*4 + (CurrentDIBX+i)*4,
					ColorRGB,
					3);
			memcpy(DIB + (FontTextureHeight-CurrentDIBY-j-1)*FontTextureWidth*4 + (CurrentDIBX+i)*4 + 3,
					InternalFace->glyph->bitmap.buffer+j*NewChar->Width+i,
					1);
		}

		// устанавливаем параметры текстуры для прорисовки нашему символу
		NewChar->TexturePositionLeft = CurrentDIBX;
		NewChar->TexturePositionRight = CurrentDIBX + NewChar->Width;
		NewChar->TexturePositionTop = CurrentDIBY;
		NewChar->TexturePositionBottom = CurrentDIBY + NewChar->Height;

		// выбираем наибольшую высоту символов
		if (MaxHeightInCurrentLine < NewChar->Height) MaxHeightInCurrentLine = NewChar->Height;
		// смещаем указатель
		CurrentDIBX += NewChar->Width + EdgingSpace;

		// подключаем к менеджеру
		vw_AttachFontChar(NewChar);
	}


/////////////////////////////////
/*
	// выводим в tga файл сгенерированный DIB, если нужно проверить

	SDL_RWops *TgaFile = SDL_RWFromFile("fontgenerationtest.tga", "wb");
	if (TgaFile == NULL)
    {
		fprintf(stderr, "Can't open VFS file for write.\n");
        return;
    }

	unsigned char UselessChar = 0;	// used for useless char.
	short int UselessInt = 0;		// used for useless int.
	unsigned char ImageType = 2;	// Type of image we are saving.
	unsigned char ImageBits = 32;		// Bit depth.
	short int ImageWidth = (short int)FontTextureWidth;
	short int ImageHeight = (short int)FontTextureHeight;

	// пишем неиспользуемые данные
	SDL_RWwrite(TgaFile, &UselessChar, sizeof(unsigned char), 1);
	SDL_RWwrite(TgaFile, &UselessChar, sizeof(unsigned char), 1);
	// тип картинки
	SDL_RWwrite(TgaFile, &ImageType, sizeof(unsigned char), 1);
	// пишем неиспользуемые данные
	SDL_RWwrite(TgaFile, &UselessInt, sizeof(short int), 1);
	SDL_RWwrite(TgaFile, &UselessInt, sizeof(short int), 1);
	SDL_RWwrite(TgaFile, &UselessChar, sizeof(unsigned char), 1);
	SDL_RWwrite(TgaFile, &UselessInt, sizeof(short int), 1);
	SDL_RWwrite(TgaFile, &UselessInt, sizeof(short int), 1);
	// записываем параметры картинки
	SDL_RWwrite(TgaFile, &ImageWidth, sizeof(short int), 1);
	SDL_RWwrite(TgaFile, &ImageHeight, sizeof(short int), 1);
	SDL_RWwrite(TgaFile, &ImageBits, sizeof(unsigned char), 1);
	// пишем неиспользуемые данные
	SDL_RWwrite(TgaFile, &UselessChar, sizeof(unsigned char), 1);
	// пишем данные диб массива
	SDL_RWwrite(TgaFile, DIB, FontTextureWidth*FontTextureHeight*4, 1);

	// закрываем файл
	SDL_RWclose(TgaFile);
*/
/////////////////////////////////


	// создаем текстуру
	vw_SetTextureProp(RI_MAGFILTER_LINEAR | RI_MINFILTER_LINEAR | RI_MIPFILTER_NONE, RI_CLAMP_TO_EDGE, true, TX_ALPHA_GREYSC, false);
	eTexture* FontTexture = vw_CreateTextureFromMemory(TextureName, DIB, FontTextureWidth, FontTextureHeight, 4, false);
	// освобождаем память
	delete [] DIB;
	if (FontTexture == 0)
	{
		fprintf(stderr, "Can't create font texture.\n");
		return;
	}


	// второй проход, всем FontChars из списка, присваиваем сгенерированную текстуру
	while (strlen(CharsList2) > 0)
	{
		unsigned CurrentChar;
		// преобразуем в утф32 и "сдвигаемся" на следующий символ в строке
		CharsList2 = utf8_to_utf32(CharsList2, &CurrentChar);
		// ставим нашу общую текстуру
		eFontChar* TMPChar = vw_FindFontCharByUTF32(CurrentChar);
		if (TMPChar != 0) TMPChar->CharTexture = FontTexture;
	}


	printf("Font characters generation end.\n\n");
}
Ejemplo n.º 20
0
			static utf32_string utf(utf8_char const* str, size_t size)
			{
				return utf8_to_utf32(str, size);
			}
Ejemplo n.º 21
0
std::pair<bool, u32string>
build_escaped_characters
(
  Iterator& current,
  const Iterator& end
)
{
  std::string building;
  bool error = false;
  int to_read = 0;

  while (*current == '\\' && error == false)
  {
    ++current;
    char32_t c = *current;
    switch(c)
    {
      case 'U':
      to_read = 8;
      ++current;
      break;

      case 'u':
      to_read = 4;
      ++current;
      break;

      case 'x':
      to_read = 2;
      ++current;
      break;

      case 'n':
      building += "\n";
      ++current;
      break;

      case 'r':
      building += "\r";
      ++current;
      break;

      case 't':
      building += "\t";
      ++current;
      break;

      case '\'':
      building += "\'";
      ++current;
      break;

      case '\"':
      building += "\"";
      ++current;
      break;

      case '\\':
      building += "\\";
      ++current;
      break;

      default:
      //invalid control character
      error = true;
      break;
    }

    //read the requested number of characters
    std::string chars;
    if (to_read > 0)
    {
      while (to_read > 0 && current != end && *current != '\'')
      {
        c = *current;  
        if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F'))
        {
          chars += c;
        }
        else
        {
          break;
        }
        --to_read;
        ++current;
      }
    }

    //if we didn't read everything then error
    if (to_read != 0)
    {
      error = true;
    }
    else
    {
      uint32_t value = 0;
      for (char c : chars)
      {
        if (c >= '0' && c <= '9')
        {
          value = value * 16 + (c - '0');
        }
        else
        {
          value = value * 16 + (c - 'A' + 10);
        }
      }

      //it was a byte if it was two characters, otherwise it was a whole
      //character
      if (chars.length() == 2)
      {
        building += char(value & 0xFF);
      }
      else
      {
        building += utf32_to_utf8(u32string(1, value));
      }
    }
  }

  u32string u32result = utf8_to_utf32(building);
  return std::make_pair(!error, u32result);
}
Ejemplo n.º 22
0
/*
 * Convert 16 bit Unicode pathname to wire format from string in current code
 * page. Conversion may involve remapping up the six characters that are
 * only legal in POSIX-like OS (if they are present in the string). Path
 * names are little endian 16 bit Unicode on the wire
 */
int
cifsConvertToUTF16(__le16 *target, const char *source, int srclen,
		 const struct nls_table *cp, int map_chars)
{
	int i, charlen;
	int j = 0;
	char src_char;
	__le16 dst_char;
	wchar_t tmp;
	wchar_t *wchar_to;	/* UTF-16 */
	int ret;
	unicode_t u;

	if (map_chars == NO_MAP_UNI_RSVD)
		return cifs_strtoUTF16(target, source, PATH_MAX, cp);

	wchar_to = kzalloc(6, GFP_KERNEL);

	for (i = 0; i < srclen; j++) {
		src_char = source[i];
		charlen = 1;

		/* check if end of string */
		if (src_char == 0)
			goto ctoUTF16_out;

		/* see if we must remap this char */
		if (map_chars == SFU_MAP_UNI_RSVD)
			dst_char = convert_to_sfu_char(src_char);
		else if (map_chars == SFM_MAP_UNI_RSVD) {
			bool end_of_string;

			if (i == srclen - 1)
				end_of_string = true;
			else
				end_of_string = false;

			dst_char = convert_to_sfm_char(src_char, end_of_string);
		} else
			dst_char = 0;
		/*
		 * FIXME: We can not handle remapping backslash (UNI_SLASH)
		 * until all the calls to build_path_from_dentry are modified,
		 * as they use backslash as separator.
		 */
		if (dst_char == 0) {
			charlen = cp->char2uni(source + i, srclen - i, &tmp);
			dst_char = cpu_to_le16(tmp);

			/*
			 * if no match, use question mark, which at least in
			 * some cases serves as wild card
			 */
			if (charlen > 0)
				goto ctoUTF16;

			/* convert SURROGATE_PAIR */
			if (strcmp(cp->charset, "utf8") || !wchar_to)
				goto unknown;
			if (*(source + i) & 0x80) {
				charlen = utf8_to_utf32(source + i, 6, &u);
				if (charlen < 0)
					goto unknown;
			} else
				goto unknown;
			ret  = utf8s_to_utf16s(source + i, charlen,
					       UTF16_LITTLE_ENDIAN,
					       wchar_to, 6);
			if (ret < 0)
				goto unknown;

			i += charlen;
			dst_char = cpu_to_le16(*wchar_to);
			if (charlen <= 3)
				/* 1-3bytes UTF-8 to 2bytes UTF-16 */
				put_unaligned(dst_char, &target[j]);
			else if (charlen == 4) {
				/* 4bytes UTF-8(surrogate pair) to 4bytes UTF-16
				 * 7-8bytes UTF-8(IVS) divided to 2 UTF-16
				 *   (charlen=3+4 or 4+4) */
				put_unaligned(dst_char, &target[j]);
				dst_char = cpu_to_le16(*(wchar_to + 1));
				j++;
				put_unaligned(dst_char, &target[j]);
			} else if (charlen >= 5) {
				/* 5-6bytes UTF-8 to 6bytes UTF-16 */
				put_unaligned(dst_char, &target[j]);
				dst_char = cpu_to_le16(*(wchar_to + 1));
				j++;
				put_unaligned(dst_char, &target[j]);
				dst_char = cpu_to_le16(*(wchar_to + 2));
				j++;
				put_unaligned(dst_char, &target[j]);
			}
			continue;

unknown:
			dst_char = cpu_to_le16(0x003f);
			charlen = 1;
		}

ctoUTF16:
		/*
		 * character may take more than one byte in the source string,
		 * but will take exactly two bytes in the target string
		 */
		i += charlen;
		put_unaligned(dst_char, &target[j]);
	}

ctoUTF16_out:
	put_unaligned(0, &target[j]); /* Null terminate target unicode string */
	kfree(wchar_to);
	return j;
}
Ejemplo n.º 23
0
//------------------------------------------------------------------------------------
// прорисовка фонта
//------------------------------------------------------------------------------------
void vw_DrawFont(int X, int Y, float FlattenWidth, float MaxWidth, float FontScale, float R, float G, float B, float Transp, const char *Text, ...)
{
	if (Text == 0) return;

	// учитываем аспект рейшен
	float AW;
	float AH;
	bool ASpresent=false;
	ASpresent = vw_GetAspectWH(&AW, &AH);
	// получаем данные текущего вьюпорта
	int W, H;
	vw_GetViewport(0, 0, &W, &H);
	float AHw = H*1.0f;


	// если текст ниже чем ширина нашего окна - не рисуем
	if (ASpresent){ if (Y > AH) return;}
	else {if (Y > H) return;}
	// если текст выше чем ноль - тоже рисовать его смысла нет
	if (Y+InternalFontSize*FontScale < 0) return;


// FlattenWidth - выравнивать по ширине
// если FlattenWidth отрицателен, выравниваем по значению, "сжимая" буквы, если нужно
// MaxWidth - рисовать до ширины


	// смотрим значения параметров в строке
	char	text[1024];
	va_list		ap;
	va_start(ap, Text);
	vsprintf(text, Text, ap);
	va_end(ap);
	// в text уже полная строка
	if (strlen(text) == 0) return;

	float Xstart = X;
	// сразу определяем "базовую" ширину пробела, чтобы учитывать в расчетах
	if (vw_FindFontCharByUTF32(0x020) == 0) vw_LoadFontChar(0x020);
	float SpaceWidth = vw_FindFontCharByUTF32(0x020)->AdvanceX*FontScale;
	// чтобы было более читаемо - делаем пробел не менее 2/3 ширины
	if (SpaceWidth < (InternalFontSize * 0.65f)) SpaceWidth = InternalFontSize * 0.65f;
	// коэф. изменения букв по ширине
	float FontWidthScale = 1.0f;

	if (Transp >= 1.0f) Transp = 1.0f;


	// если нужно выравнивать, считаем данные пробелов
	if (FlattenWidth > 0)
	{
		float LineWidth = 0;
		int SpaceCount = 0;

		const char *CountCheck = text;
		while (strlen(CountCheck) > 0)
		{
			unsigned UTF32;
			// преобразуем в утф32 и "сдвигаемся" на следующий символ в строке
			CountCheck = utf8_to_utf32(CountCheck, &UTF32);
			// находим наш текущий символ
			eFontChar* DrawChar = vw_FindFontCharByUTF32(UTF32);
			if (DrawChar == 0) DrawChar = vw_LoadFontChar(UTF32);

			// считаем кол-во пробелов
			if (UTF32 == 0x020)
				SpaceCount++;
			else
				LineWidth += DrawChar->AdvanceX;
		}

		if (FlattenWidth > LineWidth)
			if (SpaceCount!=0) SpaceWidth = (FlattenWidth - LineWidth)/SpaceCount;
	}
	// если нужно сжать, считаем коэф. сжатия букв
	if (FlattenWidth < 0)
	{
		float LineWidth = 0;

		const char *CountCheck = text;
		while (strlen(CountCheck) > 0)
		{
			unsigned UTF32;
			// преобразуем в утф32 и "сдвигаемся" на следующий символ в строке
			CountCheck = utf8_to_utf32(CountCheck, &UTF32);
			// находим наш текущий символ
			eFontChar* DrawChar = vw_FindFontCharByUTF32(UTF32);
			if (DrawChar == 0) DrawChar = vw_LoadFontChar(UTF32);

			// считаем длину символов с пробелами
			if (UTF32 != 0x020)
				LineWidth += DrawChar->AdvanceX;
			else
				LineWidth += SpaceWidth;
		}

		if (FlattenWidth*(-1.0f) < LineWidth) FontWidthScale = FlattenWidth/LineWidth*(-1.0f);
	}


	float LineWidth = 0;

	// установка свойств текстуры
	vw_SetTextureBlend(true, RI_BLEND_SRCALPHA, RI_BLEND_INVSRCALPHA);
	// ставим цвет
	vw_SetColor(R, G, B, Transp);

	// для отрисовки
	eTexture* CurrentTexture = 0;
	int k=0;
	// буфер для последовательности RI_QUADS
	// войдет RI_2f_XYZ | RI_2f_TEX
#ifdef USE_GLES
	float tmp[(2+2)*6*strlen(text)]; 
#else
	float tmp[(2+2)*4*strlen(text)]; 
#endif

	// чтобы меньше делать операций умножения, включаем коэф. один в другой сразу для ширины символов
	FontWidthScale = FontScale*FontWidthScale;


	// прорисовка текста
	const char *textdraw = text;
	// прорисовываем все символы
	while (strlen(textdraw) > 0)
	{
		unsigned UTF32;
		// преобразуем в утф32 и "сдвигаемся" на следующий символ в строке
		textdraw = utf8_to_utf32(textdraw, &UTF32);
		// находим наш текущий символ
		eFontChar* DrawChar = vw_FindFontCharByUTF32(UTF32);
		if (DrawChar == 0) DrawChar = vw_LoadFontChar(UTF32);
		// первый символ - запоминаем его текстуру
		if (CurrentTexture == 0) CurrentTexture = DrawChar->CharTexture;


		// проверка на текстуру, если текстура поменялась - отрисовываем все что есть в буфере, если там что-то есть
		if (CurrentTexture != DrawChar->CharTexture)
		{
			// если что-то было в буфере - выводим
			if (k > 0)
			{
				// Установка текстуры
				vw_SetTexture(0, CurrentTexture);
				// отрисовываем все что есть в буфере
#ifdef USE_GLES
				vw_SendVertices(RI_QUADS, 6*(k/24), RI_2f_XY | RI_1_TEX, tmp, 4*sizeof(float));
#else
				vw_SendVertices(RI_QUADS, 4*(k/16), RI_2f_XY | RI_1_TEX, tmp, 4*sizeof(float));
#endif
			}


			// запоминаем новую текстуру
			CurrentTexture = DrawChar->CharTexture;
			// сбрасываем счетчики
			k=0;
		}


		// если не пробел - рисуем
		if (UTF32 != 0x020)
		{

			float DrawX = Xstart + DrawChar->Left*FontWidthScale;
			float DrawY = Y + GlobalFontOffsetY + (InternalFontSize - DrawChar->Top)*FontScale;

			// Вычисление поправки по У в зависимости от DrawCorner
			// - расположения угла начала координат
			float tmpPosY = 0;
			// изменяем только в случае RI_UL_CORNER
			if (ASpresent) tmpPosY = (AH - DrawY - DrawY - DrawChar->Height*FontScale);
			else tmpPosY = (AHw - DrawY - DrawY - DrawChar->Height*FontScale);

			float ImageHeight = DrawChar->CharTexture->Height*1.0f;
			float ImageWidth = DrawChar->CharTexture->Width*1.0f;

			float FrameHeight = (DrawChar->TexturePositionBottom*1.0f )/ImageHeight;
			float FrameWidth = (DrawChar->TexturePositionRight*1.0f )/ImageWidth;

			float Yst = (DrawChar->TexturePositionTop*1.0f)/ImageHeight;
			float Xst = (DrawChar->TexturePositionLeft*1.0f)/ImageWidth;
#ifdef USE_GLES
			tmp[k++] = DrawX;
			tmp[k++] = DrawY +tmpPosY + DrawChar->Height*FontScale;
			tmp[k++] = Xst;
			tmp[k++] = 1.0f-Yst;

			tmp[k++] = DrawX;
			tmp[k++] = DrawY +tmpPosY + DrawChar->Height*FontScale;
			tmp[k++] = Xst;
			tmp[k++] = 1.0f-Yst;

			tmp[k++] = DrawX;
			tmp[k++] = DrawY +tmpPosY;
			tmp[k++] = Xst;
			tmp[k++] = 1.0f-FrameHeight;

			tmp[k++] = DrawX + DrawChar->Width*FontWidthScale;
			tmp[k++] = DrawY +tmpPosY + DrawChar->Height*FontScale;
			tmp[k++] = FrameWidth;
			tmp[k++] = 1.0f-Yst;

			tmp[k++] = DrawX + DrawChar->Width*FontWidthScale;
			tmp[k++] = DrawY +tmpPosY;
			tmp[k++] = FrameWidth;
			tmp[k++] = 1.0f-FrameHeight;

			tmp[k++] = DrawX + DrawChar->Width*FontWidthScale;
			tmp[k++] = DrawY +tmpPosY;
			tmp[k++] = FrameWidth;
			tmp[k++] = 1.0f-FrameHeight;

#else
			tmp[k++] = DrawX;
			tmp[k++] = DrawY +tmpPosY + DrawChar->Height*FontScale;
			tmp[k++] = Xst;
			tmp[k++] = 1.0f-Yst;

			tmp[k++] = DrawX;
			tmp[k++] = DrawY +tmpPosY;
			tmp[k++] = Xst;
			tmp[k++] = 1.0f-FrameHeight;

			tmp[k++] = DrawX + DrawChar->Width*FontWidthScale;
			tmp[k++] = DrawY +tmpPosY;
			tmp[k++] = FrameWidth;
			tmp[k++] = 1.0f-FrameHeight;

			tmp[k++] = DrawX + DrawChar->Width*FontWidthScale;
			tmp[k++] = DrawY +tmpPosY + DrawChar->Height*FontScale;
			tmp[k++] = FrameWidth;
			tmp[k++] = 1.0f-Yst;
#endif


			Xstart += DrawChar->AdvanceX*FontWidthScale;
			LineWidth += DrawChar->AdvanceX*FontWidthScale;
		}
		else
		{
			Xstart += SpaceWidth*FontWidthScale;
			LineWidth += SpaceWidth*FontWidthScale;
		}
		// если нужно прорисовывать с ограничением по длине
		if (MaxWidth != 0.0f)
			if (LineWidth >= MaxWidth) break;
	}


	// если что-то было в буфере - выводим
	if (k > 0)
	{
		// Установка текстуры
		vw_SetTexture(0, CurrentTexture);
		// отрисовываем все что есть в буфере
#ifdef USE_GLES
		vw_SendVertices(RI_QUADS, 6*(k/24), RI_2f_XY | RI_1_TEX, tmp, 4*sizeof(float));
#else
		vw_SendVertices(RI_QUADS, 4*(k/16), RI_2f_XY | RI_1_TEX, tmp, 4*sizeof(float));
#endif
	}



	vw_SetColor(1.0f, 1.0f, 1.0f, 1.0f);
	vw_SetTextureBlend(false, 0, 0);
	vw_BindTexture(0, 0);
}
Ejemplo n.º 24
0
void glf_render_str(gl_tex_font_p glf, GLfloat x, GLfloat y, const char *text, int32_t n_sym)
{
    if(glf && glf->ft_face && text && (text[0] != 0))
    {
        uint8_t *nch, *ch = (uint8_t*)text;
        FT_Vector kern;
        int32_t x_pt = 0;
        int32_t y_pt = 0;
        if(glf->gl_real_tex_indexes_count == 1)
        {
            GLuint elements_count = 0;
            uint32_t curr_utf32, next_utf32;
            GLfloat *p, *buffer;

            buffer = (GLfloat*)malloc(48 * utf8_strlen(text) * sizeof(GLfloat));
            nch = utf8_to_utf32(ch, &curr_utf32);
            curr_utf32 = FT_Get_Char_Index(glf->ft_face, curr_utf32);

            qglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
            for(p = buffer; *ch && n_sym--;)
            {
                char_info_p g;
                uint8_t *nch2 = utf8_to_utf32(nch, &next_utf32);

                next_utf32 = FT_Get_Char_Index(glf->ft_face, next_utf32);
                ch = nch;
                nch = nch2;

                g = glf->glyphs + curr_utf32;
                FT_Get_Kerning(glf->ft_face, curr_utf32, next_utf32, FT_KERNING_UNSCALED, &kern);   // kern in 1/64 pixel
                curr_utf32 = next_utf32;

                if(g->tex_index != 0)
                {
                    GLfloat x0 = x  + g->left + x_pt / 64.0f;
                    GLfloat x1 = x0 + g->width;
                    GLfloat y0 = y  + g->top + y_pt / 64.0f;
                    GLfloat y1 = y0 - g->height;

                    *p = x0;            p++;
                    *p = y0;            p++;
                    *p = g->tex_x0;     p++;
                    *p = g->tex_y0;     p++;
                    vec4_copy(p, glf->gl_font_color);   p += 4;

                    *p = x1;            p++;
                    *p = y0;            p++;
                    *p = g->tex_x1;     p++;
                    *p = g->tex_y0;     p++;
                    vec4_copy(p, glf->gl_font_color);   p += 4;

                    *p = x1;            p++;
                    *p = y1;            p++;
                    *p = g->tex_x1;     p++;
                    *p = g->tex_y1;     p++;
                    vec4_copy(p, glf->gl_font_color);   p += 4;
                    elements_count++;

                    *p = x0;            p++;
                    *p = y0;            p++;
                    *p = g->tex_x0;     p++;
                    *p = g->tex_y0;     p++;
                    vec4_copy(p, glf->gl_font_color);   p += 4;

                    *p = x1;            p++;
                    *p = y1;            p++;
                    *p = g->tex_x1;     p++;
                    *p = g->tex_y1;     p++;
                    vec4_copy(p, glf->gl_font_color);   p += 4;

                    *p = x0;            p++;
                    *p = y1;            p++;
                    *p = g->tex_x0;     p++;
                    *p = g->tex_y1;     p++;
                    vec4_copy(p, glf->gl_font_color);   p += 4;
                    elements_count++;
                }
                x_pt += kern.x + g->advance_x_pt;
                y_pt += kern.y + g->advance_y_pt;
            }
            ///RENDER
            if(elements_count != 0)
            {
                qglBindTexture(GL_TEXTURE_2D, glf->gl_tex_indexes[0]);
                qglVertexPointer(2, GL_FLOAT, 8 * sizeof(GLfloat), buffer+0);
                qglTexCoordPointer(2, GL_FLOAT, 8 * sizeof(GLfloat), buffer+2);
                qglColorPointer(4, GL_FLOAT, 8 * sizeof(GLfloat), buffer+4);
                qglDrawArrays(GL_TRIANGLES, 0, elements_count * 3);
            }
            qglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
            free(buffer);
        }
        else
        {
            GLfloat *p, buffer[32];
            GLuint active_texture = 0;
            uint32_t curr_utf32, next_utf32;
            nch = utf8_to_utf32(ch, &curr_utf32);
            curr_utf32 = FT_Get_Char_Index(glf->ft_face, curr_utf32);
            qglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
            for(; *ch && n_sym--;)
            {
                char_info_p g;
                uint8_t *nch2 = utf8_to_utf32(nch, &next_utf32);

                next_utf32 = FT_Get_Char_Index(glf->ft_face, next_utf32);
                ch = nch;
                nch = nch2;

                g = glf->glyphs + curr_utf32;
                FT_Get_Kerning(glf->ft_face, curr_utf32, next_utf32, FT_KERNING_UNSCALED, &kern);   // kern in 1/64 pixel
                curr_utf32 = next_utf32;

                if(g->tex_index != 0)
                {
                    ///RENDER
                    GLfloat x0 = x  + g->left + x_pt / 64.0f;
                    GLfloat x1 = x0 + g->width;
                    GLfloat y0 = y  + g->top + y_pt / 64.0f;
                    GLfloat y1 = y0 - g->height;

                    p = buffer;
                    *p = x0;            p++;
                    *p = y0;            p++;
                    *p = g->tex_x0;     p++;
                    *p = g->tex_y0;     p++;
                    vec4_copy(p, glf->gl_font_color);   p += 4;

                    *p = x1;            p++;
                    *p = y0;            p++;
                    *p = g->tex_x1;     p++;
                    *p = g->tex_y0;     p++;
                    vec4_copy(p, glf->gl_font_color);   p += 4;

                    *p = x1;            p++;
                    *p = y1;            p++;
                    *p = g->tex_x1;     p++;
                    *p = g->tex_y1;     p++;
                    vec4_copy(p, glf->gl_font_color);   p += 4;

                    *p = x0;            p++;
                    *p = y1;            p++;
                    *p = g->tex_x0;     p++;
                    *p = g->tex_y1;     p++;
                    vec4_copy(p, glf->gl_font_color);

                    if(active_texture != g->tex_index)
                    {
                        qglBindTexture(GL_TEXTURE_2D, g->tex_index);
                        active_texture = g->tex_index;
                    }
                    qglVertexPointer(2, GL_FLOAT, 8 * sizeof(GLfloat), buffer+0);
                    qglTexCoordPointer(2, GL_FLOAT, 8 * sizeof(GLfloat), buffer+2);
                    qglColorPointer(4, GL_FLOAT, 8 * sizeof(GLfloat), buffer+4);
                    qglDrawArrays(GL_TRIANGLE_FAN, 0, 4);
                }
                x_pt += kern.x + g->advance_x_pt;
                y_pt += kern.y + g->advance_y_pt;
            }
        }
    }
}
Ejemplo n.º 25
0
//------------------------------------------------------------------------------------
// прорисовка фонта в 3д пространстве
//------------------------------------------------------------------------------------
void vw_DrawFont3D(float X, float Y, float Z, const char *Text, ...)
{

	if (Text == 0) return;

	// смотрим значения параметров в строке
	char	text[1024];
	va_list		ap;
	va_start(ap, Text);
	vsprintf(text, Text, ap);
	va_end(ap);
	// в text уже полная строка
	if (strlen(text) == 0) return;
	// прорисовка текста
	const char *textdraw = text;


	float Xstart = 0.0f;
	// сразу определяем "базовую" ширину пробела
	float SpaceWidth = vw_FindFontCharByUTF32(0x020)->AdvanceX;
	// чтобы было более читаемо - делаем пробел не менее 2/3 ширины
	if (SpaceWidth < (InternalFontSize * 0.65f)) SpaceWidth = InternalFontSize * 0.65f;

	textdraw = text;


	// для отрисовки
	eTexture* CurrentTexture = 0;
	int k=0;
	// буфер для последовательности RI_QUADS
	// войдет RI_2f_XY | RI_2f_TEX
#ifdef USE_GLES
	float tmp[(2+2)*6*strlen(textdraw)];
#else
	float tmp[(2+2)*4*strlen(textdraw)];
#endif

	// установка свойств текстуры
	vw_SetTextureBlend(true, RI_BLEND_SRCALPHA, RI_BLEND_INVSRCALPHA);
	// всегда стаим белый цвет
	vw_SetColor(1.0f, 1.0f, 1.0f, 1.0f);

	vw_PushMatrix();

	vw_Translate(VECTOR3D(X, Y, Z));
	VECTOR3D CurrentCameraRotation;
	vw_GetCameraRotation(&CurrentCameraRotation);

	// поворачиваем к камере
	vw_Rotate(CurrentCameraRotation.y, 0.0f, 1.0f, 0.0f);
	vw_Rotate(CurrentCameraRotation.x, 1.0f, 0.0f, 0.0f);


	// прорисовываем все символы
	while (strlen(textdraw) > 0)
	{
		unsigned UTF32;
		// преобразуем в утф32 и "сдвигаемся" на следующий символ в строке
		textdraw = utf8_to_utf32(textdraw, &UTF32);
		// находим наш текущий символ
		eFontChar* DrawChar = vw_FindFontCharByUTF32(UTF32);
		if (DrawChar == 0) DrawChar = vw_LoadFontChar(UTF32);
		// первый символ - запоминаем его текстуру
		if (CurrentTexture == 0) CurrentTexture = DrawChar->CharTexture;


		// проверка на текстуру, если текстура поменялась - отрисовываем все что есть в буфере, если там что-то есть
		if (CurrentTexture != DrawChar->CharTexture)
		{
			// если что-то было в буфере - выводим
			if (k > 0)
			{
				// Установка текстуры
				vw_SetTexture(0, CurrentTexture);
				// отрисовываем все что есть в буфере
				vw_SendVertices(RI_QUADS, 4*(k/16), RI_2f_XY | RI_1_TEX, tmp, 4*sizeof(float));
			}


			// запоминаем новую текстуру
			CurrentTexture = DrawChar->CharTexture;
			// сбрасываем счетчики
			k=0;
		}


		// если не пробел - рисуем
		if (UTF32 != 0x020)
		{
			float DrawX = Xstart + DrawChar->Left;
			float DrawY = InternalFontSize - DrawChar->Top;


			float ImageHeight = DrawChar->CharTexture->Height*1.0f;
			float ImageWidth = DrawChar->CharTexture->Width*1.0f;

			float FrameHeight = (DrawChar->TexturePositionBottom*1.0f )/ImageHeight;
			float FrameWidth = (DrawChar->TexturePositionRight*1.0f )/ImageWidth;

			float Yst = (DrawChar->TexturePositionTop*1.0f)/ImageHeight;
			float Xst = (DrawChar->TexturePositionLeft*1.0f)/ImageWidth;

#ifdef USE_GLES
			tmp[k++] = DrawX/10.0f;
			tmp[k++] = (DrawY + DrawChar->Height)/10.0f;
			tmp[k++] = Xst;
			tmp[k++] = 1.0f-Yst;

			tmp[k++] = DrawX/10.0f;
			tmp[k++] = (DrawY + DrawChar->Height)/10.0f;
			tmp[k++] = Xst;
			tmp[k++] = 1.0f-Yst;

			tmp[k++] = DrawX/10.0f;
			tmp[k++] = DrawY/10.0f;
			tmp[k++] = Xst;
			tmp[k++] = 1.0f-FrameHeight;

			tmp[k++] = (DrawX + DrawChar->Width)/10.0f;
			tmp[k++] = (DrawY + DrawChar->Height)/10.0f;
			tmp[k++] = FrameWidth;
			tmp[k++] = 1.0f-Yst;

			tmp[k++] = (DrawX + DrawChar->Width)/10.0f;
			tmp[k++] = DrawY/10.0f;
			tmp[k++] = FrameWidth;
			tmp[k++] = 1.0f-FrameHeight;

			tmp[k++] = (DrawX + DrawChar->Width)/10.0f;
			tmp[k++] = DrawY/10.0f;
			tmp[k++] = FrameWidth;
			tmp[k++] = 1.0f-FrameHeight;
#else
			tmp[k++] = DrawX/10.0f;
			tmp[k++] = (DrawY + DrawChar->Height)/10.0f;
			tmp[k++] = Xst;
			tmp[k++] = 1.0f-Yst;

			tmp[k++] = DrawX/10.0f;
			tmp[k++] = DrawY/10.0f;
			tmp[k++] = Xst;
			tmp[k++] = 1.0f-FrameHeight;

			tmp[k++] = (DrawX + DrawChar->Width)/10.0f;
			tmp[k++] = DrawY/10.0f;
			tmp[k++] = FrameWidth;
			tmp[k++] = 1.0f-FrameHeight;

			tmp[k++] = (DrawX + DrawChar->Width)/10.0f;
			tmp[k++] = (DrawY + DrawChar->Height)/10.0f;
			tmp[k++] = FrameWidth;
			tmp[k++] = 1.0f-Yst;
#endif


			Xstart += DrawChar->AdvanceX;
		}
		else
		{
			Xstart += SpaceWidth;
		}

	}


	// если что-то было в буфере - выводим
	if (k > 0)
	{
		// Установка текстуры
		vw_SetTexture(0, CurrentTexture);
		// отрисовываем все что есть в буфере
#ifdef USE_GLES
		vw_SendVertices(RI_QUADS, 6*(k/16), RI_2f_XY | RI_1_TEX, tmp, 4*sizeof(float));
#else
		vw_SendVertices(RI_QUADS, 4*(k/16), RI_2f_XY | RI_1_TEX, tmp, 4*sizeof(float));
#endif
	}


	vw_PopMatrix();



	vw_SetTextureBlend(false, 0, 0);
	vw_BindTexture(0, 0);

}
Ejemplo n.º 26
0
size_t String8::getUtf32(char32_t* dst, size_t dst_len) const
{
    return utf8_to_utf32(mString, length(), dst, dst_len);
}
Ejemplo n.º 27
0
int sf_nlscpy(struct sf_glob_info *sf_g,
              char *name, size_t name_bound_len,
              const unsigned char *utf8_name, size_t utf8_len)
{
    if (sf_g->nls)
    {
        const char *in;
        char *out;
        size_t out_len;
        size_t out_bound_len;
        size_t in_bound_len;

        in = utf8_name;
        in_bound_len = utf8_len;

        out = name;
        out_len = 0;
        out_bound_len = name_bound_len;

        while (in_bound_len)
        {
            int nb;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)
            unicode_t uni;

            nb = utf8_to_utf32(in, in_bound_len, &uni);
#else
            linux_wchar_t uni;

            nb = utf8_mbtowc(&uni, in, in_bound_len);
#endif
            if (nb < 0)
            {
                LogFunc(("utf8_mbtowc failed(%s) %x:%d\n",
                            (const char *) utf8_name, *in, in_bound_len));
                return -EINVAL;
            }
            in += nb;
            in_bound_len -= nb;

            nb = sf_g->nls->uni2char(uni, out, out_bound_len);
            if (nb < 0)
            {
                LogFunc(("nls->uni2char failed(%s) %x:%d\n",
                            utf8_name, uni, out_bound_len));
                return nb;
            }
            out += nb;
            out_bound_len -= nb;
            out_len += nb;
        }

        *out = 0;
    }
    else
    {
        if (utf8_len + 1 > name_bound_len)
            return -ENAMETOOLONG;

        memcpy(name, utf8_name, utf8_len + 1);
    }
    return 0;
}
Ejemplo n.º 28
0
 void Button_base::set_label(const std::string &label)
 {
     set_label( utf8_to_utf32(label) );
 }