/* ft.c */ /************************************************************************ Part of the dvipng distribution This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . Copyright (C) 2002-2009 Jan-Åke Larsson ************************************************************************/ #include "dvipng.h" void LoadFT(int32_t c, struct char_entry * ptr) { FT_Bitmap bitmap; FT_UInt glyph_i; int i,j,k; unsigned char* bit; static bool hintwarning=false; DEBUG_PRINT(DEBUG_FT,("\n LOAD FT CHAR\t%d (%d)",c,ptr->tfmw)); if (currentfont->psfontmap!=NULL && currentfont->psfontmap->encoding != NULL) { DEBUG_PRINT(DEBUG_FT,(" %s",currentfont->psfontmap->encoding->charname[c])); glyph_i = FT_Get_Name_Index(currentfont->face, currentfont->psfontmap->encoding->charname[c]); } else if (currentfont->psfontmap!=NULL && currentfont->psfontmap->subfont != NULL) { glyph_i = FT_Get_Char_Index( currentfont->face, currentfont->psfontmap->subfont->charindex[c] ); DEBUG_PRINT(DEBUG_FT,(" 0x%X",currentfont->psfontmap->subfont->charindex[c])); } else glyph_i = FT_Get_Char_Index( currentfont->face, c ); if (FT_Load_Glyph( currentfont->face, glyph_i, FT_LOAD_RENDER | FT_LOAD_TARGET_LIGHT )) { /* On some configurations (with FreeType <= 2.1.7) the above fails, while the below works */ if (!hintwarning) { hintwarning=true; Warning("the used FreeType does not have target_light hinting"); } if (FT_Load_Glyph( currentfont->face, glyph_i, FT_LOAD_RENDER | FT_LOAD_NO_HINTING )) Fatal("cannot load FT char %d",c); } ptr->xOffset = -currentfont->face->glyph->bitmap_left*shrinkfactor; ptr->yOffset = (currentfont->face->glyph->bitmap_top-1)*shrinkfactor; bitmap=currentfont->face->glyph->bitmap; DEBUG_PRINT(DEBUG_FT,(" (%dx%d)",bitmap.width,bitmap.rows)); if ((ptr->data = calloc(bitmap.width*bitmap.rows,sizeof(char))) == NULL) Fatal("unable to malloc image space for char %c", (char)c); ptr->w = bitmap.width; ptr->h = bitmap.rows; #define GREYLEVELS 16 DEBUG_PRINT(DEBUG_GLYPH,("\nDRAW GLYPH %d\n", (int)c)); bit=ptr->data; for(i=0;i0 ? k*16-1 : 0; */ DEBUG_PRINT(DEBUG_GLYPH,("%3u ",k)); bit[i*bitmap.width+j]=k; } DEBUG_PRINT(DEBUG_GLYPH,("|\n")); } } bool InitFT(struct font_entry * tfontp) { int error; if (libfreetype==NULL) { if (FT_Init_FreeType( &libfreetype )) { Warning("an error occured during freetype initialisation, disabling it"); option_flags &= ~USE_FREETYPE; return(false); } # ifdef DEBUG else { FT_Int amajor, aminor, apatch; DEBUG_PRINT(DEBUG_FT,("\n COMPILED WITH FREETYPE %d.%d.%d", FREETYPE_MAJOR, FREETYPE_MINOR, FREETYPE_PATCH)); # ifdef HAVE_FT_LIBRARY_VERSION FT_Library_Version( libfreetype, &amajor, &aminor, &apatch ); DEBUG_PRINT(DEBUG_FT,("\n USING LIBFT %d.%d.%d", amajor, aminor, apatch)); # endif } # endif } DEBUG_PRINT((DEBUG_DVI|DEBUG_FT),("\n OPEN FT FONT:\t'%s'", tfontp->name)); error = FT_New_Face( libfreetype, tfontp->name, 0, &tfontp->face ); if (error == FT_Err_Unknown_File_Format) { Warning("font file %s has unknown format", tfontp->name); return(false); } else if (error) { Warning("font file %s could not be opened", tfontp->name); return(false); } Message(BE_VERBOSE,"<%s>", tfontp->name); if (tfontp->psfontmap != NULL && tfontp->psfontmap->subfont != NULL) error=FT_Select_Charmap(tfontp->face, tfontp->psfontmap->subfont->encoding); else if (tfontp->psfontmap == NULL || tfontp->psfontmap->encoding == NULL) #ifndef FT_ENCODING_ADOBE_CUSTOM # define FT_ENCODING_ADOBE_CUSTOM ft_encoding_adobe_custom # define FT_ENCODING_ADOBE_STANDARD ft_encoding_adobe_standard #endif error=FT_Select_Charmap(tfontp->face, FT_ENCODING_ADOBE_CUSTOM); if (error) { Warning("unable to set font encoding for %s", tfontp->name); if(FT_Select_Charmap( tfontp->face, FT_ENCODING_ADOBE_STANDARD )) { Warning("unable to set fallback font encoding for %s", tfontp->name); return(false); } } if (FT_Set_Char_Size( tfontp->face, /* handle to face object */ 0, /* char_width in 1/64th of points */ ((int64_t)tfontp->d*64*7200)/7227/65536, /* char_height in 1/64th of _big_points, not TeX points */ tfontp->dpi/shrinkfactor, /* horizontal resolution */ tfontp->dpi/shrinkfactor )) /* vertical resolution */ { Warning("unable to set font size for %s", tfontp->name); return(false); } if (tfontp->psfontmap!=NULL) FT_Set_Transform(tfontp->face, tfontp->psfontmap->ft_transformp, NULL); tfontp->type = FONT_TYPE_FT; return(true); } static void UnLoadFT(struct char_entry *ptr) { if (ptr->data!=NULL) free(ptr->data); ptr->data=NULL; } void DoneFT(struct font_entry *tfontp) { int c=0; int error = FT_Done_Face( tfontp->face ); if (error) Warning("font file %s could not be closed", tfontp->name); while(cchr[c]!=NULL) { UnLoadFT((struct char_entry*)tfontp->chr[c]); free(tfontp->chr[c]); tfontp->chr[c]=NULL; } c++; } if (tfontp->name!=NULL) free(tfontp->name); tfontp->name=NULL; }