Пример #1
0
float Font::getKerning(Uint32 first, Uint32 second, unsigned int characterSize) const
{
    // Special case where first or second is 0 (null character)
    if (first == 0 || second == 0)
        return 0.f;

    FT_Face face = static_cast<FT_Face>(m_face);

    if (face && FT_HAS_KERNING(face) && setCurrentSize(characterSize))
    {
        // Convert the characters to indices
        FT_UInt index1 = FT_Get_Char_Index(face, first);
        FT_UInt index2 = FT_Get_Char_Index(face, second);

        // Get the kerning vector
        FT_Vector kerning;
        FT_Get_Kerning(face, index1, index2, FT_KERNING_DEFAULT, &kerning);

        // X advance is already in pixels for bitmap fonts
        if (!FT_IS_SCALABLE(face))
            return static_cast<float>(kerning.x);

        // Return the X advance
        return static_cast<float>(kerning.x) / static_cast<float>(1 << 6);
    }
    else
    {
        // Invalid font, or no kerning
        return 0.f;
    }
}
Пример #2
0
int  FontFreeType::getHorizontalKerningForChars(unsigned short firstChar, unsigned short secondChar)
{
    if (!_fontRef)
        return 0;

    bool hasKerning = FT_HAS_KERNING( _fontRef );
    
    if (!hasKerning)
        return 0;
    
    // get the ID to the char we need
    int glyph_index1 = FT_Get_Char_Index(_fontRef, firstChar);
    
    if (!glyph_index1)
        return 0;
    
    // get the ID to the char we need
    int glyph_index2 = FT_Get_Char_Index(_fontRef, secondChar);
    
    if (!glyph_index2)
        return 0;
    
    FT_Vector kerning;
    
    if (FT_Get_Kerning( _fontRef, glyph_index1, glyph_index2,  FT_KERNING_DEFAULT,  &kerning ))
        return 0;
    
    return ( kerning.x >> 6 );
}
Пример #3
0
int RenderChar(FT_ULong currentchar, int sx, int sy, int ex, int color)
{
	int row, pitch, bit, x = 0, y = 0;
	FT_UInt glyphindex;
	FT_Vector kerning;
	FTC_Node anode;

	//load char

		if(!(glyphindex = FT_Get_Char_Index(face, currentchar)))
		{
//			printf("<FT_Get_Char_Index for Char \"%c\" failed with Errorcode 0x%.2X>\n", (int)currentchar, error);
			return 0;
		}

		if((error = FTC_SBitCache_Lookup(cache, &desc, glyphindex, &sbit, &anode)))
		{
//			printf("<FTC_SBitCache_Lookup for Char \"%c\" failed with Errorcode 0x%.2X>\n", (int)currentchar, error);
			return 0;
		}

		if(use_kerning)
		{
			FT_Get_Kerning(face, prev_glyphindex, glyphindex, ft_kerning_default, &kerning);

			prev_glyphindex = glyphindex;
			kerning.x >>= 6;
		}
		else kerning.x = 0;
Пример #4
0
//------------------------------------------------------------------------
bool font_engine_freetype_base::add_kerning(unsigned first, unsigned second,
        double* x, double* y)
{
    if(m_cur_face && first && second && FT_HAS_KERNING(m_cur_face))
    {
        FT_Vector delta;

        FT_Get_Kerning(m_cur_face, first, second,
                       FT_KERNING_DEFAULT, &delta);

        double dx = int26p6_to_dbl(delta.x);
        double dy = int26p6_to_dbl(delta.y);
        if(m_glyph_rendering == glyph_ren_outline ||
                m_glyph_rendering == glyph_ren_agg_mono ||
                m_glyph_rendering == glyph_ren_agg_gray8)
        {
            m_affine.transform_2x2(&dx, &dy);
        }
        *x += dx;
        *y += dy;

        return true;
    }
    return false;
}
Пример #5
0
void FTFace::BuildKerningCache()
{
    FT_Vector kernAdvance;
    kernAdvance.x = 0;
    kernAdvance.y = 0;
    kerningCache = new FTGL_DOUBLE[FTFace::MAX_PRECOMPUTED
				   * FTFace::MAX_PRECOMPUTED * 2];
    for(unsigned int j = 0; j < FTFace::MAX_PRECOMPUTED; j++)
    {
        for(unsigned int i = 0; i < FTFace::MAX_PRECOMPUTED; i++)
        {
            err = FT_Get_Kerning(*ftFace, i, j, ft_kerning_unfitted,
                                 &kernAdvance);
            if(err)
            {
                delete[] kerningCache;
                kerningCache = NULL;
                return;
            }

            kerningCache[2 * (j * FTFace::MAX_PRECOMPUTED + i)] =
                                static_cast<FTGL_DOUBLE>(kernAdvance.x) / 64.0;
            kerningCache[2 * (j * FTFace::MAX_PRECOMPUTED + i) + 1] =
                                static_cast<FTGL_DOUBLE>(kernAdvance.y) / 64.0;
        }
    }
}
Пример #6
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;
}
Пример #7
0
FTPoint FTFace::KernAdvance(unsigned int index1, unsigned int index2)
{
    FTGL_DOUBLE x, y;

    if(!hasKerningTable || !index1 || !index2)
    {
        return FTPoint(0.0, 0.0);
    }

    if(kerningCache && index1 < FTFace::MAX_PRECOMPUTED
        && index2 < FTFace::MAX_PRECOMPUTED)
    {
        x = kerningCache[2 * (index2 * FTFace::MAX_PRECOMPUTED + index1)];
        y = kerningCache[2 * (index2 * FTFace::MAX_PRECOMPUTED + index1) + 1];
        return FTPoint(x, y);
    }

    FT_Vector kernAdvance;
    kernAdvance.x = kernAdvance.y = 0;

    err = FT_Get_Kerning(*ftFace, index1, index2, ft_kerning_unfitted,
                         &kernAdvance);
    if(err)
    {
        return FTPoint(0.0f, 0.0f);
    }

    x = static_cast<float>(kernAdvance.x) / 64.0f;
    y = static_cast<float>(kernAdvance.y) / 64.0f;

    return FTPoint(x, y);
}
Пример #8
0
//-----------------------------------------------------------
int ofTrueTypeFont::getKerning(int c, int prevC) const{
    if(useKerning){
        FT_Vector kerning;
        FT_Get_Kerning(face, FT_Get_Char_Index(face, prevC), FT_Get_Char_Index(face, c), FT_KERNING_UNFITTED, &kerning);
        return kerning.x>>6;
    }else{
        return 0;
Пример #9
0
static void line_extents(VGFT_FONT_T *font, VGfloat *x, VGfloat *y, const char *text, int chars_count)
{
   int i;
   int prev_glyph_index = 0;
   if (chars_count == 0) return;

   for (i=0; i < chars_count; i++)
   {
      int glyph_index = FT_Get_Char_Index(font->ft_face, text[i]);
      if (!glyph_index) return;

      if (i != 0)
      {
         FT_Vector kern;
         if (FT_Get_Kerning(font->ft_face, prev_glyph_index, glyph_index,
                            FT_KERNING_DEFAULT, &kern))
         {
            assert(0);
         }
         *x += float_from_26_6(kern.x);
         *y += float_from_26_6(kern.y);
      }
      FT_Load_Glyph(font->ft_face, glyph_index, FT_LOAD_DEFAULT);
      *x += float_from_26_6(font->ft_face->glyph->advance.x);
   }
}
Пример #10
0
osg::Vec2 FreeTypeFont::getKerning(const osgText::FontResolution& fontRes, unsigned int leftcharcode, unsigned int rightcharcode, osgText::KerningType kerningType)
{
    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(FreeTypeLibrary::instance()->getMutex());

    setFontResolution(fontRes);

    if (!FT_HAS_KERNING(_face) || (kerningType == osgText::KERNING_NONE)) return osg::Vec2(0.0f,0.0f);

    FT_Kerning_Mode mode = (kerningType==osgText::KERNING_DEFAULT) ? ft_kerning_default : ft_kerning_unfitted;

    // convert character code to glyph index
    FT_UInt left = FT_Get_Char_Index( _face, leftcharcode );
    FT_UInt right = FT_Get_Char_Index( _face, rightcharcode );

    // get the kerning distances.
    FT_Vector  kerning;

    FT_Error error = FT_Get_Kerning( _face,                     // handle to face object
                                     left,                      // left glyph index
                                     right,                     // right glyph index
                                     mode,                      // kerning mode
                                     &kerning );                // target vector

    if (error)
    {
        OSG_WARN << "FT_Get_Kerning(...) returned error code " <<std::hex<<error<<std::dec<< std::endl;
        return osg::Vec2(0.0f,0.0f);
    }

    float coord_scale = getCoordScale();

    return osg::Vec2((float)kerning.x*coord_scale,(float)kerning.y*coord_scale);
}
Пример #11
0
GLubyte *app::font::glyph(FT_Int32 flag, int curr, int prev,
                          int& x, int& y, int& w, int& h, int& a, int& k)
{
    FT_Vector kern;

    // Look up the current pair of characters.

    FT_UInt L = FT_Get_Char_Index(face, prev);
    FT_UInt R = FT_Get_Char_Index(face, curr);

    // Get the kerning and glyph sizes.

    FT_Get_Kerning(face, L, R, FT_KERNING_DEFAULT, &kern);
    FT_Load_Glyph (face, R, flag);

    // Convert these values to pixels and return the buffer.

    x = face->glyph->metrics.horiBearingX >> 6;
    y = face->glyph->metrics.horiBearingY >> 6;
    w = face->glyph->metrics.width        >> 6;
    h = face->glyph->metrics.height       >> 6;
    a = face->glyph->advance.x            >> 6;
    k = kern.x                            >> 6;

    return (GLubyte *) face->glyph->bitmap.buffer;
}
Пример #12
0
void Font::draw(IScene* scene, const char* text, glm::mat4 transform, float font_size, glm::vec3 color)
{
	FT_Set_Pixel_Sizes(m_font_face, font_size, font_size);
    glUseProgram(TEXT_PROGRAM);
    checkGLError();

    glm::vec3 pen(0, 0, 0);
    char prev = 0;
    bool kern = FT_HAS_KERNING(m_font_face);
    for(const char* i = text; i[0]; ++i) {
        FT_UInt index = FT_Get_Char_Index(m_font_face, i[0]);
        Glyph glyph = renderGlyph(i[0], font_size);

        if(prev && kern && i) {
            FT_Vector delta;
            FT_Get_Kerning(m_font_face, prev, index, FT_KERNING_DEFAULT, &delta);
            pen.x += delta.x * scene->getDPU();
            //fprintf(stderr, "%ld\n", delta.x);
        }

        if(i[0] == '\n') {
            pen.x = 0;
            pen.y += font_size;
            prev = 0;
            continue;
        } else if(i[0] == ' ' || glyph.id == 0) {
            pen.x += font_size;
            prev = 0;
            continue;
        }

        glUniform3f(m_color_uniform, color.x, color.y, color.z);
        glm::vec3 offset(glyph.bearing.x, -glyph.bearing.y, 0.0f);

        glm::mat4 mvp = scene->getActiveProjectionMatrix() *
                        scene->getActiveViewMatrix() *
                        transform *
                        glm::translate(glm::mat4(1), -(pen + offset) * scene->getDPU()) *
                        glm::scale(glm::mat4(1), glm::vec3(glyph.dimensions.x * scene->getDPU(), glyph.dimensions.y * scene->getDPU(), 1.0f));
        //fprintf(stderr, "Result: %f, %f, %f, %f\n", glyph.dimensions.x, glyph.dimensions.y, glyph.dimensions.x * scene->getDPU(), glyph.dimensions.y * scene->getDPU());
        glUniformMatrix4fv(m_transform_uniform, 1, GL_FALSE, &mvp[0][0]);
        glEnableVertexAttribArray(m_vertex_position);
        glBindBuffer(GL_ARRAY_BUFFER, QUAD_BUFFER);
        glVertexAttribPointer(m_vertex_position, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);

        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, glyph.texture);
        glUniform1i(m_texture_uniform, 0);
        checkGLError();

        glDrawArrays(GL_TRIANGLES, 0, 6);
        checkGLError();

        glDisableVertexAttribArray(m_vertex_position);
        pen.x += glyph.advance;
        //fprintf(stderr, "(%d)\n", (int)glyph.advance);
        prev = index;
    }
}
//http://www.freetype.org/freetype2/docs/tutorial/step2.html
FT_Error measure_string(FT_Face face, std::string text, int size, Vector2i* size_out)
{
   int pos_x = 0;
   bool use_kerning = FT_HAS_KERNING(face) ? true : false;
   FT_UInt prev_glyph_index = 0;

   FT_BBox text_bb;
   text_bb.xMax = 0;
   text_bb.xMin = 0;
   text_bb.yMax = 0;
   text_bb.yMin = 0;
   FT_Error error;

   error = FT_Set_Char_Size(face, 0, size * 64, 72, 72);

   for(unsigned int i = 0; i < text.length(); i++)
   {
      FT_UInt glyph_index = FT_Get_Char_Index(face, text.c_str()[i]);

      if(use_kerning && prev_glyph_index)
      {
         FT_Vector delta;
         FT_Get_Kerning(face, prev_glyph_index, glyph_index, FT_KERNING_DEFAULT, &delta);
         pos_x += delta.x >> 6;
      }
      prev_glyph_index = glyph_index;

      if(error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT) != FT_Err_Ok)
      {
         Log::Error(__FILE__, "Unable to load glyph %d", glyph_index);
         return error;
      }

      FT_Glyph glyph;
      if(error = FT_Get_Glyph(face->glyph, &glyph) != FT_Err_Ok)
      {
         Log::Error(__FILE__, "Unable to get glyph %d", glyph_index);
      }

      FT_BBox bb;
      FT_Glyph_Get_CBox(glyph, ft_glyph_bbox_pixels, &bb);
      bb.xMax += pos_x;
      bb.xMin += pos_x;


      pos_x += glyph->advance.x >> 16;

      //Grow overall bounding box
      if(bb.xMax > text_bb.xMax)
         text_bb.xMax = bb.xMax;
      if(bb.yMax > text_bb.yMax)
         text_bb.yMax = bb.yMax;
      if(bb.xMin < text_bb.xMin)
         text_bb.xMin = bb.xMin;
      if(bb.yMin < text_bb.yMin)
         text_bb.yMin = bb.yMin;

      FT_Done_Glyph(glyph);
   }
Пример #14
0
static cairo_status_t
glyph_array_add_text(glyph_array_t *glyphs, cairo_t *cr, const char *s, double spacing)
{
    cairo_scaled_font_t *scaled_font;
    cairo_status_t status;
    FT_Face face;
    unsigned long charcode;
    unsigned int index;
    cairo_text_extents_t extents;
    const char *p;
    FT_Vector kerning;
    double kern_x;
    int first = TRUE;

    scaled_font = cairo_get_scaled_font (cr);
    status = cairo_scaled_font_status (scaled_font);
    if (status)
	return status;

    face = cairo_ft_scaled_font_lock_face (scaled_font);
    if (face == NULL)
	return CAIRO_STATUS_FONT_TYPE_MISMATCH;

    p = s;
    while (*p)
    {
        charcode = *p;
        index = FT_Get_Char_Index (face, charcode);
        glyphs->glyph_list[glyphs->num_glyphs].index = index;
        if (first) {
            first = FALSE;
            glyphs->glyph_list[glyphs->num_glyphs].x = glyphs->x;
            glyphs->glyph_list[glyphs->num_glyphs].y = glyphs->y;
        } else {
            cairo_glyph_extents (cr, &glyphs->glyph_list[glyphs->num_glyphs - 1], 1, &extents);
            FT_Get_Kerning (face,
                            glyphs->glyph_list[glyphs->num_glyphs - 1].index,
                            glyphs->glyph_list[glyphs->num_glyphs].index,
                            FT_KERNING_UNSCALED,
                            &kerning);
            kern_x = DOUBLE_FROM_26_6(kerning.x);
            glyphs->glyph_list[glyphs->num_glyphs].x =
		glyphs->glyph_list[glyphs->num_glyphs - 1].x + extents.x_advance + kern_x + spacing;
            glyphs->glyph_list[glyphs->num_glyphs].y =
		glyphs->glyph_list[glyphs->num_glyphs - 1].y + extents.y_advance;
	}

	cairo_glyph_extents (cr, &glyphs->glyph_list[glyphs->num_glyphs], 1, &extents);
	glyphs->x = glyphs->glyph_list[glyphs->num_glyphs].x + extents.x_advance + spacing;
	glyphs->y = glyphs->glyph_list[glyphs->num_glyphs].y + extents.y_advance;
	p++;
        glyphs->num_glyphs++;
    }

    cairo_ft_scaled_font_unlock_face (scaled_font);
    return CAIRO_STATUS_SUCCESS;
}
Пример #15
0
GLvec2 Font::kerning(char prev, char code) const {
    // Returns kerning in units normalized by font size
    FT_Vector delta;
    FT_Face face = (FT_Face)face_;
    FT_UInt prevIndex = FT_Get_Char_Index(face, prev);
    FT_UInt curIndex = FT_Get_Char_Index(face, code);
    FT_Get_Kerning(face, prevIndex, curIndex, FT_KERNING_DEFAULT, &delta);
    return GLvec2((delta.x >> 6)/(GLfloat)size_, (delta.y >> 6)/(GLfloat)size_);
}
Пример #16
0
//-----------------------------------------------------------
int ofTrueTypeFont::getKerning(uint32_t c, uint32_t prevC) const{
    if(FT_HAS_KERNING( face )){
        FT_Vector kerning;
        FT_Get_Kerning(face.get(), FT_Get_Char_Index(face.get(), c), FT_Get_Char_Index(face.get(), prevC), FT_KERNING_UNFITTED, &kerning);
        return kerning.x * fontUnitScale;
    }else{
        return 0;
    }
}
Пример #17
0
int TextureFont::PickCharacter(const char *str, float mouseX, float mouseY) const
{
	assert(str && mouseX >= 0.0f && mouseY >= 0.0f);

	// at the point of the mouse in-box test, the vars have the following values:
	// i1: the index of the character being tested
	// i2: the index of the next character
	// charBytes: the number of bytes used to encode the next character
	// right: the right edge of the box being tested
	// bottom:  the bottom of the box being tested
	// x: the x-coordinate of the next character
	// chr1: the Unicode value of the character being tested
	// chr2: the Unicode value of the next character

	const float lineSpacing = GetHeight()*PARAGRAPH_SPACING;
	Uint32 chr2 = '\n'; // pretend we've just had a new line
	float bottom = GetHeight() - lineSpacing, x = 0.0f;
	int i2 = 0, charBytes = 0;
	do {
		int i1 = i2;
		Uint32 chr1 = chr2;

		// read the next character
		i2 += charBytes;
		charBytes = conv_mb_to_wc(&chr2, &str[i2]);
		assert(!str[i2] || charBytes); // assert valid encoding

		float right;
		if (chr1 == '\n') {
			right = std::numeric_limits<float>::max();
			x = 0.0f;
		} else {
			std::map<Uint32,glfglyph_t>::const_iterator it = m_glyphs.find(chr1);
			assert(it != m_glyphs.end());
			float advance = it->second.advx;

			if (chr2 != '\n' && chr2 != '\0') {
				FT_UInt a = FT_Get_Char_Index(m_face, chr1);
				FT_UInt b = FT_Get_Char_Index(m_face, chr2);
				FT_Vector kern;
				FT_Get_Kerning(m_face, a, b, FT_KERNING_UNFITTED, &kern);
				advance += float(kern.x) / 64.0f;
			}

			right = x + (advance / 2.0f);
			x += advance;
		}

		if ((mouseY < bottom) && (mouseX < right))
			return i1;

		if (chr1 == '\n')
			bottom += lineSpacing;
	} while (charBytes);

	return i2;
}
Пример #18
0
bool getKerning(double &output, FontHandle *font, int unicode1, int unicode2) {
    FT_Vector kerning;
    if (FT_Get_Kerning(font->face, FT_Get_Char_Index(font->face, unicode1), FT_Get_Char_Index(font->face, unicode2), FT_KERNING_UNSCALED, &kerning)) {
        output = 0;
        return false;
    }
    output = kerning.x/64.;
    return true;
}
Пример #19
0
void
XeTeXFontInst_FT2::getKernPair(LEGlyphID leftGlyph, LEGlyphID rightGlyph, LEPoint &kern) const
{
	FT_Vector	kerning;
	if (FT_Get_Kerning(face, leftGlyph, rightGlyph, FT_KERNING_UNSCALED, &kerning) == 0) {
		kern.fX = kerning.x;
		kern.fY = kerning.y;
	}
	else
		kern.fX = kern.fY = 0;
}
Пример #20
0
double
font::kerning( char32_t c1, char32_t c2 )
{
	FT_Vector kerning;
	FT_UInt prev_index = FT_Get_Char_Index( _face, c1 );
	FT_UInt next_index = FT_Get_Char_Index( _face, c2 );

	FT_Get_Kerning( _face, prev_index, next_index, FT_KERNING_UNFITTED, &kerning );

	return kerning.x / ( 64.0 * 64.0 );
}
Пример #21
0
static void draw_chars(VGFT_FONT_T *font, const char *text, int char_count, VGbitfield paint_modes, int peek) {
   // Put in first character
   glyph_indices[0] = FT_Get_Char_Index(font->ft_face, text[0]);
   int prev_glyph_index = glyph_indices[0];

   // Calculate glyph_indices and adjustments
   FT_Vector kern;
   int i;
   for (i = 1; i != char_count; ++i) {
      int glyph_index = FT_Get_Char_Index(font->ft_face, text[i]);
      if (!glyph_index) return;
      glyph_indices[i] = glyph_index;

      if (FT_Get_Kerning(font->ft_face, prev_glyph_index, glyph_index,
                         FT_KERNING_DEFAULT, &kern)) {
        assert(0);
      }
      adjustments_x[i - 1] = float_from_26_6(kern.x);
      adjustments_y[i - 1] = float_from_26_6(kern.y);

      prev_glyph_index = glyph_index;
   }

   // Get the last adjustment?
   if (peek) {
      int peek_glyph_index = FT_Get_Char_Index(font->ft_face, text[i]);
      if (!peek_glyph_index) return;
      if (FT_Get_Kerning(font->ft_face, prev_glyph_index, peek_glyph_index,
                         FT_KERNING_DEFAULT, &kern)) {
        assert(0);
      }
      adjustments_x[char_count - 1] = float_from_26_6(kern.x);
      adjustments_y[char_count - 1] = float_from_26_6(kern.y);
   } else {
      adjustments_x[char_count - 1] = 0.0f;
      adjustments_y[char_count - 1] = 0.0f;
   }

   vgDrawGlyphs(font->vg_font, char_count, glyph_indices,
                adjustments_x, adjustments_y, paint_modes, VG_FALSE);
}
JNIEXPORT jint JNICALL Java_com_badlogic_gdx_graphics_g2d_freetype_FreeType_getKerning(JNIEnv* env, jclass clazz, jlong face, jint leftGlyph, jint rightGlyph, jint kernMode) {


//@line:664

   	FT_Vector kerning;
   	FT_Error error = FT_Get_Kerning((FT_Face)face, leftGlyph, rightGlyph, kernMode, &kerning);
   	if(error) return 0;
   	return kerning.x;
   

}
Пример #23
0
int TextureFont::PickCharacter(const char *str, float mouseX, float mouseY) const
{
	assert(str && mouseX >= 0.0f && mouseY >= 0.0f);

	// at the point of the mouse in-box test, the vars have the following values:
	// i1: the index of the character being tested
	// i2: the index of the next character
	// charBytes: the number of bytes used to encode the next character
	// right: the right edge of the box being tested
	// bottom:  the bottom of the box being tested
	// x: the x-coordinate of the next character
	// chr1: the Unicode value of the character being tested
	// chr2: the Unicode value of the next character

	Uint32 chr2 = '\n'; // pretend we've just had a new line
	float bottom = 0.0f, x = 0.0f;
	int i2 = 0, charBytes = 0;
	do {
		int i1 = i2;
		Uint32 chr1 = chr2;

		// read the next character
		i2 += charBytes;
		charBytes = utf8_decode_char(&chr2, &str[i2]);
		assert(!str[i2] || charBytes); // assert valid encoding

		float right;
		if (chr1 == '\n') {
			right = std::numeric_limits<float>::max();
			x = 0.0f;
		} else {
			const glfglyph_t &glyph = GetGlyph(chr1);
			float advance = glyph.advx;

			if (chr2 != '\n' && chr2 != '\0') {
				FT_Vector kern;
				FT_Get_Kerning(m_face, glyph.ftIndex, GetGlyph(chr2).ftIndex, FT_KERNING_UNFITTED, &kern);
				advance += float(kern.x) / 64.0f;
			}

			right = x + (advance / 2.0f);
			x += advance;
		}

		if ((mouseY < bottom) && (mouseX < right))
			return i1;

		if (chr1 == '\n')
			bottom += GetHeight();
	} while (charBytes);

	return i2;
}
Пример #24
0
/**
 * @internal
 * Calculate the kerning between "left" and "right.
 *
 * @param fi the font instance to use
 * @param left the left glyph index
 * @param right the right glyph index
 * @param[out] kerning the kerning calculated.
 * @return FALSE on error, TRUE on success.
 */
EAPI int
evas_common_font_query_kerning(RGBA_Font_Int *fi, FT_UInt left, FT_UInt right,
			       int *kerning)
{
   int *result;
   FT_Vector delta;
   int key[2];
   int error = 1;

   key[0] = left;
   key[1] = right;

   result = eina_hash_find(fi->kerning, key);
   if (result)
     {
	*kerning = result[2];
	goto on_correct;
     }

   /* NOTE: ft2 seems to have a bug. and sometimes returns bizarre
    * values to kern by - given same font, same size and same
    * prev_index and index. auto/bytecode or none hinting doesn't
    * matter */
   evas_common_font_int_reload(fi);
   FTLOCK();
   if (FT_Get_Kerning(fi->src->ft.face,
		      key[0], key[1],
		      FT_KERNING_DEFAULT, &delta) == 0)
     {
	int *push;

        FTUNLOCK();
	*kerning = delta.x;

	push = malloc(sizeof (int) * 3);
	if (!push) return 1;

	push[0] = key[0];
	push[1] = key[1];
	push[2] = *kerning;

	eina_hash_direct_add(fi->kerning, push, push);

	goto on_correct;
     }

        FTUNLOCK();
   error = 0;

 on_correct:
   return error;
}
void gfx_font_adapter::add_kerning(unsigned int first, unsigned int second, scalar* x, scalar* y)
{
    if (m_impl->font && first && second && FT_HAS_KERNING(m_impl->font)) {
        FT_Vector delta;
        FT_Get_Kerning(m_impl->font, first, second, FT_KERNING_DEFAULT, &delta);
        scalar dx = int26p6_to_flt(delta.x);
        scalar dy = int26p6_to_flt(delta.y);
        if (m_impl->font->glyph->format != FT_GLYPH_FORMAT_BITMAP)
            m_impl->matrix.transform_2x2(&dx, &dy);
        *x += dx;
        *y += dy;
    }
}
Пример #26
0
static void glyphstring_create(FT_Face face, Text *text, FT_Glyph *glyph_string,
		FT_Vector *pos)
{
	const uint8_t *string = text->string;
	FT_Bool has_kerning;
	FT_UInt glyph_index, previous;
	FT_Vector pen, delta;
	uint32_t charcode;
	int i;

	has_kerning = FT_HAS_KERNING(face);
	previous = 0;
	i = 0;
	pen.x = pen.y = 0;
	while (string[0] != '\0')
	{
		charcode = utf8_next(&string);
		glyph_index = FT_Get_Char_Index(face, charcode);
		if (has_kerning && previous && glyph_index)
			FT_Get_Kerning(face, previous, glyph_index, FT_KERNING_DEFAULT,
					&delta);
		else
			delta.x = 0;

		if (glyph_index == 0)
			log_err("Glyph for character U+%X missing\n", charcode);

		if (FT_Load_Glyph(face, glyph_index, FT_LOAD_RENDER) != 0)
		{
			log_err("Error loading glyph for character U+%X\n", charcode);
			continue;
		}
		if (FT_Get_Glyph(face->glyph, &glyph_string[i]) != 0)
		{
			log_err("Error copying glyph for character U+%X\n", charcode);
			continue;
		}

		pen.x += delta.x;

		pos[i] = pen;

		pen.x += face->glyph->advance.x;
		pen.y += face->glyph->advance.y;

		previous = glyph_index;
		i++;
	}

	text->num_glyphs = i;
}
Пример #27
0
bool Font::drawString(const std::wstring& s, float x, float y)
{
    bool Ret = true;
    float penX = x, penY = y;
    uint32_t previousGlyph = 0;
    FT_Vector Delta;
    CacheEntry* theGlyph = NULL;
    std::size_t Length = s.length();

    for (std::size_t i = 0; i < Length; ++i)
    {
        if (mAutoCache)
            cacheChar(s[i]);

        //Special cases
        switch (s[i])
        {
        case L'\t':
            penX += spaceAdvance() * TabSize;
            previousGlyph = 0;
            continue;
        case L'\v':
            penY += mHeight * TabSize;
            previousGlyph = 0;
            continue;
        case L'\n':
            penY += mHeight;
            penX = x;
            previousGlyph = 0;
            continue;
        }
        theGlyph = getCacheEntry(s[i]);
        if (theGlyph == NULL)
        {
            Ret = false;
            previousGlyph = 0;
            continue;
        }
        //Kerning
        if (previousGlyph != 0 && mHaveKerning && mUseKerning)
        {
            FT_Get_Kerning(mFace, previousGlyph, theGlyph->glyphIndex, FT_KERNING_DEFAULT, &Delta);
            penX += Delta.x >> 6;
            penY += Delta.y >> 6;
        }
        if (!drawChar(s[i], penX, penY))
            Ret = false;

        penX += theGlyph->Advance;
        previousGlyph = theGlyph->glyphIndex;
    }
Пример #28
0
// ------------------------------------------ texture_font_generate_kerning ---
void
texture_font_generate_kerning( texture_font_t *self )
{
    size_t i, j;
    FT_Library library;
    FT_Face face;
    FT_UInt glyph_index, prev_index;
    texture_glyph_t *glyph, *prev_glyph;
    FT_Vector kerning;
    
    assert( self );

    /* Load font */
//    if( !texture_font_load_face( &library, self->filename, self->size, &face ) )
//    {
//        return;
//    }
    if( !texture_font_load_face( self, &library, self->size, &face ) )// <----- changed
    {
        return;
    }

    /* For each glyph couple combination, check if kerning is necessary */
    /* Starts at index 1 since 0 is for the special backgroudn glyph */
    for( i=1; i<self->glyphs->size; ++i )
    {
        glyph = *(texture_glyph_t **) vector_get( self->glyphs, i );
        glyph_index = FT_Get_Char_Index( face, glyph->charcode );
        vector_clear( glyph->kerning );

        for( j=1; j<self->glyphs->size; ++j )
        {
            prev_glyph = *(texture_glyph_t **) vector_get( self->glyphs, j );
            prev_index = FT_Get_Char_Index( face, prev_glyph->charcode );
            FT_Get_Kerning( face, prev_index, glyph_index, FT_KERNING_UNFITTED, &kerning );
            // printf("%c(%d)-%c(%d): %ld\n",
            //       prev_glyph->charcode, prev_glyph->charcode,
            //       glyph_index, glyph_index, kerning.x);
            if( kerning.x )
            {
                // 64 * 64 because of 26.6 encoding AND the transform matrix used
                // in texture_font_load_face (hres = 64)
                kerning_t k = {prev_glyph->charcode, kerning.x / (float)(64.0f*64.0f)};
                vector_push_back( glyph->kerning, &k );
            }
        }
    }
    FT_Done_Face( face );
    FT_Done_FreeType( library );
}
Пример #29
0
void 
FT2Font::load_glyphs() {
  _VERBOSE("FT2Font::load_glyphs");
  
  /* a small shortcut */ 
  
  FT_Bool use_kerning = FT_HAS_KERNING( face ); 
  FT_UInt previous = 0; 
  
  glyphs.resize(0);
  pen.x = 0;
  pen.y = 0;
  
  for ( unsigned int n = 0; n < text.size(); n++ ) { 
    FT_UInt glyph_index = FT_Get_Char_Index( face, text[n] );
    /* retrieve kerning distance and move pen position */ 
    if ( use_kerning && previous && glyph_index ) { 
      FT_Vector delta;
      FT_Get_Kerning( face, previous, glyph_index,
		      ft_kerning_default, &delta );
      pen.x += delta.x;
    }
    error = FT_Load_Glyph( face, glyph_index, FT_LOAD_DEFAULT ); 
    if ( error ) {
      std::cerr << "\tcould not load glyph for " << text[n] << std::endl;
      continue; 
    }
    /* ignore errors, jump to next glyph */ 
    
    /* extract glyph image and store it in our table */

    FT_Glyph thisGlyph; 
    error = FT_Get_Glyph( face->glyph, &thisGlyph ); 

    if ( error ) {
      std::cerr << "\tcould not get glyph for " << text[n] << std::endl;
      continue; 
    }
    /* ignore errors, jump to next glyph */ 

    FT_Glyph_Transform( thisGlyph, 0, &pen);
    pen.x += face->glyph->advance.x;
    
    previous = glyph_index; 
    glyphs.push_back(thisGlyph);
  }
  // now apply the rotation
  for (unsigned int n=0; n<glyphs.size(); n++) 
    FT_Glyph_Transform(glyphs[n], &matrix, 0);
}
Пример #30
0
int TTFFont::getKerningOffset(byte left, byte right) const {
	if (!_hasKerning)
		return 0;

	FT_UInt leftGlyph = _glyphSlots[left];
	FT_UInt rightGlyph = _glyphSlots[right];

	if (!leftGlyph || !rightGlyph)
		return 0;

	FT_Vector kerningVector;
	FT_Get_Kerning(_face, leftGlyph, rightGlyph, FT_KERNING_DEFAULT, &kerningVector);
	return (kerningVector.x / 64);
}