summaryrefslogtreecommitdiff
path: root/dviware/dvipng/ft.c
diff options
context:
space:
mode:
Diffstat (limited to 'dviware/dvipng/ft.c')
-rw-r--r--dviware/dvipng/ft.c179
1 files changed, 179 insertions, 0 deletions
diff --git a/dviware/dvipng/ft.c b/dviware/dvipng/ft.c
new file mode 100644
index 0000000000..9609b10a10
--- /dev/null
+++ b/dviware/dvipng/ft.c
@@ -0,0 +1,179 @@
+/* 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
+ <http://www.gnu.org/licenses/>.
+
+ 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;i<bitmap.rows;i++) {
+ for(j=0;j<bitmap.width;j++) {
+ k=bitmap.buffer[i*bitmap.pitch+j]/(256/GREYLEVELS)*17;
+ /* k=(bitmap.buffer[i*bitmap.pitch+j]+1)/16; */
+ /* k= k>0 ? 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(c<NFNTCHARS) {
+ if (tfontp->chr[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;
+}
+
+