Esempio n. 1
0
static FT_Outline* getFTOutline(JNIEnv* env, jobject font2D,
        FTScalerContext *context, FTScalerInfo* scalerInfo,
        jint glyphCode, jfloat xpos, jfloat ypos) {
    int renderFlags;
    int glyph_index;
    FT_Error error;
    FT_GlyphSlot ftglyph;

    if (glyphCode >= INVISIBLE_GLYPHS ||
            isNullScalerContext(context) || scalerInfo == NULL) {
        return NULL;
    }

    error = setupFTContext(env, font2D, scalerInfo, context);
    if (error) {
        return NULL;
    }

    renderFlags = FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP;

    glyph_index = FT_Get_Char_Index(scalerInfo->face, glyphCode);

    error = FT_Load_Glyph(scalerInfo->face, glyphCode, renderFlags);
    if (error) {
        return NULL;
    }

    ftglyph = scalerInfo->face->glyph;

    /* apply styles */
    if (context->doBold) { /* if bold style */
        FT_GlyphSlot_Embolden(ftglyph);
    }
    if (context->doItalize) { /* if oblique */
        FT_GlyphSlot_Oblique(ftglyph);
    }

    FT_Outline_Translate(&ftglyph->outline,
                         FloatToF26Dot6(xpos),
                         -FloatToF26Dot6(ypos));

    return &ftglyph->outline;
}
Esempio n. 2
0
static void freetype2_drawtext(PFont pfont, image_p pimage, int x, int y,
							   const void *text, int cc, int flags)
{
	PFontFreetype pf = (PFontFreetype) pfont;
	uint16_t* value;
	FT_Glyph glyph;
	int pen_x = x;
	int pen_y = y + pf->size;
	int i;
	FT_BitmapGlyph bitmap_glyph;
	FT_Bitmap* bitmap;

	value = _nge_ft_conv_encoding(pfont, text, &cc);
	if (cc <= 0)
		return;

	if(pimage->swizzle ==1){
		unswizzle_swap(pimage);
		pimage->dontswizzle = 1;
	}
	pimage->modified =1;
	for (i =0;i<cc;i++) {
		FT_Load_Glyph( pf->face, FT_Get_Char_Index( pf->face, value[i] ), FT_LOAD_DEFAULT );
		if(pf->flags & FLAGS_FREETYPE_BOLD)
			FT_GlyphSlot_Embolden(pf->face->glyph);
		if(pf->flags & FLAGS_FREETYPE_ITALICS)
			FT_GlyphSlot_Oblique(pf->face->glyph);
		FT_Get_Glyph( pf->face->glyph, &glyph );
		FT_Render_Glyph( pf->face->glyph, ft_render_mode_normal );
		FT_Glyph_To_Bitmap( &glyph, ft_render_mode_normal, 0, 1 );
		bitmap_glyph = (FT_BitmapGlyph)glyph;
		bitmap=&bitmap_glyph->bitmap;
		draw_one_word(pf,bitmap,pimage,pen_x + pf->face->glyph->bitmap_left,pen_y - pf->face->glyph->bitmap_top );
		pen_x  +=(pf->face->glyph->advance.x+pf->fix_width*72) >> 6  ;
		FT_Done_Glyph( glyph );
	}
}
Esempio n. 3
0
int kGUIFace::LoadFont(const char *filename,bool bold)
{
	int size,glyph_index;
	int advance;
	unsigned int c;
	unsigned long fontfilesize;

	m_haskerning=false;
	m_bold=bold;
	/* handle bigfile based fonts */
	m_memfile=kGUI::LoadFile(filename,&fontfilesize);
	assert(m_memfile!=0,"Couldn't find font!");

#if defined(WIN32) || defined(MINGW)
	//windows only, this is so that when printing, reports can use these fonts too!
	AddFontMemResourceEx(m_memfile, fontfilesize,0,&kGUIFont::m_numreg);
#elif defined(LINUX) || defined(MACINTOSH)
#else
#error
#endif

	if(FT_New_Memory_Face( kGUIFont::GetLibrary(),
							m_memfile,	/* first byte in memory */
							fontfilesize,	/* size in bytes */
							0,				/* face_index */
							GetFacePtr() ))
		return(-1);

	/* make a name for this font */
	if(!strcmp(m_ftface->style_name, "Regular"))
		m_name.Sprintf("%s", m_ftface->family_name);
    else
        m_name.Sprintf("%s %s",m_ftface->family_name, m_ftface->style_name);

	/* calculate pixel heights for different sizes of this font */
	for(size=1;size<=MAXFONTSIZE;++size)
	{
		kGUI::SelectFont(this,size);
		m_pixabove[size]=-1;
		m_pixbelow[size]=-1;

		/* pre-calculate character widths */
		if(size<=MAXQUICKSIZE)
		{
			for(c=0;c<MAXCCACHE;++c)
			{
				advance=0;
				glyph_index = FT_Get_Char_Index( m_ftface, c );
				if(glyph_index>0)
				{
					if(FT_Load_Glyph(m_ftface, glyph_index, FT_LOAD_DEFAULT)==0)
					{
						if(bold)
						{
							if(!FT_Render_Glyph( m_ftface->glyph, ft_render_mode_normal ))
								FT_GlyphSlot_Embolden(m_ftface->glyph);
						}
						advance=m_ftface->glyph->advance.x >> 6;
					}
				}
				m_quickwidths[size][c]=advance;
			}
		}
	}
	m_haskerning = FT_HAS_KERNING( m_ftface )!=0; 

	return(0);	/* ok */
}
Esempio n. 4
0
void kGUIText::DrawSection(int sstart,int slen,int sx,int x,int y,int rowheight,kGUIColor color)
{
	kGUIFace *face;
	int glyph_index;
	int font_height,font_above,font_below;
	const kGUICorners *clip;
	FT_Face ftface;
	int size;
	bool cachesize;
	int *cacheptr;
	unsigned int ch;	/* current character */
	unsigned int nb;	/* number of bytes for current character */
	int ry;
	bool isbold;

	size=GetFontSize();
	if(!size)
		return;

	if(size<MAXQUICKSIZE)
		cachesize=true;	
	else
		cachesize=false;

	face=kGUIFont::GetFace(GetFontID());
	isbold=face->GetBold();
	ftface=face->GetFace();
	font_height=face->GetPixHeight(size);
	ry=y+rowheight-font_height;
	font_above = face->GetPixAscHeight(size);
	font_below = face->GetPixDescHeight(size);

	kGUI::SelectFont(face,size);

	clip=kGUI::GetClipCorners();
	if(y>clip->by)
		return;

	while(slen>0)
	{
		/* get character in current string encoding mode */
		ch=GetChar(sstart,&nb);
		if(!ch)
			return;
		sstart+=nb;
		slen-=nb;

		/* is this character in the cache? */
		if( cachesize==true && (ch<MAXCCACHE))
			cacheptr=face->m_quickcache[size][ch];
		else
			cacheptr=0;
		if(cacheptr)
		{
			DrawChar( (char *)(cacheptr+5),
						x + cacheptr[2],
						y+font_above-cacheptr[3],
						cacheptr[0], cacheptr[1],
						color);

			x+=cacheptr[4];
			x+=m_letterspacing;
			if(x>clip->rx)
				return;
		}
		else
		{
			if(ch=='\t')
			{
				int tw;

				tw=GetTabWidth(x-sx);
				if(!tw)
				{
					if( cachesize==true && (' '<MAXCCACHE))
					{
						cacheptr=face->m_quickcache[size][(int)' '];
						tw=cacheptr[4];
					}
					else
						tw=face->GetCharWidth(' ');
				}
				x+=tw;
				x+=m_letterspacing;
				if(x>clip->rx)
					return;
			}
			else
			{
				glyph_index = FT_Get_Char_Index( ftface, ch );
				if(glyph_index>0)
				{
					if(!FT_Load_Glyph(ftface, glyph_index, FT_LOAD_DEFAULT))
					{
						if(!FT_Render_Glyph( ftface->glyph, ft_render_mode_normal ))
						{
							if(isbold)
								FT_GlyphSlot_Embolden(ftface->glyph);

							/* cache this character? */
							if( cachesize==true && (ch<MAXCCACHE))
							{
								int bsize=ftface->glyph->bitmap.width*ftface->glyph->bitmap.rows;

								cacheptr = new int[5+((bsize)/sizeof(int))+1];
								face->m_quickcache[size][ch]=cacheptr;
								cacheptr[0]=ftface->glyph->bitmap.width;
								cacheptr[1]=ftface->glyph->bitmap.rows;
								cacheptr[2]=ftface->glyph->bitmap_left;
								cacheptr[3]=ftface->glyph->bitmap_top;
								cacheptr[4]=ftface->glyph->advance.x >> 6;
								memcpy(cacheptr+5,ftface->glyph->bitmap.buffer,bsize);
							}

							/* draw to screen using writepixel */
							DrawChar( (char *)ftface->glyph->bitmap.buffer,
										x + ftface->glyph->bitmap_left,
										y+font_above-ftface->glyph->bitmap_top,
										ftface->glyph->bitmap.width, ftface->glyph->bitmap.rows,
										color);

							x+=ftface->glyph->advance.x >> 6;
							x+=m_letterspacing;
							if(x>clip->rx)
								return;
						}
					}
				}
			}
		}
	}
Esempio n. 5
0
/*
 * Load the glyphs of a paragraph. When shaping with HarfBuzz the glyph indices
 * have already been determined at this point, as well as the advance values.
 */
static int LoadGlyphs( filter_t *p_filter, paragraph_t *p_paragraph,
                       bool b_use_glyph_indices, bool b_overwrite_advance )
{
    if( p_paragraph->i_size <= 0 || p_paragraph->i_runs_count <= 0 )
    {
        msg_Err( p_filter, "LoadGlyphs() invalid parameters. "
                 "Paragraph size: %d. Runs count %d", p_paragraph->i_size,
                 p_paragraph->i_runs_count );
        return VLC_EGENERIC;
    }

    filter_sys_t *p_sys = p_filter->p_sys;

    for( int i = 0; i < p_paragraph->i_runs_count; ++i )
    {
        run_desc_t *p_run = p_paragraph->p_runs + i;
        text_style_t *p_style = p_run->p_style;

        FT_Face p_face = 0;
        if( !p_run->p_face )
        {
            p_face = LoadFace( p_filter, p_style );
            if( !p_face )
            {
                p_face = p_sys->p_face;
                p_style = &p_sys->style;
                p_run->p_style = p_style;
            }
            p_run->p_face = p_face;
        }
        else
            p_face = p_run->p_face;

        if( p_sys->p_stroker )
        {
            double f_outline_thickness =
                var_InheritInteger( p_filter, "freetype-outline-thickness" ) / 100.0;
            f_outline_thickness = VLC_CLIP( f_outline_thickness, 0.0, 0.5 );
            int i_radius = ( p_style->i_font_size << 6 ) * f_outline_thickness;
            FT_Stroker_Set( p_sys->p_stroker,
                            i_radius,
                            FT_STROKER_LINECAP_ROUND,
                            FT_STROKER_LINEJOIN_ROUND, 0 );
        }

        for( int j = p_run->i_start_offset; j < p_run->i_end_offset; ++j )
        {
            int i_glyph_index;
            if( b_use_glyph_indices )
                i_glyph_index = p_paragraph->pi_glyph_indices[ j ];
            else
                i_glyph_index =
                    FT_Get_Char_Index( p_face, p_paragraph->p_code_points[ j ] );

            glyph_bitmaps_t *p_bitmaps = p_paragraph->p_glyph_bitmaps + j;

            if( FT_Load_Glyph( p_face, i_glyph_index,
                               FT_LOAD_NO_BITMAP | FT_LOAD_DEFAULT )
             && FT_Load_Glyph( p_face, i_glyph_index, FT_LOAD_DEFAULT ) )
            {
                p_bitmaps->p_glyph = 0;
                p_bitmaps->p_outline = 0;
                p_bitmaps->p_shadow = 0;
                p_bitmaps->i_x_advance = 0;
                p_bitmaps->i_y_advance = 0;
                continue;
            }

            if( ( p_style->i_style_flags & STYLE_BOLD )
                  && !( p_face->style_flags & FT_STYLE_FLAG_BOLD ) )
                FT_GlyphSlot_Embolden( p_face->glyph );
            if( ( p_style->i_style_flags & STYLE_ITALIC )
                  && !( p_face->style_flags & FT_STYLE_FLAG_ITALIC ) )
                FT_GlyphSlot_Oblique( p_face->glyph );

            if( FT_Get_Glyph( p_face->glyph, &p_bitmaps->p_glyph ) )
            {
                p_bitmaps->p_glyph = 0;
                p_bitmaps->p_outline = 0;
                p_bitmaps->p_shadow = 0;
                p_bitmaps->i_x_advance = 0;
                p_bitmaps->i_y_advance = 0;
                continue;
            }

            if( p_filter->p_sys->p_stroker )
            {
                p_bitmaps->p_outline = p_bitmaps->p_glyph;
                if( FT_Glyph_StrokeBorder( &p_bitmaps->p_outline,
                                           p_filter->p_sys->p_stroker, 0, 0 ) )
                    p_bitmaps->p_outline = 0;
            }

            if( p_filter->p_sys->style.i_shadow_alpha > 0 )
                p_bitmaps->p_shadow = p_bitmaps->p_outline ?
                                      p_bitmaps->p_outline : p_bitmaps->p_glyph;

            if( b_overwrite_advance )
            {
                p_bitmaps->i_x_advance = p_face->glyph->advance.x;
                p_bitmaps->i_y_advance = p_face->glyph->advance.y;
            }
        }
    }
    return VLC_SUCCESS;
}
Esempio n. 6
0
/*
 * Class:     sun_font_FreetypeFontScaler
 * Method:    getGlyphImageNative
 * Signature: (Lsun/font/Font2D;JI)J
 */
JNIEXPORT jlong JNICALL
Java_sun_font_FreetypeFontScaler_getGlyphImageNative(
        JNIEnv *env, jobject scaler, jobject font2D,
        jlong pScalerContext, jlong pScaler, jint glyphCode) {

    int error, imageSize;
    UInt16 width, height;
    GlyphInfo *glyphInfo;
    int glyph_index;
    int renderFlags = FT_LOAD_RENDER, target;
    FT_GlyphSlot ftglyph;

    FTScalerContext* context =
        (FTScalerContext*) jlong_to_ptr(pScalerContext);
    FTScalerInfo *scalerInfo =
             (FTScalerInfo*) jlong_to_ptr(pScaler);

    if (isNullScalerContext(context) || scalerInfo == NULL) {
        return ptr_to_jlong(getNullGlyphImage());
    }

    error = setupFTContext(env, font2D, scalerInfo, context);
    if (error) {
        invalidateJavaScaler(env, scaler, scalerInfo);
        return ptr_to_jlong(getNullGlyphImage());
    }

    /* if algorithmic styling is required then we do not request bitmap */
    if (context->doBold || context->doItalize) {
        renderFlags =  FT_LOAD_DEFAULT;
    }

    /* NB: in case of non identity transform
     we might also prefer to disable transform before hinting,
     and apply it explicitly after hinting is performed.
     Or we can disable hinting. */

    /* select appropriate hinting mode */
    if (context->aaType == TEXT_AA_OFF) {
        target = FT_LOAD_TARGET_MONO;
    } else if (context->aaType == TEXT_AA_ON) {
        target = FT_LOAD_TARGET_NORMAL;
    } else if (context->aaType == TEXT_AA_LCD_HRGB ||
               context->aaType == TEXT_AA_LCD_HBGR) {
        target = FT_LOAD_TARGET_LCD;
    } else {
        target = FT_LOAD_TARGET_LCD_V;
    }
    renderFlags |= target;

    glyph_index = FT_Get_Char_Index(scalerInfo->face, glyphCode);

    error = FT_Load_Glyph(scalerInfo->face, glyphCode, renderFlags);
    if (error) {
        //do not destroy scaler yet.
        //this can be problem of particular context (e.g. with bad transform)
        return ptr_to_jlong(getNullGlyphImage());
    }

    ftglyph = scalerInfo->face->glyph;

    /* apply styles */
    if (context->doBold) { /* if bold style */
        FT_GlyphSlot_Embolden(ftglyph);
    }
    if (context->doItalize) { /* if oblique */
        FT_GlyphSlot_Oblique(ftglyph);
    }

    /* generate bitmap if it is not done yet
     e.g. if algorithmic styling is performed and style was added to outline */
    if (ftglyph->format == FT_GLYPH_FORMAT_OUTLINE) {
        FT_Render_Glyph(ftglyph, FT_LOAD_TARGET_MODE(target));
    }

    width  = (UInt16) ftglyph->bitmap.width;
    height = (UInt16) ftglyph->bitmap.rows;

    imageSize = width*height;
    glyphInfo = (GlyphInfo*) malloc(sizeof(GlyphInfo) + imageSize);
    if (glyphInfo == NULL) {
        glyphInfo = getNullGlyphImage();
        return ptr_to_jlong(glyphInfo);
    }
    glyphInfo->cellInfo  = NULL;
    glyphInfo->managed   = UNMANAGED_GLYPH;
    glyphInfo->rowBytes  = width;
    glyphInfo->width     = width;
    glyphInfo->height    = height;
    glyphInfo->topLeftX  = (float)  ftglyph->bitmap_left;
    glyphInfo->topLeftY  = (float) -ftglyph->bitmap_top;

    if (ftglyph->bitmap.pixel_mode ==  FT_PIXEL_MODE_LCD) {
        glyphInfo->width = width/3;
    } else if (ftglyph->bitmap.pixel_mode ==  FT_PIXEL_MODE_LCD_V) {
        glyphInfo->height = glyphInfo->height/3;
    }

    if (context->fmType == TEXT_FM_ON) {
        double advh = FTFixedToFloat(ftglyph->linearHoriAdvance);
        glyphInfo->advanceX =
            (float) (advh * FTFixedToFloat(context->transform.xx));
        glyphInfo->advanceY =
            (float) (advh * FTFixedToFloat(context->transform.xy));
    } else {
        if (!ftglyph->advance.y) {
            glyphInfo->advanceX =
                (float) ROUND(FT26Dot6ToFloat(ftglyph->advance.x));
            glyphInfo->advanceY = 0;
        } else if (!ftglyph->advance.x) {
            glyphInfo->advanceX = 0;
            glyphInfo->advanceY =
                (float) ROUND(FT26Dot6ToFloat(-ftglyph->advance.y));
        } else {
            glyphInfo->advanceX = FT26Dot6ToFloat(ftglyph->advance.x);
            glyphInfo->advanceY = FT26Dot6ToFloat(-ftglyph->advance.y);
        }
    }

    if (imageSize == 0) {
        glyphInfo->image = NULL;
    } else {
        glyphInfo->image = (unsigned char*) glyphInfo + sizeof(GlyphInfo);
        //convert result to output format
        //output format is either 3 bytes per pixel (for subpixel modes)
        // or 1 byte per pixel for AA and B&W
        if (ftglyph->bitmap.pixel_mode ==  FT_PIXEL_MODE_MONO) {
            /* convert from 8 pixels per byte to 1 byte per pixel */
            CopyBW2Grey8(ftglyph->bitmap.buffer,
                         ftglyph->bitmap.pitch,
                         (void *) glyphInfo->image,
                         width,
                         width,
                         height);
        } else if (ftglyph->bitmap.pixel_mode ==  FT_PIXEL_MODE_GRAY) {
            /* byte per pixel to byte per pixel => just copy */
            memcpy(glyphInfo->image, ftglyph->bitmap.buffer, imageSize);
        } else if (ftglyph->bitmap.pixel_mode ==  FT_PIXEL_MODE_GRAY4) {
            /* 4 bits per pixel to byte per pixel */
            CopyGrey4ToGrey8(ftglyph->bitmap.buffer,
                             ftglyph->bitmap.pitch,
                             (void *) glyphInfo->image,
                             width,
                             width,
                             height);
        } else if (ftglyph->bitmap.pixel_mode ==  FT_PIXEL_MODE_LCD) {
            /* 3 bytes per pixel to 3 bytes per pixel */
            CopyFTSubpixelToSubpixel(ftglyph->bitmap.buffer,
                                     ftglyph->bitmap.pitch,
                                     (void *) glyphInfo->image,
                                     width,
                                     width,
                                     height);
        } else if (ftglyph->bitmap.pixel_mode ==  FT_PIXEL_MODE_LCD_V) {
            /* 3 bytes per pixel to 3 bytes per pixel */
            CopyFTSubpixelVToSubpixel(ftglyph->bitmap.buffer,
                                      ftglyph->bitmap.pitch,
                                      (void *) glyphInfo->image,
                                      width*3,
                                      width,
                                      height);
            glyphInfo->rowBytes *=3;
        } else {
            free(glyphInfo);
            glyphInfo = getNullGlyphImage();
        }
    }

    return ptr_to_jlong(glyphInfo);
}
Esempio n. 7
0
static int _draw_string(FT_Face face, const uint8_t *string, int length,
                        TEXTST_BITMAP *bmp, int x, int y,
                        BD_TEXTST_REGION_STYLE *style,
                        int *baseline_pos)
{
    uint8_t  color = style->font_color;
    unsigned char_code;
    int      ii, jj, kk;
    unsigned flags;

    if (length <= 0) {
        return -1;
    }
    if (!bmp) {
        flags = FT_LOAD_DEFAULT;
    } else {
        flags = FT_LOAD_RENDER;
    }

    for (ii = 0; ii < length; ii++) {
        /*if (p->char_code == BLURAY_TEXT_CHAR_CODE_UTF8) {*/
            int char_size = _utf8_char_size(string + ii);
            char_code = _utf8_char_get(string + ii, char_size);
            ii += char_size - 1;
        /*}*/

        if (FT_Load_Char(face, char_code, flags /*| FT_LOAD_MONOCHROME*/) == 0) {

            if (style->font_style.bold && !(face->style_flags & FT_STYLE_FLAG_BOLD)) {
                FT_GlyphSlot_Embolden( face->glyph );
            }
            if (style->font_style.italic && !(face->style_flags & FT_STYLE_FLAG_ITALIC)) {
                FT_GlyphSlot_Oblique( face->glyph );
            }

            if (bmp) {
                for (jj = 0; jj < face->glyph->bitmap.rows; jj++) {
                    for (kk = 0; kk < face->glyph->bitmap.width; kk++) {
                        uint8_t pixel = face->glyph->bitmap.buffer[jj * face->glyph->bitmap.pitch + kk];
                        if (pixel & 0x80) {
                            int xpos = x + face->glyph->bitmap_left + kk;
                            int ypos = y - face->glyph->bitmap_top + jj;
                            if (xpos >= 0 && xpos < bmp->width && ypos >= 0 && ypos < bmp->height) {
                                bmp->mem[xpos + ypos * bmp->stride] = color;
                            }
                        }
                    }
                }
            }

            /* track max baseline when calculating line size */
            if (baseline_pos) {
                *baseline_pos = BD_MAX(*baseline_pos, (face->size->metrics.ascender >> 6) + 1);
            }

            x += face->glyph->metrics.horiAdvance >> 6;
        }
    }

    return x;
}