int main(int argc, char *argv[]) {
	int                i, j, err, size, first=' ', last='~',
	                   bitmapOffset = 0, x, y, byte;
	char              *fontName, c, *ptr;
	FT_Library         library;
	FT_Face            face;
	FT_Glyph           glyph;
	FT_Bitmap         *bitmap;
	FT_BitmapGlyphRec *g;
	GFXglyph          *table;
	uint8_t            bit;

	// Parse command line.  Valid syntaxes are:
	//   fontconvert [filename] [size]
	//   fontconvert [filename] [size] [last char]
	//   fontconvert [filename] [size] [first char] [last char]
	// Unless overridden, default first and last chars are
	// ' ' (space) and '~', respectively

	if(argc < 3) {
		fprintf(stderr, "Usage: %s fontfile size [first] [last]\n",
		  argv[0]);
		return 1;
	}

	size = atoi(argv[2]);

	if(argc == 4) {
		last  = atoi(argv[3]);
	} else if(argc == 5) {
		first = atoi(argv[3]);
		last  = atoi(argv[4]);
	}

	if(last < first) {
		i     = first;
		first = last;
		last  = i;
	}

	ptr = strrchr(argv[1], '/'); // Find last slash in filename
	if(ptr) ptr++;         // First character of filename (path stripped)
	else    ptr = argv[1]; // No path; font in local dir.

	// Allocate space for font name and glyph table
	if((!(fontName = malloc(strlen(ptr) + 20))) ||
	   (!(table = (GFXglyph *)malloc((last - first + 1) *
	    sizeof(GFXglyph))))) {
		fprintf(stderr, "Malloc error\n");
		return 1;
	}

	// Derive font table names from filename.  Period (filename
	// extension) is truncated and replaced with the font size & bits.
	strcpy(fontName, ptr);
	ptr = strrchr(fontName, '.'); // Find last period (file ext)
	if(!ptr) ptr = &fontName[strlen(fontName)]; // If none, append
	// Insert font size and 7/8 bit.  fontName was alloc'd w/extra
	// space to allow this, we're not sprintfing into Forbidden Zone.
	sprintf(ptr, "%dpt%db", size, (last > 127) ? 8 : 7);
	// Space and punctuation chars in name replaced w/ underscores.  
	for(i=0; (c=fontName[i]); i++) {
		if(isspace(c) || ispunct(c)) fontName[i] = '_';
	}

	// Init FreeType lib, load font
	if((err = FT_Init_FreeType(&library))) {
		fprintf(stderr, "FreeType init error: %d", err);
		return err;
	}
	if((err = FT_New_Face(library, argv[1], 0, &face))) {
		fprintf(stderr, "Font load error: %d", err);
		FT_Done_FreeType(library);
		return err;
	}

	// << 6 because '26dot6' fixed-point format
	FT_Set_Char_Size(face, size << 6, 0, DPI, 0);

	// Currently all symbols from 'first' to 'last' are processed.
	// Fonts may contain WAY more glyphs than that, but this code
	// will need to handle encoding stuff to deal with extracting
	// the right symbols, and that's not done yet.
	// fprintf(stderr, "%ld glyphs\n", face->num_glyphs);

	printf("package Giza.Bitmap_Fonts.%s is\n\n", fontName);

	printf("   %sBitmaps : aliased constant Font_Bitmap := (\n  ",
               fontName);

	// Process glyphs and output huge bitmap data array
	for(i=first, j=0; i<=last; i++, j++) {
		// MONO renderer provides clean image with perfect crop
		// (no wasted pixels) via bitmap struct.
		if((err = FT_Load_Char(face, i, FT_LOAD_TARGET_MONO))) {
			fprintf(stderr, "Error %d loading char '%c'\n",
			  err, i);
			continue;
		}

		if((err = FT_Render_Glyph(face->glyph,
		  FT_RENDER_MODE_MONO))) {
			fprintf(stderr, "Error %d rendering char '%c'\n",
			  err, i);
			continue;
		}

		if((err = FT_Get_Glyph(face->glyph, &glyph))) {
			fprintf(stderr, "Error %d getting glyph '%c'\n",
			  err, i);
			continue;
		}

		bitmap = &face->glyph->bitmap;
		g      = (FT_BitmapGlyphRec *)glyph;

		// Minimal font and per-glyph information is stored to
		// reduce flash space requirements.  Glyph bitmaps are
		// fully bit-packed; no per-scanline pad, though end of
		// each character may be padded to next byte boundary
		// when needed.  16-bit offset means 64K max for bitmaps,
		// code currently doesn't check for overflow.  (Doesn't
		// check that size & offsets are within bounds either for
		// that matter...please convert fonts responsibly.)
		table[j].bitmapOffset = bitmapOffset;
		table[j].width        = bitmap->width;
		table[j].height       = bitmap->rows;
		table[j].xAdvance     = face->glyph->advance.x >> 6;
		table[j].xOffset      = g->left;
		table[j].yOffset      = 1 - g->top;

		for(y=0; y < bitmap->rows; y++) {
			for(x=0;x < bitmap->width; x++) {
				byte = x / 8;
				bit  = 0x80 >> (x & 7);
				enbit(bitmap->buffer[
				  y * bitmap->pitch + byte] & bit);
			}
		}

		// Pad end of char bitmap to next byte boundary if needed
		int n = (bitmap->width * bitmap->rows) & 7;
		if(n) { // Pixel count not an even multiple of 8?
			n = 8 - n; // # bits to next multiple
			while(n--) enbit(0);
		}
		bitmapOffset += (bitmap->width * bitmap->rows + 7) / 8;

		FT_Done_Glyph(glyph);
	}

	printf(");\n\n"); // End bitmap array

	// Output glyph attributes table (one per character)
	printf("   %sGlyphs : aliased constant Glyph_Array := (\n",
               fontName);
	for(i=first, j=0; i<=last; i++, j++) {
		printf("  (%d, %d, %d, %d, %d, %d)",
		  table[j].bitmapOffset,
		  table[j].width,
		  table[j].height,
		  table[j].xAdvance,
		  table[j].xOffset,
		  table[j].yOffset);
		if(i < last) {
			printf(",   -- 0x%02X", i);
			if((i >= ' ') && (i <= '~')) {
				printf(" '%c'", i);
			}
			putchar('\n');
		}
	}
	printf("); -- 0x%02X", last);
	if((last >= ' ') && (last <= '~')) printf(" '%c'", last);
	printf("\n\n");

	// Output font structure
	printf("   Font : Bitmap_Font :=\n");
        printf("     (%sBitmaps'Access,\n", fontName);
        printf("      %sGlyphs'Access,\n", fontName);
	printf("      16#%02X#,\n", first);
	printf("      16#%02X#,\n", last);
	printf("      %ld);\n", face->size->metrics.height >> 6);

	printf("end Giza.Bitmap_Fonts.%s;\n", fontName);

	FT_Done_FreeType(library);

	return 0;
}
Пример #2
0
void TTF_Init(void)
	{
	if (!TTF_initialized && FT_Init_FreeType(&library))
		E_Exit("TTF: Couldn't init FreeType engine");
	TTF_initialized = true;
	}
Пример #3
0
/* ------------------------------------------------------------------------- */
int main ( int argc, char *argv[] )
{
    FT_Library  library;
    FT_Face     face;
    FT_FaceRec  props;
    FT_Error    error = 0;
    FT_UInt     names;
    FT_CharMap  charmap;
    FX_Kern_0   *kstable;
    TT_OS2      *pOS2;
    TT_Postscript *ppost;
    ULONG       rc;
    BOOL        bDumpUCS = FALSE;
    BOOL        bShowKST = FALSE;
    BOOL        bShowOS2 = FALSE;
    BOOL        bShowPS  = FALSE;
    char        szPID[10];
    char        szEID[32];
    int         i;


    char     *buf;

    if ( argc < 2 ) {
        printf("FONTNAME - Show summary of OpenType font names and other optional information.\n");
        printf("Syntax: FONTNAME <filename> [ options ]\n\n");
        printf("  /D    Dump Unicode and DBCS strings as hex values\n");
        printf("  /K    Show kerning summary (KERN format 0 only)\n");
        printf("  /O    Show OS/2 table\n");
        printf("  /P    Show POST table\n\n");
        printf("NAME and CMAP table information is always shown.\n\n");
        printf("\nNo font file specified.\n");
        return 0;
    }
    for ( i = 2; i < argc; i++ ) {
        if ( strlen( argv[i] ) > 1 ) {
            CHAR cOption = 0;
            if ( argv[i][0] == '/' || argv[i][0] == '-') cOption = argv[i][1];
            switch ( cOption ) {
                case 'd':
                case 'D':
                    bDumpUCS = TRUE;
                    break;
                case 'k':
                case 'K':
                    bShowKST = TRUE;
                    break;
                case 'o':
                case 'O':
                    bShowOS2 = TRUE;
                    break;
                case 'p':
                case 'P':
                    bShowPS = TRUE;
                    break;
                default : break;
            }
        }
    }

    if (( rc = UniCreateUconvObject( L"@endian=big", &uconv )) != ULS_SUCCESS ) {
        printf("Failed to create Unicode conversion object (rc=0x%X).\n");
        printf("Unicode text values will not be shown.\n");
        uconv = NULL;
    }

    error = FT_Init_FreeType( &library );
    if ( error ) {
        printf("An error occurred during library initialization.\n");
        return (int) error;
    }
    printf("FreeType 2 library initialized successfully.\n");

    error = FT_New_Face( library, argv[1], 0, &face );
    if ( error ) {
        if ( error == FT_Err_Unknown_File_Format )
            printf("The file format is unsupported.\n");
        else
            printf("The file \"%s\" could not be loaded.\n", argv[1]);
        goto done;
    }
    printf("Font %s read successfully.\n", face->family_name );

    names = FT_Get_Sfnt_Name_Count( face );
    if ( names ) {

        printf("Names table contains %d entries:\n", names );
        for ( i = 0; i < names; i++ ) {
            FT_SfntName name;
            error = FT_Get_Sfnt_Name( face, i, &name );
            if ( error ) continue;
            printf("%2d: Plat %d, Enc %d, Lang 0x%X, ID %2d ",
                   i, name.platform_id, name.encoding_id, name.language_id, name.name_id );
            if ( name.platform_id == 1 && name.encoding_id == 0 && name.string_len < 100 ) {
                printf(" \"");
                PrintNameString( name.string, name.string_len );
                printf("\"\n");
            }
            else if ( name.platform_id == 3 && name.encoding_id == 1 && uconv && name.string_len < 200 ) {
                printf(" (U)\"");
                if (bDumpUCS)
                    DumpUnicodeString( name.string, name.string_len );
                else
                    PrintUnicodeString( name.string, name.string_len );
                printf("\"\n");
            }
            else if ( name.string_len < 200 && bDumpUCS ) {
                printf(" \"");
                DumpUnicodeString( name.string, name.string_len );
                printf("\"\n");
            }
            else
                printf(" [%d bytes]\n", name.string_len );
        }
    }

    printf("\nINCLUDED CMAPS");
    printf("\n--------------\n");
    for ( i = 0; i < face->num_charmaps; i++ ) {
        charmap = face->charmaps[i];
        switch ( charmap->platform_id ) {
            case 0:
                strcpy( szPID, "Unicode");
                switch ( charmap->encoding_id ) {
                    case 0:  strcpy( szEID, "default");     break;
                    case 1:  strcpy( szEID, "1.1");         break;
                    case 3:  strcpy( szEID, "2+");          break;
                    case 4:  strcpy( szEID, "3.1+ UTF-32"); break;
                    default: strcpy( szEID, "unknown");     break;
                }
                break;

            case 1:
                strcpy( szPID, "Macintosh");
                switch ( charmap->encoding_id ) {
                    case 0:  strcpy( szEID, "Roman");         break;
                    case 1:  strcpy( szEID, "Japanese");      break;
                    case 2:  strcpy( szEID, "Chinese-T");     break;
                    case 3:  strcpy( szEID, "Korean");        break;
                    case 8:  strcpy( szEID, "symbols");       break;
                    case 25: strcpy( szEID, "Chinese-S");     break;
                    default: strcpy( szEID, "other language");break;
                }
                break;

            case 3:
                strcpy( szPID, "Windows");
                switch ( charmap->encoding_id ) {
                    case 0:  strcpy( szEID, "symbols");           break;
                    case 1:  strcpy( szEID, "Unicode");           break;
                    case 2:  strcpy( szEID, "Shift-JIS (Japan)"); break;
                    case 3:  strcpy( szEID, "GB2312 (China)");    break;
                    case 4:  strcpy( szEID, "Big5 (Taiwan)");     break;
                    case 5:  strcpy( szEID, "Wansung (Korea)");   break;
                    case 6:  strcpy( szEID, "Johab (Korea)");     break;
                    case 10: strcpy( szEID, "UCS-4");             break;
                    default: strcpy( szEID, "unknown");           break;
                }
                break;

            default:
                strcpy( szPID, "unknown");
                strcpy( szEID, "unknown");
                break;
        }
        printf("Platform: %d (%s), Encoding: %d (%s)\n", charmap->platform_id, szPID,
                                                         charmap->encoding_id, szEID );
    }
#if 0
    error = FX_Flush_Stream( face );
    if ( error ) {
        printf("Failed to close stream: 0x%X\n", error );
        FT_Done_Face( face );
        goto done;
    }
    error = FX_Activate_Stream( face );
    if ( error ) {
        printf("Failed to reopen stream: 0x%X\n", error );
        FT_Done_Face( face );
        goto done;
    }
#endif

    if ( bShowKST ) {
        printf("\nKERNING INFORMATION");
        printf("\n-------------------\n");
        error = FX_Get_Kerning_Pairs( face, &kstable );
        switch ( error ) {
            case 0:
                printf("%u kerning pairs defined:\n", kstable->nPairs );
                if ( kstable->nPairs )
                {
                    for ( i = 0; i < kstable->nPairs; i++ ) {
                        printf("   %X / %X (%d)\n",
                               kstable->pairs[i].left,
                               kstable->pairs[i].right,
                               kstable->pairs[i].value );
                    }
                }
                safe_free( kstable );
                break;
            case FT_Err_Table_Missing:
                printf("No kerning table defined.\n");
                break;
            case FX_Err_Invalid_Kerning_Table:
                printf("The kerning table is invalid.\n");
                break;
            case FT_Err_Out_Of_Memory:
                printf("Memory allocation error.\n");
                break;
            case FX_Err_Invalid_Kerning_Table_Format:
                printf("No supported kerning table format found.\n");
                break;
            default: printf("An unknown error (0x%X) was encountered.\n", error );
                     break;
        }
    }

    if ( bShowOS2 ) {
        printf("\nOS/2 TABLE");
        printf("\n----------\n");

        pOS2 = (TT_OS2 *) FT_Get_Sfnt_Table( face, ft_sfnt_os2 );
        if ( pOS2 ) {
            printf("version:             %u\n", pOS2->version );
            printf("xAvgCharWidth:       %d\n", pOS2->xAvgCharWidth );
            printf("usWeightClass:       %u\n", pOS2->usWeightClass );
            printf("usWidthClass:        %u\n", pOS2->usWidthClass );
            printf("fsType:              0x%X\n", pOS2->fsType );
            printf("ySubscriptXSize:     %d\n", pOS2->ySubscriptXSize );
            printf("ySubscriptYSize:     %d\n", pOS2->ySubscriptYSize );
            printf("ySubscriptXOffset:   %d\n", pOS2->ySubscriptXOffset );
            printf("ySubscriptYOffset:   %d\n", pOS2->ySubscriptYOffset );
            printf("ySuperscriptXSize:   %d\n", pOS2->ySuperscriptXSize );
            printf("ySuperscriptYSize:   %d\n", pOS2->ySuperscriptYSize );
            printf("ySuperscriptXOffset: %d\n", pOS2->ySuperscriptXOffset );
            printf("ySuperscriptYOffset: %d\n", pOS2->ySuperscriptYOffset );
            printf("yStrikeoutSize:      %d\n", pOS2->yStrikeoutSize );
            printf("yStrikeoutPosition:  %d\n", pOS2->yStrikeoutPosition );
            printf("sFamilyClass:        %d\n", pOS2->sFamilyClass );
            printf("panose:              []\n");
            printf("ulUnicodeRange1:     0x%X\n", pOS2->ulUnicodeRange1 );
            printf("ulUnicodeRange2:     0x%X\n", pOS2->ulUnicodeRange2 );
            printf("ulUnicodeRange3:     0x%X\n", pOS2->ulUnicodeRange3 );
            printf("ulUnicodeRange4:     0x%X\n", pOS2->ulUnicodeRange4 );
            printf("achVendID:           %c%c%c%c\n", pOS2->achVendID[0], pOS2->achVendID[1], pOS2->achVendID[2], pOS2->achVendID[3] );
            printf("fsSelection:         0x%X\n", pOS2->fsSelection );
            printf("usFirstCharIndex:    %u\n", pOS2->usFirstCharIndex );
            printf("usLastCharIndex:     %u\n", pOS2->usLastCharIndex );
            printf("sTypoAscender:       %d\n", pOS2->sTypoAscender );
            printf("sTypoDescender:      %d\n", pOS2->sTypoDescender );
            printf("sTypoLineGap:        %d\n", pOS2->sTypoLineGap );
            printf("usWinAscent:         %u\n", pOS2->usWinAscent );
            printf("usWinDescent:        %u\n", pOS2->usWinDescent );
        }
        else printf("OS/2 table could not be located.\n");
    }

    if ( bShowPS) {
        printf("\nPOST TABLE");
        printf("\n----------\n");

        ppost = (TT_Postscript *) FT_Get_Sfnt_Table( face, ft_sfnt_post );
        if ( ppost ) {
            printf("FormatType:         0x%X\n", ppost->FormatType );
            printf("italicAngle:        %d\n", ppost->italicAngle );
            printf("underlinePosition:  %d\n", ppost->underlinePosition );
            printf("underlineThickness: %d\n", ppost->underlineThickness );
            printf("isFixedPitch:       %u\n", ppost->isFixedPitch );
            printf("minMemType42:       %u\n", ppost->minMemType42 );
            printf("maxMemType42:       %u\n", ppost->maxMemType42 );
            printf("minMemType1:        %u\n", ppost->minMemType1 );
            printf("maxMemType1:        %u\n", ppost->maxMemType1 );
        }
        else printf("POST table could not be loaded.\n");
    }

    error = FT_Done_Face( face );
done:
    FT_Done_FreeType( library );
    if ( uconv ) UniFreeUconvObject( uconv );
    return (int) error;
}
	FreetypeFontProvider::FreetypeFontProvider(const FontProvider::Options& options): FontProvider(options)
	{
		if ( options.size.height < 1 )
		{
			throw std::runtime_error("[FreetypeFontProvider] Invalid size");
		}

		if ( options.mode == L"" || options.mode == L"normal" )
		{
			m_render_mode = FT_RENDER_MODE_NORMAL;
		}
		else if ( options.mode == L"monochrome" )
		{
			m_render_mode = FT_RENDER_MODE_MONO;
		}
		else if ( options.mode == L"lcd" )
		{
			m_render_mode = FT_RENDER_MODE_LCD;
		}
		else
		{
			throw std::runtime_error("[FreetypeFontProvider] Invalid font.mode");
		}

		if ( FT_Init_FreeType(&m_font_library) )
		{
			throw std::runtime_error("[FreetypeFontProvider] Can't initialize Freetype");
		}

		std::string filename_u8 = Encoding::UTF8.FromUCS2(options.name);
		if ( FT_New_Face(m_font_library, filename_u8.c_str(), 0, &m_font_face) )
		{
			Dispose();
			throw std::runtime_error("[FreetypeFontProvider] Can't load font from file");
		}

		int hres = 64;
		FT_Matrix matrix =
		{
			(int)((1.0/hres) * 0x10000L),
			(int)((0.0)      * 0x10000L),
			(int)((0.0)      * 0x10000L),
			(int)((1.0)      * 0x10000L)
		};

		if ( FT_Set_Char_Size(m_font_face, (uint32_t)(options.size.height*64), 0, 96*hres, 96) )
		{
			Dispose();
			throw std::runtime_error("[FreetypeFontProvider] Can't setup font");
		}

		FT_Set_Transform(m_font_face, &matrix, NULL);

		float yscale = m_font_face->size->metrics.y_scale / (float)(1 << 16);
		int height = std::ceil((m_font_face->bbox.yMax-m_font_face->bbox.yMin) * yscale / 64.0f);
		//int descender = std::floor(m_font_face->descender * yscale / 64.0f);
		//int ascender = std::ceil(m_font_face->ascender * yscale / 64.0f);

		auto get_metrics = [&](wchar_t code) -> FT_Glyph_Metrics
		{
			if ( FT_Load_Glyph(m_font_face, FT_Get_Char_Index(m_font_face, code), 0) )
			{
				throw std::runtime_error("[FreetypeFontProvider] Metrics error");
			}

			return m_font_face->glyph->metrics;
		};

		int width = 0;

		FT_Glyph_Metrics mDot = get_metrics(L'.'), mAt = get_metrics(L'@');
		if ( mDot.horiAdvance == mAt.horiAdvance )
		{
			// Monospace font
			width = std::ceil(mDot.horiAdvance / 64.0f);
		}
		else
		{
			// This is not a monospace font
			//throw std::runtime_error("[FreetypeFontProvider::ctor] This is not a monospace font");
			width = std::ceil(mAt.horiAdvance / 64.0f);
		}

		width = std::ceil(width/64.0);

		height = m_font_face->size->metrics.height >> 6;
		//descender = m_font_face->size->metrics.descender >> 6;

		m_cell_size = Size(width, height);
		m_glyph_size = Size(width, height);

		FT_Library_SetLcdFilter(m_font_library, FT_LCD_FILTER_DEFAULT);
		
		return;
	}
Пример #5
0
TTFLibrary::TTFLibrary() : _library(), _initialized(false) {
	if (!FT_Init_FreeType(&_library))
		_initialized = true;
}
Пример #6
0
Font::Font()
{
    if(FT_Init_FreeType(&library))
        throw love::Exception("TrueTypeFont Loading error: FT_Init_FreeType failed\n");
}
Пример #7
0
tgon::FTFontManager::FTFontManager( )
{
	FT_Init_FreeType( &library );
}
Пример #8
0
//******************** M A I N ************************
void get_font(string FontName_base, char letter, int ptsize, vect2d *times)
{
    _mkdir("font_rasters");
    std::string FontName = "fonts/" + FontName_base + ".ttf";
    char buf[256];
    string letter_name;
    letter_name += letter;
    if (letter >= 'A' && letter <= 'Z')
        letter_name += letter;

    //-----------------------------------------
    // Load contour of glyph
    //-----------------------------------------

    lines.clear();
    bez2s.clear();

    FT_Face face;
    FT_Library    library;
    FT_Error error;

    error = FT_Init_FreeType( &library );
    Check(error, "", "error initializing FT lib");

    error = FT_New_Face( library, FontName.c_str(), 0, &face );
    Check(error, "",  "error loading font");

    FT_F26Dot6 font_size = ptsize*64;
    error = FT_Set_Char_Size( face, font_size, font_size, 72, 72 );
    Check(error, "", "error setting char size");

    FT_UInt   glyph_index = FT_Get_Char_Index( face, letter );
    FT_Int32  load_flags = FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP;
    error = FT_Load_Glyph( face,  glyph_index, load_flags );
    Check(error, "", "error loading glyph");

    FT_Glyph glyph;
    error = FT_Get_Glyph( face->glyph, &glyph );
    Check(error, "", "error getting glyph");

    FT_OutlineGlyph Outg;
    error = GetOutLine(glyph, &Outg);
    Check(error,"", "error getting outline");

    // use my own callcacks to walk over the contour
    FT_Outline_Funcs func_interface;
    func_interface.shift = 0;
    func_interface.delta = 0;
    func_interface.move_to = move_to;
    func_interface.line_to = line_to;
    func_interface.conic_to = conic_to;
    func_interface.cubic_to = cubic_to;
    FT_Outline_Decompose(&Outg->outline, &func_interface, 0);

    //-----------------------------------------
    // Rasterize using FreeType
    //-----------------------------------------

    // rasterize using FreeType so that a comparison to my code can be made
    double t_ft_start = get_time();
    FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL);
    double t_ft_stop = get_time();

    // save timing
    FILE *fa = fopen("timings.txt", "a");
    fprintf(fa, "time FreeType = %f\n", t_ft_stop - t_ft_start);
    fclose(fa);

    // create grid / calculate resolution
    g.max_depth = 0;
    g.grid_res = 2;

    int maxsize = max(face->glyph->bitmap.width, face->glyph->bitmap.rows);
    while (g.grid_res < maxsize)
    {
        g.grid_res *= 2;
        g.max_depth++;
    }

    vect2i offset;
    offset.set((g.grid_res - face->glyph->bitmap.width) / 2, (g.grid_res - face->glyph->bitmap.rows) / 2);

    // copy bitmap into a buffer
    Array2D<vect3ub> ftgrid;
    ftgrid.resize(g.grid_res, g.grid_res);

    for (int k = 0; k < g.grid_res*g.grid_res; k++)
        ftgrid.data[k].set(0);

    for (int j = 0; j < face->glyph->bitmap.rows; j++)
    {
        unsigned char *row = face->glyph->bitmap.buffer + (face->glyph->bitmap.rows-j-1)*face->glyph->bitmap.pitch;

        for (int i = 0; i < face->glyph->bitmap.width; i++)
        {
            ftgrid(i + offset[0], j + offset[1]) = row[i];
        }
    }

    sprintf(buf, "font_rasters/%s_%04d_%s_1_ft.png", FontName_base.c_str(), ptsize, letter_name.c_str());
    save_png(buf, ftgrid);

    //-----------------------------------------
    // Rasterize using our method
    //-----------------------------------------

    // get bbox
    FT_BBox bbox;
    FT_Outline_Get_BBox(&Outg->outline, &bbox);
    //printf("bbox = (%f, %f), (%f, %f)\n", bbox.xMin/64., bbox.yMin/64., bbox.xMax/64., bbox.yMax/64.);

    // fit in box
    vect2f ext;
    ext.set(bbox.xMax/64. - bbox.xMin/64., bbox.yMax/64. - bbox.yMin/64.);
    float maxext = std::max(ext[0], ext[1]) * 1.1;

    for (int i = 0; i < lines.s; i++)
    {
        //printf("line\n");
        for (int j = 0; j < 2; j++)
        {
            lines[i][j][0] = (lines[i][j][0] - floor(bbox.xMin/64.) + offset[0]) / g.grid_res;
            lines[i][j][1] = (lines[i][j][1] - floor(bbox.yMin/64.) + offset[1]) / g.grid_res;
            //printf("%f %f\n", lines[i][j][0], lines[i][j][1]);
        }
    }
    for (int i = 0; i < bez2s.s; i++)
    {
        //printf("bez2\n");
        for (int j = 0; j < 3; j++)
        {
            bez2s[i][j][0] = (bez2s[i][j][0] - floor(bbox.xMin/64.) + offset[0]) / g.grid_res;
            bez2s[i][j][1] = (bez2s[i][j][1] - floor(bbox.yMin/64.) + offset[1]) / g.grid_res;
            //printf("%f %f\n", bez2s[i][j][0], bez2s[i][j][1]);
        }
    }

    //vect3ub *grid = new vect3ub [g.grid_res*g.grid_res];
    Array2D<float> grid;
    Array2D<vect3ub> ourgrid;
    grid.resize(g.grid_res, g.grid_res);
    ourgrid.resize(g.grid_res, g.grid_res);

    // rasterize
    for (int k = 0; k < g.grid_res*g.grid_res; k++)
        grid.data[k] = 0;
    double t_ours_start = get_time();
    raster_poly(lines, bez2s, grid.data);
    double t_ours_stop = get_time();

    // save timing
    FILE *f = fopen("timings.txt", "a");
    fprintf(f, "time wavelet = %f\n", (t_ours_stop - t_ours_start));
    fclose(f);

    // copy into color image and save
    for (int k = 0; k < g.grid_res*g.grid_res; k++)
    {
        if (grid.data[k] >= 1)
            ourgrid.data[k] = 255;
        else if (grid.data[k] <= 0)
            ourgrid.data[k] = 0;
        else
            ourgrid.data[k] = grid.data[k]*255;
    }
    sprintf(buf, "font_rasters/%s_%04d_%s_2_ours.png", FontName_base.c_str(), ptsize, letter_name.c_str());
    save_png(buf, ourgrid);

    //-----------------------------------------
    // Calculate difference between renders
    //-----------------------------------------
    Array2D<vect3ub> grid_dif;
    grid_dif.resize(g.grid_res, g.grid_res);

    for (int i = 0; i < grid_dif.data_size; i++)
    {
        int dif = (grid.data[i]*255 - ftgrid.data[i][0]) * 10;
        if (dif > 255)
            dif = 255;
        else if (dif < -255)
            dif = -255;

#if 1
        grid_dif.data[i] = 255;

        if (dif < 0)
        {
            grid_dif.data[i][0] += dif;
            grid_dif.data[i][1] += dif;
        }
        else
        {
            grid_dif.data[i][1] -= dif;
            grid_dif.data[i][2] -= dif;
        }
#else
        grid_dif.data[i] = 0;

        if (dif < 0)
            grid_dif.data[i][2] -= dif;
        else
            grid_dif.data[i][0] += dif;
#endif
    }

    sprintf(buf, "font_rasters/%s_%04d_%s_3_dif.png", FontName_base.c_str(), ptsize, letter_name.c_str());
    save_png(buf, grid_dif);

    //printf("--== timing comparison ==--\n");
    //printf("time freetype = %f\n", t_ft_stop - t_ft_start);
    //printf("time wavelets = %f\n", t_ours_stop - t_ours_start);
    //printf("times slower = %f\n", (t_ours_stop - t_ours_start) / (t_ft_stop - t_ft_start) );

    if (times)
    {
        times->v[0] += t_ft_stop - t_ft_start;
        times->v[1] += t_ours_stop - t_ours_start;
    }
}
Пример #9
0
int main (int argc, char** argv)
{
    if (argc != 2)
    {
        std::cerr << "Usage: " << argv[0] << " <num-iter>" << std::endl;
        return EXIT_FAILURE;
    }

    const unsigned NUM_ITER = atoi(argv[1]);

    // open first face in the font
    FT_Library ft_library = 0;
    FT_Error error = FT_Init_FreeType(&ft_library);
    if (error) throw std::runtime_error("Failed to initialize FreeType2 library");

    FT_Face ft_face[NUM_EXAMPLES];
    FT_New_Face(ft_library, "fonts/DejaVuSerif.ttf", 0, &ft_face[ENGLISH]);
    FT_New_Face(ft_library, "fonts/amiri-0.104/amiri-regular.ttf", 0, &ft_face[ARABIC]);
    FT_New_Face(ft_library, "fonts/fireflysung-1.3.0/fireflysung.ttf", 0, &ft_face[CHINESE]);

    // Get our harfbuzz font structs
    hb_font_t *hb_ft_font[NUM_EXAMPLES];
    hb_ft_font[ENGLISH] = hb_ft_font_create(ft_face[ENGLISH], NULL);
    hb_ft_font[ARABIC]  = hb_ft_font_create(ft_face[ARABIC] , NULL);
    hb_ft_font[CHINESE] = hb_ft_font_create(ft_face[CHINESE], NULL);

    {
        std::cerr << "Starting ICU shaping:" << std::endl;
        progress_timer timer1(std::clog,"ICU shaping done");
        UErrorCode err = U_ZERO_ERROR;
        for (unsigned i = 0; i < NUM_ITER; ++i)
        {
            for (unsigned j = 0; j < NUM_EXAMPLES; ++j)
            {
                UnicodeString text = UnicodeString::fromUTF8(texts[j]);
                int32_t length = text.length();
                UnicodeString reordered;
                UnicodeString shaped;
                UBiDi *bidi = ubidi_openSized(length, 0, &err);
                ubidi_setPara(bidi, text.getBuffer(), length, UBIDI_DEFAULT_LTR, 0, &err);
                ubidi_writeReordered(bidi, reordered.getBuffer(length),
                                     length, UBIDI_DO_MIRRORING, &err);
                ubidi_close(bidi);
                reordered.releaseBuffer(length);
                u_shapeArabic(reordered.getBuffer(), length,
                              shaped.getBuffer(length), length,
                              U_SHAPE_LETTERS_SHAPE | U_SHAPE_LENGTH_FIXED_SPACES_NEAR |
                              U_SHAPE_TEXT_DIRECTION_VISUAL_LTR, &err);
                shaped.releaseBuffer(length);
                if (U_SUCCESS(err))
                {
                    U_NAMESPACE_QUALIFIER StringCharacterIterator iter(shaped);
                    for (iter.setToStart(); iter.hasNext();)
                    {
                        UChar ch = iter.nextPostInc();
                        int32_t glyph_index = FT_Get_Char_Index(ft_face[j], ch);
                        if (i == 0)
                        {
                            std::cerr << glyph_index <<  ":";
                        }
                    }
                    if (i == 0) std::cerr << std::endl;
                }
            }
        }
    }

    {
        const char **shaper_list = hb_shape_list_shapers();
        for ( ;*shaper_list; shaper_list++)
        {
            std::cerr << *shaper_list << std::endl;
        }

        std::cerr << "Starting Harfbuzz shaping" << std::endl;
        progress_timer timer2(std::clog,"Harfbuzz shaping done");
        const char* const shapers[]  = { /*"ot",*/"fallback" };
        hb_buffer_t *buffer(hb_buffer_create());

        for (unsigned i = 0; i < NUM_ITER; ++i)
        {
            for (unsigned j = 0; j < NUM_EXAMPLES; ++j)
            {
                UnicodeString text = UnicodeString::fromUTF8(texts[j]);
                int32_t length = text.length();
                hb_buffer_clear_contents(buffer);
                //hb_buffer_set_unicode_funcs(buffer.get(), hb_icu_get_unicode_funcs());
                hb_buffer_pre_allocate(buffer, length);
                hb_buffer_add_utf16(buffer, text.getBuffer(), text.length(), 0, length);
                hb_buffer_set_direction(buffer, text_directions[j]);
                hb_buffer_set_script(buffer, scripts[j]);
                hb_buffer_set_language(buffer,hb_language_from_string(languages[j], std::strlen(languages[j])));
                //hb_shape(hb_ft_font[j], buffer.get(), 0, 0);
                hb_shape_full(hb_ft_font[j], buffer, 0, 0, shapers);
                unsigned num_glyphs = hb_buffer_get_length(buffer);
                hb_glyph_info_t *glyphs = hb_buffer_get_glyph_infos(buffer, NULL);
                //hb_glyph_position_t *positions = hb_buffer_get_glyph_positions(buffer.get(), NULL);
                for (unsigned k=0; k<num_glyphs; ++k)
                {
                    int32_t glyph_index = glyphs[k].codepoint;
                    if (i == 0)
                    {
                        std::cerr  <<  glyph_index << ":";
                    }
                }
                if (i == 0) std::cerr << std::endl;
            }
        }
        hb_buffer_destroy(buffer);
    }

    // cleanup
    for (int j=0; j < NUM_EXAMPLES; ++j)
    {
        hb_font_destroy(hb_ft_font[j]);
    }
    FT_Done_FreeType(ft_library);

    return EXIT_SUCCESS;
}
int main (int argc, char **argv)
{
	int i,j,found=0,m,mask=1,kmode=1,pmode=0, lc=-1, changed=0, todo=1, help=1, help_changed=0, move=0;
	unsigned char actchan[20]=""/*,channel[128]=""*/;
	FILE *fh,*fh2;
	char *cpt1,*cpt2;
	gpixel mp, mc[MAX_MASK], tp;
	int tsx=430, tsy=120, tdy=24, tsz=28, txw=500, tcol=TURQUOISE;
	int xp[MAX_MASK][8],yp[MAX_MASK][8],xw[MAX_MASK][8],yw[MAX_MASK][8],valid[MAX_MASK],cmc[MAX_MASK],xxp,xxw,yyp,yyw,nmsk=0,amsk=0;
	double xs=1.0, ys=1.0;
	time_t t1,t2;

		for(j=0; j<MAX_MASK; j++)
		{
			valid[j]=0;
			cmc[j]=BLACK;
			make_color(BLACK, &mc[j]);
			for(i=0; i<8; i++)
			{
				xp[j][i]=(1280-40)/2;
				xw[j][i]=40;
				yp[j][i]=(720-20)/2;
				yw[j][i]=20;
			}	
		}
		system("pzapit -var > /tmp/logomaskset.stat");
		if((fh=fopen("/tmp/logomaskset.stat","r"))!=NULL)
		{
			if(fgets(tstr,500,fh))
			{
				TrimString(tstr);
				if(strlen(tstr))
				{
					if(sscanf(tstr+strlen(tstr)-1,"%d",&pmode)!=1)
					{
						pmode=0;
					}
				}
			}
			fclose(fh);
		}
	
		system("touch /tmp/.logomask_kill");

		fb = open(FB_DEVICE, O_RDWR);

		if(ioctl(fb, FBIOGET_FSCREENINFO, &fix_screeninfo) == -1)
		{
			printf("logomask <FBIOGET_FSCREENINFO failed>\n");
			return -1;
		}
		if(ioctl(fb, FBIOGET_VSCREENINFO, &var_screeninfo) == -1)
		{
			printf("logomask <FBIOGET_VSCREENINFO failed>\n");
			return -1;
		}
		
		if(!(lfb = (unsigned char*)mmap(0, fix_screeninfo.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fb, 0)))
		{
			printf("logomask <mapping of Framebuffer failed>\n");
			return -1;
		}

	//init fontlibrary

		if((error = FT_Init_FreeType(&library)))
		{
			printf("logomask <FT_Init_FreeType failed with Errorcode 0x%.2X>", error);
			munmap(lfb, fix_screeninfo.smem_len);
			return -1;
		}

		if((error = FTC_Manager_New(library, 1, 2, 0, &MyFaceRequester, NULL, &manager)))
		{
			printf("logomask <FTC_Manager_New failed with Errorcode 0x%.2X>\n", error);
			FT_Done_FreeType(library);
			munmap(lfb, fix_screeninfo.smem_len);
			return -1;
		}

		if((error = FTC_SBitCache_New(manager, &cache)))
		{
			printf("logomask <FTC_SBitCache_New failed with Errorcode 0x%.2X>\n", error);
			FTC_Manager_Done(manager);
			FT_Done_FreeType(library);
			munmap(lfb, fix_screeninfo.smem_len);
			return -1;
		}

		if((error = FTC_Manager_LookupFace(manager, FONT, &face)))
		{
			printf("logomask <FTC_Manager_Lookup_Face failed with Errorcode 0x%.2X>\n", error);
			FTC_Manager_Done(manager);
			FT_Done_FreeType(library);
			munmap(lfb, fix_screeninfo.smem_len);
			return -1;
		}

		use_kerning = FT_HAS_KERNING(face);

		desc.face_id = FONT;
		desc.flags = FT_LOAD_MONOCHROME;


		InitRC();

	//init backbuffer

		if(!(lbb = malloc(fix_screeninfo.line_length*var_screeninfo.yres)))
		{
			printf("logomask <allocating of Backbuffer failed>\n");
			munmap(lfb, fix_screeninfo.smem_len);
			return -1;
		}

		memset(lbb, 0, fix_screeninfo.line_length*var_screeninfo.yres);

		system("pzapit -gi > /tmp/logomask.chan");
		if((fh=fopen("/tmp/logomask.chan","r"))!=NULL)
		{
			if(fgets(tstr, BUFSIZE, fh))
			{
				TrimString(tstr);
				if((cpt1=strchr(tstr,' '))!=NULL)
					*cpt1=0;
			}
			fclose(fh);
			if(strlen(tstr))
			{
				strcpy(actchan,tstr);
			}

			if((fh=fopen(CFG_FILE,"r"))!=NULL)
			{
				found=0;
				while(fgets(tstr, BUFSIZE, fh) && !found)
				{
					TrimString(tstr);
					if(strlen(tstr))
					{
						if(strstr(tstr,actchan)!=NULL)
						{
							mask=1;
							nmsk=0;
							cpt2=strstr(tstr,",MC");
							if((cpt1=strchr(tstr,','))!=NULL)
							{
								while(cpt1)
								{
									valid[nmsk]=0;
									if(cpt2 && sscanf(cpt2+1,"MC%8X",&mp.lpixel)==1)
									{
										cpt2=strchr(cpt2+1,',');
									}
									else
									{
										make_color(BLACK, &mp);
									}
									for(i=0; i<8 && cpt1; i++)
									{
										cpt1++;
										if(sscanf(cpt1,"%d,%d,%d,%d",&xxp,&xxw,&yyp,&yyw)==4)
										{
											xp[nmsk][i]=xxp;
											xw[nmsk][i]=xxw;
											yp[nmsk][i]=yyp;
											yw[nmsk][i]=yyw;
											mc[nmsk].lpixel=mp.lpixel;
											found=1;
											valid[nmsk]=1;
										}
										for(j=0; j<4 && cpt1; j++)
										{
											cpt1=strchr(cpt1+1,',');
										}
									}
									if(valid[nmsk])
									{
										nmsk++;
									}
								}
							}
						}
					}
				}
				fclose(fh);
			}
		}

		if(!nmsk)
		{
			nmsk=1;
			valid[0]=1;
		}
		mask=nmsk;
		for(m=0; m<MAX_MASK; m++)
		{
			if(valid[m])
			{
				xxp=xp[m][pmode];
				xxw=xw[m][pmode];				
				yyp=yp[m][pmode];
				yyw=yw[m][pmode];
				tp.lpixel=mc[m].lpixel;
				RenderBox(xxp, yyp, xxp+xxw, yyp+yyw, FILL, &tp);
				if(m==amsk)
					RenderBox(xxp, yyp, xxp+xxw, yyp+yyw, GRID, make_color(LBLUE,&tp));
				for(i=0;i<=yyw;i++)
				{
					j=(yyp+i)*fix_screeninfo.line_length+(xxp<<2);
					if((j+(xxw<<2))<fix_screeninfo.line_length*var_screeninfo.yres)
					{
						memcpy(lfb+j, lbb+j, xxw<<2);
					}
				}
			}
		}
		time(&t1);
		while((rc!=KEY_EXIT) && (rc!=KEY_OK))
		{
			rc=GetRCCode();
			if((rc!=-1) && (rc!=KEY_EXIT) && (rc!=KEY_OK))
			{
				time(&t1);
				move=0;
				xxp=xp[amsk][pmode];
				xxw=xw[amsk][pmode];
				yyp=yp[amsk][pmode];
				yyw=yw[amsk][pmode];
				lpix.lpixel=mc[amsk].lpixel;
				switch(rc)
				{
					case KEY_LEFT:
					if(lc==KEY_LEFT)
					{
						xs+=0.3;
					}
					else
					{
						xs=1.0;
					}
					if(kmode)
					{
						if(xxp>0)
						{
							changed=1;
							xxp-=xs;
						}
					}
					else
					{
						if(xxw>6)
						{
							changed=1;
							xxw-=xs;
						}
					}
					move=1;
					break;
				
					case KEY_RIGHT:
					if((xxp+xxw)<(fix_screeninfo.line_length-1))
					{
						changed=1;
						if(lc==KEY_RIGHT)
						{
							xs+=0.3;
						}
						else
						{
							xs=1.0;
						}
						if(kmode)
						{
							xxp+=xs;
						}
						else
						{
							xxw+=xs;
						}
					}
					move=1;
					break;
				
					case KEY_UP:
					if(lc==KEY_UP)
					{
						ys+=0.2;
					}
					else
					{
						ys=1.0;
					}
					if(kmode)
					{
						if(yyp>0)
						{
							changed=1;
							yyp-=ys;
						}
					}
					else
					{
						if(yyw>6)
						{
							changed=1;
							yyw-=ys;
						}
					}
					move=1;
					break;
				
					case KEY_DOWN:
					if((yyp+yyw)<(var_screeninfo.yres-1))
					{
						changed=1;
						if(lc==KEY_DOWN)
						{
							ys+=0.2;
						}
						else
						{
							ys=1.0;
						}
						if(kmode)
						{
							yyp+=ys;
						}
						else
						{
							yyw+=ys;
						}
					}
					move=1;
					break;
				
					case KEY_RED:
						changed=1;
						RenderBox(xxp, yyp, xxp+xxw, yyp+yyw, FILL, make_color(TRANSP,&tp));
						for(i=0;i<=yyw;i++)
						{
							j=(yyp+i)*fix_screeninfo.line_length+(xxp<<2);
							if(((j+(xxw<<2)))<fix_screeninfo.line_length*var_screeninfo.yres)
							{
								memcpy(lfb+j, lbb+j, xxw<<2);
							}
						}
						valid[amsk]=0;
						nmsk--;
						kmode=1;
						if(nmsk)
						{
							todo=2;
							amsk=-1;
							for(m=0; m<MAX_MASK && amsk<0; m++)
							{
								if(valid[m])
								{
									amsk=m;
									xxp=xp[amsk][pmode];
									xxw=xw[amsk][pmode];
									yyp=yp[amsk][pmode];
									yyw=yw[amsk][pmode];
									lpix.lpixel=mc[amsk].lpixel;
								}
							}	
						}
						else
						{
							todo=mask=0;
						}
					break;
				
					case KEY_GREEN:
						if(nmsk<MAX_MASK)
						{
							todo=2;
							changed=1;
							kmode=1;
							amsk=-1;
							for(m=0; amsk<0 && m<MAX_MASK; m++)
							{
								if(!valid[m])
								{
									amsk=m;
									valid[amsk]=1;
									nmsk++;
									cmc[amsk]=BLACK;
									make_color(BLACK, &mc[amsk]);
									for(i=0; i<8; i++)
									{
										xp[amsk][i]=(1280-40)/2;
										xw[amsk][i]=40;
										yp[amsk][i]=(720-20)/2;
										yw[amsk][i]=20;
									}
									xxp=xp[amsk][pmode];
									xxw=xw[amsk][pmode];
									yyp=yp[amsk][pmode];
									yyw=yw[amsk][pmode];
									lpix.lpixel=mc[amsk].lpixel;
								}
							}
						}	
					break;
					
					case KEY_PAGEUP:
						if(nmsk>1)
						{
							m=amsk+1;
							if(m>=MAX_MASK)
							{
								m=0;
							}
							while(!valid[m])
							{
								if(++m>=MAX_MASK)
								{
									m=0;
								}
							}
							RenderBox(xxp, yyp, xxp+xxw, yyp+yyw, FILL, &lpix);
							amsk=m;
							xxp=xp[amsk][pmode];
							xxw=xw[amsk][pmode];
							yyp=yp[amsk][pmode];
							yyw=yw[amsk][pmode];
							lpix.lpixel=mc[amsk].lpixel;
						}
					break;
				
					case KEY_PAGEDOWN:
						if(nmsk>1)
						{
							m=amsk-1;
							if(m<0)
							{
								m=MAX_MASK-1;
							}
							while(!valid[m])
							{
								if(--m<0)
								{
									m=MAX_MASK;
								}
							}
							RenderBox(xxp, yyp, xxp+xxw, yyp+yyw, FILL, &lpix);
							amsk=m;
							xxp=xp[amsk][pmode];
							xxw=xw[amsk][pmode];
							yyp=yp[amsk][pmode];
							yyw=yw[amsk][pmode];
							lpix.lpixel=mc[amsk].lpixel;
						}
					break;

					case KEY_YELLOW:
						kmode=0;
					break;
				
					case KEY_BLUE:
						kmode=1;
					break;
					
					case KEY_1:
						if(nmsk)
						{
							if(mc[amsk].cpixel.rd < 0xF0)
								mc[amsk].cpixel.rd+=0x10;
							else
								mc[amsk].cpixel.rd=0xFF;
							changed=1;
						}
					break;

					case KEY_4:
						if(nmsk)
						{
							mc[amsk].cpixel.rd=0x80;
							changed=1;
						}
					break;

					case KEY_7:
						if(nmsk)
						{
							if(mc[amsk].cpixel.rd > 0x0F)
								mc[amsk].cpixel.rd-=0x10;
							else
								mc[amsk].cpixel.rd=0x00;
							changed=1;
						}
					break;

					case KEY_2:
						if(nmsk)
						{
							if(mc[amsk].cpixel.gn < 0xF0)
								mc[amsk].cpixel.gn+=0x10;
							else
								mc[amsk].cpixel.gn=0xFF;
							changed=1;
						}
					break;

					case KEY_5:
						if(nmsk)
						{
							mc[amsk].cpixel.gn=0x80;
							changed=1;
						}
					break;

					case KEY_8:
						if(nmsk)
						{
							if(mc[amsk].cpixel.gn > 0x0F)
								mc[amsk].cpixel.gn-=0x10;
							else
								mc[amsk].cpixel.gn=0x00;
							changed=1;
						}
					break;

					case KEY_3:
						if(nmsk)
						{
							if(mc[amsk].cpixel.bl < 0xF0)
								mc[amsk].cpixel.bl+=0x10;
							else
								mc[amsk].cpixel.bl=0xFF;
							changed=1;
						}
					break;

					case KEY_6:
						if(nmsk)
						{
							mc[amsk].cpixel.bl=0x80;
							changed=1;
						}
					break;

					case KEY_9:
						if(nmsk)
						{
							if(mc[amsk].cpixel.bl > 0x0F)
								mc[amsk].cpixel.bl-=0x10;
							else
								mc[amsk].cpixel.bl=0x00;
							changed=1;
						}
					break;

					case KEY_VOLUMEDOWN:
						if(nmsk)
						{
							if(mc[amsk].cpixel.tr < 0xF8)
								mc[amsk].cpixel.tr+=0x08;
							else
								mc[amsk].cpixel.tr=0xFF;
							changed=1;
						}
					break;

					case KEY_VOLUMEUP:
						if(nmsk)
						{
							if(mc[amsk].cpixel.tr > 0x08)
								mc[amsk].cpixel.tr-=0x08;
							else
								mc[amsk].cpixel.tr=0x00;
							changed=1;
						}
					break;

					case KEY_MUTE:
						if(nmsk)
						{
							if(++cmc[amsk]>LTURQUOISE)
								cmc[amsk]=BLACK;
							make_color(cmc[amsk], &mc[amsk]);
							changed=1;
						}
					break;

					case KEY_HELP:
						help_changed=1;
					break;
				}
				lc=rc;
				lpix.lpixel=mc[amsk].lpixel;
				if(mask || todo==2)
				{
					RenderBox(xp[amsk][pmode], yp[amsk][pmode], xp[amsk][pmode]+xw[amsk][pmode], yp[amsk][pmode]+yw[amsk][pmode], FILL, make_color(TRANSP, &tp));
					for(i=0;i<=yw[amsk][pmode];i++)
					{
						j=(yp[amsk][pmode]+i)*fix_screeninfo.line_length+(xp[amsk][pmode]<<2);
						if((j+(xw[amsk][pmode]<<2))<fix_screeninfo.line_length*var_screeninfo.yres)
						{
							memcpy(lfb+j, lbb+j, (xw[amsk][pmode]+1)<<2);
						}
					}
					xp[amsk][pmode]=xxp;
					xw[amsk][pmode]=xxw;
					yp[amsk][pmode]=yyp;
					yw[amsk][pmode]=yyw;
					for(m=0; mask && m<MAX_MASK; m++)
					{
						if(valid[m])
						{
							xxp=xp[m][pmode];
							xxw=xw[m][pmode];
							yyp=yp[m][pmode];
							yyw=yw[m][pmode];
							tp.lpixel=mc[m].lpixel;
							RenderBox(xxp, yyp, xxp+xxw, yyp+yyw, FILL, ((m==amsk) && move)?make_color(TRANSP, &tp):&tp);
							if(m==amsk)
								RenderBox(xxp, yyp, xxp+xxw, yyp+yyw, GRID, make_color((kmode)?LBLUE:LYELLOW,&tp));
							for(i=0;i<=yyw;i++)
							{
								j=(yyp+i)*fix_screeninfo.line_length+(xxp<<2);
								if((j+(xxw<<2))<fix_screeninfo.line_length*var_screeninfo.yres)
								{
									memcpy(lfb+j, lbb+j, (xxw+1)<<2);
								}
							}
						}
					}
				}
			}
			time(&t2);
			if((t2-t1)>1)
			{
				xs=1.0;
				ys=1.0;
				tsy=120;
				if(move)
				{
					RenderBox(xp[amsk][pmode], yp[amsk][pmode], xp[amsk][pmode]+xw[amsk][pmode], yp[amsk][pmode]+yw[amsk][pmode], FILL, &mc[amsk]);
					RenderBox(xp[amsk][pmode], yp[amsk][pmode], xp[amsk][pmode]+xw[amsk][pmode], yp[amsk][pmode]+yw[amsk][pmode], GRID, make_color((kmode)?LBLUE:LYELLOW,&tp));
				}
				move=0;
				if(help_changed)
				{
					help^=1;
				}
				if(help)
				{
					RenderBox(tsx,tsy,tsx+txw,tsy+21*tdy,FILL,make_color(TRANSP, &tp));
					if(nmsk)
						RenderBox(xp[amsk][pmode], yp[amsk][pmode], xp[amsk][pmode]+xw[amsk][pmode], yp[amsk][pmode]+yw[amsk][pmode], GRID, make_color((kmode)?LBLUE:LYELLOW, &tp));
					RenderString("Maskensteuerung", tsx, tsy+=tdy, txw, LEFT, tsz, tcol);
					RenderString("Blau  :  Umschalten auf Positionseinstellung", tsx, tsy+=tdy, txw, LEFT, tsz, tcol);
					RenderString("Gelb  :  Umschalten auf Größeneinstellung", tsx, tsy+=tdy, txw, LEFT, tsz, tcol);
					RenderString("Grün  :  Maske hinzufügen", tsx, tsy+=tdy, txw, LEFT, tsz, tcol);
					RenderString("Rot    :  Maske löschen", tsx, tsy+=tdy, txw, LEFT, tsz, tcol);
					RenderString("PgUp :  nächste Maske auswählen", tsx, tsy+=tdy, txw, LEFT, tsz, tcol);
					RenderString("PgDn :  vorherige Maske auswählen", tsx, tsy+=tdy, txw, LEFT, tsz, tcol);
					RenderString("Maskenfarbe", tsx, tsy+=(2*tdy), txw, LEFT, tsz, tcol);
					RenderString("Mute  :  Maskenfarbe aus Vorgabe auswählen", tsx, tsy+=tdy, txw, LEFT, tsz, tcol);
					RenderString("1,4,7   :  Farbton Rot erhöhen, auf Mitte setzen, verringern", tsx, tsy+=tdy, txw, LEFT, tsz, tcol);
					RenderString("2,5,8  :  Farbton Grün erhöhen, auf Mitte setzen, verringern", tsx, tsy+=tdy, txw, LEFT, tsz, tcol);
					RenderString("3,6,9  :  Farbton Blau erhöhen, auf Mitte setzen, verringern", tsx, tsy+=tdy, txw, LEFT, tsz, tcol);
					RenderString("Vol +  :  Transparenz erhöhen", tsx, tsy+=tdy, txw, LEFT, tsz, tcol);
					RenderString("Vol -  :  Transparenz verringern", tsx, tsy+=tdy, txw, LEFT, tsz, tcol);
					RenderString("Allgemein", tsx, tsy+=(2*tdy), txw, LEFT, tsz, tcol);
					RenderString("?        :  Hilfetext ein/ausschalten", tsx, tsy+=tdy, txw, LEFT, tsz, tcol);
					RenderString("Exit    :  Abbrechen", tsx, tsy+=tdy, txw, LEFT, tsz, tcol);
					RenderString("OK     :  Speichern und Beenden", tsx, tsy+=tdy, txw, LEFT, tsz, tcol);
				}
				else
				{
					if(help_changed)
					{
						RenderBox(tsx, tsy, tsx+txw, tsy+21*tdy, FILL, make_color(TRANSP, &tp));
						if(nmsk)
							RenderBox(xp[amsk][pmode], yp[amsk][pmode], xp[amsk][pmode]+xw[amsk][pmode], yp[amsk][pmode]+yw[amsk][pmode], GRID, make_color((kmode)?LBLUE:LYELLOW, &tp));
					}
				}
				help_changed=0;
				memcpy(lfb, lbb, fix_screeninfo.line_length*var_screeninfo.yres);
			}
		}
		if(rc==KEY_EXIT)
		{
			changed=0;
			todo=0;
		}
		if(rc==KEY_OK && changed)
		{
			if((fh2=fopen("/tmp/logomask.conf","w"))!=NULL)
			{
				fh=fopen(CFG_FILE,"r");
				while(fh && fgets(tstr, BUFSIZE, fh))
				{
					TrimString(tstr);
					if(strlen(tstr))
					{
						if(strstr(tstr,actchan)==NULL)
						{
							fprintf(fh2,"%s\n",tstr);
						}
					}
				}
				if(fh)
				{
					fclose(fh);
				}
				if(todo)
				{
					fprintf(fh2,"%s",actchan);
					for(j=0; j<MAX_MASK; j++)
					{
						if(valid[j])
						{
							for(i=0; i<8; i++)
							{
								fprintf(fh2,",%d,%d,%d,%d",xp[j][i],xw[j][i],yp[j][i],yw[j][i]);
							}
						}
					}
					for(j=0; j<MAX_MASK; j++)
					{
						if(valid[j])
						{
							fprintf(fh2,",MC%08X",mc[j].lpixel);
						}
					}
					fprintf(fh2,",\n");
				}
				fclose(fh2);
				remove(CFG_FILE);
				system("mv /tmp/logomask.conf /var/tuxbox/config/logomask.conf");
			}
		}		
		free(lbb);
		munmap(lfb, fix_screeninfo.smem_len);

		close(fb);
		CloseRC();
		remove("/tmp/.logomask_kill");
		remove("/tmp/logomaskset.*");
		system("logomask &");
		return 0;
}
Пример #11
0
/*****************************************************************************
 * Create: allocates osd-text video thread output method
 *****************************************************************************
 * This function allocates and initializes a Clone vout method.
 *****************************************************************************/
static int Create( vlc_object_t *p_this )
{
    filter_t *p_filter = (filter_t *)p_this;
    filter_sys_t *p_sys;
    char *psz_fontfile = NULL;
    int i, i_error;
    int i_fontsize = 0;
    vlc_value_t val;

    /* Allocate structure */
    p_sys = malloc( sizeof( filter_sys_t ) );
    if( !p_sys )
    {
        msg_Err( p_filter, "out of memory" );
        return VLC_ENOMEM;
    }
    p_sys->p_face = 0;
    p_sys->p_library = 0;

    for( i = 0; i < 256; i++ )
    {
        p_sys->pi_gamma[i] = (uint8_t)( pow( (double)i * 255.0f, 0.5f ) );
    }

    var_Create( p_filter, "freetype-font",
                VLC_VAR_STRING | VLC_VAR_DOINHERIT );
    var_Create( p_filter, "freetype-fontsize",
                VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
    var_Create( p_filter, "freetype-rel-fontsize",
                VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );

    /* Look what method was requested */
    var_Get( p_filter, "freetype-font", &val );
    psz_fontfile = val.psz_string;
    if( !psz_fontfile || !*psz_fontfile )
    {
        if( psz_fontfile ) free( psz_fontfile );
        psz_fontfile = (char *)malloc( PATH_MAX + 1 );
#ifdef WIN32
        GetWindowsDirectory( psz_fontfile, PATH_MAX + 1 );
        strcat( psz_fontfile, "\\fonts\\arial.ttf" );
#elif SYS_DARWIN
        strcpy( psz_fontfile, DEFAULT_FONT );
#else
        msg_Err( p_filter, "user didn't specify a font" );
        goto error;
#endif
    }

    i_error = FT_Init_FreeType( &p_sys->p_library );
    if( i_error )
    {
        msg_Err( p_filter, "couldn't initialize freetype" );
        goto error;
    }

    i_error = FT_New_Face( p_sys->p_library, psz_fontfile ? psz_fontfile : "",
                           0, &p_sys->p_face );
    if( i_error == FT_Err_Unknown_File_Format )
    {
        msg_Err( p_filter, "file %s have unknown format", psz_fontfile );
        goto error;
    }
    else if( i_error )
    {
        msg_Err( p_filter, "failed to load font file %s", psz_fontfile );
        goto error;
    }

    i_error = FT_Select_Charmap( p_sys->p_face, ft_encoding_unicode );
    if( i_error )
    {
        msg_Err( p_filter, "Font has no unicode translation table" );
        goto error;
    }

    p_sys->i_use_kerning = FT_HAS_KERNING( p_sys->p_face );

    var_Get( p_filter, "freetype-fontsize", &val );
    if( val.i_int )
    {
        i_fontsize = val.i_int;
    }
    else
    {
        var_Get( p_filter, "freetype-rel-fontsize", &val );
        i_fontsize = (int)p_filter->fmt_out.video.i_height / val.i_int;
    }
    if( i_fontsize <= 0 )
    {
        msg_Warn( p_filter, "Invalid fontsize, using 12" );
        i_fontsize = 12;
    }
    msg_Dbg( p_filter, "Using fontsize: %i", i_fontsize);

    i_error = FT_Set_Pixel_Sizes( p_sys->p_face, 0, i_fontsize );
    if( i_error )
    {
        msg_Err( p_filter, "couldn't set font size to %d", i_fontsize );
        goto error;
    }

    if( psz_fontfile ) free( psz_fontfile );
    p_filter->pf_render_string = RenderText;
    p_filter->p_sys = p_sys;
    return VLC_SUCCESS;

 error:
    if( p_sys->p_face ) FT_Done_Face( p_sys->p_face );
    if( p_sys->p_library ) FT_Done_FreeType( p_sys->p_library );
    if( psz_fontfile ) free( psz_fontfile );
    free( p_sys );
    return VLC_EGENERIC;
}
Пример #12
0
static void
dump_dependencies(void)
{
#ifdef __GNUC__
  g_print ("Compiler: GCC " __VERSION__ "\n");
#elif defined _MSC_VER
  g_print ("Compiler: MSC %d\n", _MSC_VER);
#else
  g_print ("Compiler: unknown\n");
#endif
  /* some flags/defines which may be interesting */
  g_print ("  with : "
#ifdef G_THREADS_ENABLED
  "threads "
#endif
#ifdef HAVE_CAIRO
  "cairo "
#endif
#ifdef HAVE_GNOME
  "gnome "
#endif
#ifdef HAVE_LIBART
  "libart "
#endif
#ifdef HAVE_PANGOCAIRO
  "pangocairo "
#endif
  "\n");

  /* print out all those dependies, both compile and runtime if possible 
   * Note: this is not meant to be complete but does only include libaries 
   * which may or have cause(d) us trouble in some versions 
   */
  g_print ("Library versions (at compile time)\n");
#ifdef HAVE_LIBPNG
  g_print ("libpng  : %s (%s)\n", png_get_header_ver(NULL), PNG_LIBPNG_VER_STRING);
#endif
#ifdef HAVE_FREETYPE
  {
    FT_Library ft_library;
    FT_Int     ft_major_version;
    FT_Int     ft_minor_version;
    FT_Int     ft_micro_version;

    if (FT_Init_FreeType (&ft_library) == 0) {
      FT_Library_Version (ft_library,
                          &ft_major_version,
                          &ft_minor_version,
                          &ft_micro_version);

      g_print ("freetype: %d.%d.%d\n", ft_major_version, ft_minor_version, ft_micro_version);
      FT_Done_FreeType (ft_library);
    }
    else
      g_print ("freetype: ?.?.?\n");
  }
#endif
  {
    const gchar* libxml_rt_version = "?";
#if 0
    /* this is stupid, does not compile on Linux:
     * app_procs.c:504: error: expected identifier before '(' token
     *
     * In fact libxml2 has different ABI for LIBXML_THREAD_ENABLED, this code only compiles without
     * threads enabled, but apparently it does only work when theay are.
     */
    xmlInitParser();
    if (xmlGetGlobalState())
      libxml_rt_version = xmlGetGlobalState()->xmlParserVersion;
#endif
    libxml_rt_version = xmlParserVersion;
    if (atoi(libxml_rt_version))
      g_print ("libxml  : %d.%d.%d (%s)\n", 
               atoi(libxml_rt_version) / 10000, atoi(libxml_rt_version) / 100 % 100, atoi(libxml_rt_version) % 100,
	       LIBXML_DOTTED_VERSION);
    else /* may include "extra" */
      g_print ("libxml  : %s (%s)\n", libxml_rt_version ? libxml_rt_version : "??", LIBXML_DOTTED_VERSION);
  }
  g_print ("glib    : %d.%d.%d (%d.%d.%d)\n", 
           glib_major_version, glib_minor_version, glib_micro_version,
           GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION, GLIB_MICRO_VERSION);
#ifdef PANGO_VERSION_ENCODE
  g_print ("pango   : %s (%d.%d.%d)\n", pango_version_string(), PANGO_VERSION_MAJOR, PANGO_VERSION_MINOR, PANGO_VERSION_MICRO);
#else
  g_print ("pango   : version not available (>= 1.14.x)\n"); /* Pango did not provide such */
#endif
#if HAVE_CAIRO
#  ifdef CAIRO_VERSION_STRING
  g_print ("cairo   : %s (%s)\n", cairo_version_string(), CAIRO_VERSION_STRING);
#  else
  g_print ("cairo   : %s (%d.%d.%d)\n", cairo_version_string(), CAIRO_VERSION_MAJOR, CAIRO_VERSION_MINOR, CAIRO_VERSION_MICRO);
#  endif
#endif
#if 0
  {
    gchar  linkedname[1024];
    gint   len = 0;

    /* relying on PREFIX is wrong */
    if ((len = readlink (PREFIX "/lib/libpango-1.0.so", linkedname, 1023)) > 0) {
      /* man 2 readlink : does not append a  NUL  character */
      linkedname[len] = '\0';
      g_print ("%s/%s\n", PREFIX, linkedname);
    }
  }
#endif
  g_print ("gtk+    : %d.%d.%d (%d.%d.%d)\n",
           gtk_major_version, gtk_minor_version, gtk_micro_version,
           GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION);

#if 0
  /* we could read $PREFIX/share/gnome-about/gnome-version.xml 
   * but is it worth the effort ? */
  g_print ("gnome   : %d.%d.%d (%d.%d.%d)\n"
           gnome_major_version, gnome_minor_version, gnome_micro_version,
           GNOME_MAJOR_VERSION, GNOME_MINOR_VERSION, GNOME_MICRO_VERSION);
#endif
}
Пример #13
0
//-----------------------------------------------------------------------------
// Get the list of available font filenames, and load the name for each of
// them. Only that, though, not the glyphs too.
//-----------------------------------------------------------------------------
TtfFontList::TtfFontList() {
    FT_Init_FreeType(&fontLibrary);
}
Пример #14
0
Font::LibraryParameter::LibraryParameter() {
    FT_Error error = FT_Init_FreeType(&library);

    // Throw an exception if the library failed
    //if (error)
}
Пример #15
0
bool Graphics::loadFonts() {
  return (!FT_Init_FreeType(&_fontLibrary) &&
          loadFont(FONT_FACE_REGULAR, _fontFace, &_fontBuffer) &&
          loadFont(FONT_FACE_BOLD, _fontFaceB, &_fontBufferB));
}
Пример #16
0
int
main(int argc, char **argv)
{
    FT_Error error;
    FT_Library library;
    FT_Face face;
    GFile *file;
    gchar *font_file, *title;
    gint row;
    GtkWidget *window, *hbox, *table, *swin, *drawing_area;
    GdkColor white = { 0, 0xffff, 0xffff, 0xffff };
    GtkWidget *button, *align;

    bindtextdomain(GETTEXT_PACKAGE, MATELOCALEDIR);
    bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
    textdomain(GETTEXT_PACKAGE);

    gtk_init(&argc, &argv);

    if (argc != 2) {
	g_printerr(_("usage: %s fontfile\n"), argv[0]);
	return 1;
    }

    if (!XftInitFtLibrary()) {
	g_printerr("could not initialise freetype library\n");
	return 1;
    }

    error = FT_Init_FreeType(&library);
    if (error) {
	g_printerr("could not initialise freetype\n");
	return 1;
    }

    file = g_file_new_for_commandline_arg (argv[1]);
    font_file = g_file_get_uri (file);
    g_object_unref (file);

    if (!font_file) {
	g_printerr("could not parse argument into a URI\n");
	return 1;
    }

    error = FT_New_Face_From_URI(library, font_file, 0, &face);
    if (error) {
	g_printerr("could not load face '%s'\n", font_file);
	return 1;
    }

    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    title = g_strconcat(face->family_name,
			face->style_name ? ", " : "",
			face->style_name, NULL);
    gtk_window_set_title(GTK_WINDOW(window), title);
    set_icon(GTK_WINDOW(window), font_file);
    g_free(title);
    gtk_window_set_resizable(GTK_WINDOW(window), TRUE);

    hbox = gtk_hbox_new(FALSE, 0);
    gtk_container_add(GTK_CONTAINER(window), hbox);

    swin = gtk_scrolled_window_new(NULL, NULL);
    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swin),
				   GTK_POLICY_AUTOMATIC, GTK_POLICY_NEVER);
    gtk_box_pack_start(GTK_BOX(hbox), swin, TRUE, TRUE, 0);

    drawing_area = gtk_drawing_area_new();
    gtk_widget_modify_bg(drawing_area, GTK_STATE_NORMAL, &white);
    gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(swin),
					  drawing_area);
#if !GTK_CHECK_VERSION (3, 0, 0)
    g_signal_connect (drawing_area, "realize", G_CALLBACK(create_text_pixmap), face);
#endif

    /* set the minimum size on the scrolled window to prevent
     * unnecessary scrolling */
    gtk_widget_set_size_request(swin, 500, -1);

    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);

    table = gtk_table_new(1, 2, FALSE);
    gtk_container_set_border_width(GTK_CONTAINER(table), 5);
    gtk_box_pack_start(GTK_BOX(hbox), table, FALSE, TRUE, 0);

    row = 0;
    add_face_info(table, &row, font_file, face);

    /* add install button */
    align = gtk_alignment_new (1.0, 0.5, 0.0, 0.0);
    gtk_table_attach (GTK_TABLE (table), align, 0, 2, row, row + 1,
                      GTK_FILL|GTK_EXPAND, GTK_FILL, 0, 0);

    button = gtk_button_new_with_mnemonic (_("I_nstall Font"));
    g_signal_connect (button, "clicked",
                      G_CALLBACK (install_button_clicked_cb), font_file);
    gtk_container_add (GTK_CONTAINER (align), button);


    gtk_table_set_col_spacings(GTK_TABLE(table), 8);
    gtk_table_set_row_spacings(GTK_TABLE(table), 2);
    gtk_widget_show_all(window);

    gtk_main();
    return 0;
}
Пример #17
0
Error DynamicFontAtSize::_load() {


	int error = FT_Init_FreeType( &library );

	ERR_EXPLAIN(TTR("Error initializing FreeType."));
	ERR_FAIL_COND_V( error !=0, ERR_CANT_CREATE );

	if (font->font_path!=String()) {

		FileAccess *f=FileAccess::open(font->font_path,FileAccess::READ);
		ERR_FAIL_COND_V(!f,ERR_CANT_OPEN);

		memset(&stream,0,sizeof(FT_StreamRec));
		stream.base=NULL;
		stream.size=f->get_len();
		stream.pos=0;
		stream.descriptor.pointer=f;
		stream.read=_ft_stream_io;
		stream.close=_ft_stream_close;

		FT_Open_Args fargs;
		memset(&fargs,0,sizeof(FT_Open_Args));
		fargs.flags=FT_OPEN_STREAM;
		fargs.stream=&stream;
		error = FT_Open_Face( library,&fargs,0,&face);
	} else if (font->font_mem) {

		memset(&stream,0,sizeof(FT_StreamRec));
		stream.base=(unsigned char*)font->font_mem;
		stream.size=font->font_mem_size;
		stream.pos=0;

		FT_Open_Args fargs;
		memset(&fargs,0,sizeof(FT_Open_Args));
		fargs.memory_base=(unsigned char*)font->font_mem;
		fargs.memory_size=font->font_mem_size;
		fargs.flags= FT_OPEN_MEMORY;
		fargs.stream=&stream;
		error = FT_Open_Face( library,&fargs,0,&face);

	} else {
		ERR_EXPLAIN("DynamicFont uninitialized");
		ERR_FAIL_V(ERR_UNCONFIGURED);
	}

	//error = FT_New_Face( library, src_path.utf8().get_data(),0,&face );

	if ( error == FT_Err_Unknown_File_Format ) {
		ERR_EXPLAIN(TTR("Unknown font format."));
		FT_Done_FreeType( library );

	} else if ( error ) {

		ERR_EXPLAIN(TTR("Error loading font."));
		FT_Done_FreeType( library );

	}

	ERR_FAIL_COND_V(error,ERR_FILE_CANT_OPEN);


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

	if ( error ) {
		FT_Done_FreeType( library );
		ERR_EXPLAIN(TTR("Invalid font size."));
		ERR_FAIL_COND_V( error, ERR_INVALID_PARAMETER );
	}*/

	error = FT_Set_Pixel_Sizes(face,0,size);

	ascent=face->size->metrics.ascender>>6;
	descent=-face->size->metrics.descender>>6;
	linegap=0;

	//print_line("ASCENT: "+itos(ascent)+" descent "+itos(descent)+" hinted: "+itos(face->face_flags&FT_FACE_FLAG_HINTER));

	valid=true;
	return OK;
}
Пример #18
0
/* initialise font handling */
bool fb_font_init(void)
{
        FT_Error error;
        FT_ULong max_cache_size;
        FT_UInt max_faces = 6;
	fb_faceid_t *fb_face;

LOG(("Freetype init..."));

	nsoptions.fb_font_monochrome = false;			
	nsoptions.fb_font_cachesize = 2048;			
	nsoptions.fb_face_sans_serif = NULL;			
	nsoptions.fb_face_sans_serif_bold = NULL;		
	nsoptions.fb_face_sans_serif_italic = NULL;		
	nsoptions.fb_face_sans_serif_italic_bold = NULL;		
	nsoptions.fb_face_serif = NULL;				
	nsoptions.fb_face_serif_bold = NULL;			
	nsoptions.fb_face_monospace = NULL;			
	nsoptions.fb_face_monospace_bold = NULL;			
	nsoptions.fb_face_cursive = NULL;			
	nsoptions.fb_face_fantasy = NULL;		


        /* freetype library initialise */
        error = FT_Init_FreeType( &library ); 
        if (error) {
                LOG(("Freetype could not initialised (code %d)\n", error));
                return false;
        }

        /* set the Glyph cache size up */
        max_cache_size = nsoption_int(fb_font_cachesize) * 1024; 

	if (max_cache_size < CACHE_MIN_SIZE) {
		max_cache_size = CACHE_MIN_SIZE;
	}

LOG(("Freetype cache..."));
DBG("Ft cache\n");
        /* cache manager initialise */
        error = FTC_Manager_New(library, 
                                max_faces, 
                                0, 
                                max_cache_size, 
                                ft_face_requester, 
                                NULL, 
                                &ft_cmanager);
        if (error) {
                LOG(("Freetype could not initialise cache manager (code %d)\n", error));
                FT_Done_FreeType(library);
                return false;
        }


LOG(("Freetype map cache..."));
DBG("Ft map cache\n");
        error = FTC_CMapCache_New(ft_cmanager, &ft_cmap_cache);

        error = FTC_ImageCache_New(ft_cmanager, &ft_image_cache);

	/* need to obtain the generic font faces */


LOG(("Freetype load fonts..."));
DBG("Ft load fonts\n");

	/* Start with the sans serif font */
	fb_face = fb_new_face(nsoption_charp(fb_face_sans_serif),
			      "sans_serif.ttf",
			      NETSURF_FB_FONT_SANS_SERIF);
	if (fb_face == NULL) {
		
LOG(("Freetype load fonts failed due SANS unavailable :(..."));
DBG("Ft Z:(((\n");
		/* The sans serif font is the default and must be found. */
                LOG(("Could not find the default font\n"));
                FTC_Manager_Done(ft_cmanager);
                FT_Done_FreeType(library);
                return false;
        } else {
		fb_faces[FB_FACE_SANS_SERIF] = fb_face;
	}

LOG(("Freetype loaded sans.."));
DBG("Ft sans loaded:)\n");

	/* Bold sans serif face */
	fb_face = fb_new_face(nsoption_charp(fb_face_sans_serif_bold),
                            "sans_serif_bold.ttf",
                            NETSURF_FB_FONT_SANS_SERIF_BOLD);
	if (fb_face == NULL) {
		/* seperate bold face unavailabe use the normal weight version */
		fb_faces[FB_FACE_SANS_SERIF_BOLD] = fb_faces[FB_FACE_SANS_SERIF];
	} else {
		fb_faces[FB_FACE_SANS_SERIF_BOLD] = fb_face;
	}

	/* Italic sans serif face */
	fb_face = fb_new_face(nsoption_charp(fb_face_sans_serif_italic),
			      "sans_serif_italic.ttf",
			      NETSURF_FB_FONT_SANS_SERIF_ITALIC);
	if (fb_face == NULL) {
		/* seperate italic face unavailabe use the normal weight version */
		fb_faces[FB_FACE_SANS_SERIF_ITALIC] = fb_faces[FB_FACE_SANS_SERIF];
	} else {
		fb_faces[FB_FACE_SANS_SERIF_ITALIC] = fb_face;
	}

	/* Bold italic sans serif face */
	fb_face = fb_new_face(nsoption_charp(fb_face_sans_serif_italic_bold), 
			      "sans_serif_italic_bold.ttf",
			      NETSURF_FB_FONT_SANS_SERIF_ITALIC_BOLD);
	if (fb_face == NULL) {
		/* seperate italic face unavailabe use the normal weight version */
		fb_faces[FB_FACE_SANS_SERIF_ITALIC_BOLD] = fb_faces[FB_FACE_SANS_SERIF];
	} else {
		fb_faces[FB_FACE_SANS_SERIF_ITALIC_BOLD] = fb_face;
	}

	/* serif face */
	fb_face = fb_new_face(nsoption_charp(fb_face_serif),
                            "serif.ttf",
			      NETSURF_FB_FONT_SERIF);
	if (fb_face == NULL) {
		/* serif face unavailabe use the default */
		fb_faces[FB_FACE_SERIF] = fb_faces[FB_FACE_SANS_SERIF];
	} else {
		fb_faces[FB_FACE_SERIF] = fb_face;
	}

	/* bold serif face*/
	fb_face = fb_new_face(nsoption_charp(fb_face_serif_bold),
			      "serif_bold.ttf",
			      NETSURF_FB_FONT_SERIF_BOLD);
	if (fb_face == NULL) {
		/* bold serif face unavailabe use the normal weight */
		fb_faces[FB_FACE_SERIF_BOLD] = fb_faces[FB_FACE_SERIF];
	} else {
		fb_faces[FB_FACE_SERIF_BOLD] = fb_face;
	}


	/* monospace face */
	fb_face = fb_new_face(nsoption_charp(fb_face_monospace),
			      "monospace.ttf",
			      NETSURF_FB_FONT_MONOSPACE);
	if (fb_face == NULL) {
		/* serif face unavailabe use the default */
		fb_faces[FB_FACE_MONOSPACE] = fb_faces[FB_FACE_SANS_SERIF];
	} else {
		fb_faces[FB_FACE_MONOSPACE] = fb_face;
	}

	/* bold monospace face*/
	fb_face = fb_new_face(nsoption_charp(fb_face_monospace_bold),
			      "monospace_bold.ttf",
			      NETSURF_FB_FONT_MONOSPACE_BOLD);
	if (fb_face == NULL) {
		/* bold serif face unavailabe use the normal weight */
		fb_faces[FB_FACE_MONOSPACE_BOLD] = fb_faces[FB_FACE_MONOSPACE];
	} else {
		fb_faces[FB_FACE_MONOSPACE_BOLD] = fb_face;
	}

	/* cursive face */
	fb_face = fb_new_face(nsoption_charp(fb_face_cursive),
			      "cursive.ttf",
			      NETSURF_FB_FONT_CURSIVE);
	if (fb_face == NULL) {
		/* cursive face unavailabe use the default */
		fb_faces[FB_FACE_CURSIVE] = fb_faces[FB_FACE_SANS_SERIF];
	} else {
		fb_faces[FB_FACE_CURSIVE] = fb_face;
	}

	/* fantasy face */
	fb_face = fb_new_face(nsoption_charp(fb_face_fantasy),
			      "fantasy.ttf",
			      NETSURF_FB_FONT_FANTASY);
	if (fb_face == NULL) {
		/* fantasy face unavailabe use the default */
		fb_faces[FB_FACE_FANTASY] = fb_faces[FB_FACE_SANS_SERIF];
	} else {
		fb_faces[FB_FACE_FANTASY] = fb_face;
	}

LOG(("Freetype fonts ready..."));
DBG("Ft ready :)\n");
        
        /* set the default render mode */
        if (nsoption_bool(fb_font_monochrome) == true)
                ft_load_type = FT_LOAD_MONOCHROME; /* faster but less pretty */
        else
                ft_load_type = 0;
        
        return true;
}
Пример #19
0
// ------------------------------------------------------------- load_glyph ---
texture_glyph_t *
load_glyph( const char *  filename,     const wchar_t 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, 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
    distance_map( 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 = 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;
}
Пример #20
0
/**
* Init and load font
**/
OpenGLFont::OpenGLFont(RenderOpenGL* render, string name, Mod* mod, float size)
{
	int error;

	// Basics
	this->pmpl = new OpenGLFont_Implementation();
	this->render = render;
	this->size = size;

	// Init freetype
	// TODO: Should we share the tf ptr between OpenGLFont instances
	error = FT_Init_FreeType(&this->pmpl->ft);
	if (error) {
		reportFatalError("Freetype: Unable to init library.");
	}

	// On Linux, the system font is found using fontconfig
	#if defined(__linux__)
		FcConfig* config = FcInitLoadConfigAndFonts();

		FcPattern* pat = FcPatternBuild(
			NULL,
			FC_FAMILY, FcTypeString, reinterpret_cast<const char*>(name.c_str()),
			NULL
		);
		FcConfigSubstitute(config, pat, FcMatchPattern);
		FcDefaultSubstitute(pat);

		FcResult result;
		FcPattern* font = FcFontMatch(config, pat, &result);
		if (font == NULL) {
			reportFatalError("Fontconfig: Unable to find font " + name);
		}

		FcChar8* filename = NULL;
		if (FcPatternGetString(font, FC_FILE, 0, &filename) != FcResultMatch) {
			reportFatalError("Fontconfig: No filename in fontconfig match");
		}

		error = FT_New_Face(this->pmpl->ft, reinterpret_cast<const char*>(filename), 0, &this->pmpl->face);

		FcPatternDestroy(font);
		FcPatternDestroy(pat);

	#else
		// All other systems use a file in the cr/ mod
		Sint64 len;
		name.append(".ttf");
		this->pmpl->buf = mod->loadBinary(name, &len);
		if (this->pmpl->buf == NULL) {
			reportFatalError("Freetype: Unable to load data");
		}

		error = FT_New_Memory_Face(this->pmpl->ft, (const FT_Byte *) this->pmpl->buf, (FT_Long)len, 0, &this->pmpl->face);
	#endif

	// Handle errors
	if (error == FT_Err_Unknown_File_Format) {
		reportFatalError("Freetype: Unsupported font format");
	} else if (error) {
		reportFatalError("Freetype: Unable to load font");
	}

	// Set character size
	error = FT_Set_Char_Size(this->pmpl->face, 0, size * 64, 72, 72);
	if (error) {
		reportFatalError("Freetype: Unable to load font size");
	}
}
Пример #21
0
bool FT2Font::init()
{
    unsigned err;

    if( ( err = FT_Init_FreeType( &m_lib ) ) )
    {
        msg_Err( getIntf(), "failed to initialize freetype (%s)",
                 ft2_strerror( err ) );
        return false;
    }

    FILE *file = fopen( m_name.c_str(), "rb" );
    if( !file )
    {
        msg_Dbg( getIntf(), "failed to open font %s (%s)",
                 m_name.c_str(), strerror(errno) );
        return false;
    }
    msg_Dbg( getIntf(), "loading font %s", m_name.c_str() );

    fseek( file, 0, SEEK_END );
    long size = ftell( file );
    rewind( file );

    if( -1==size )
    {
        msg_Dbg( getIntf(), "fseek loading font %s (%s)",
                 m_name.c_str(), strerror(errno) );
        fclose( file );
        return false;
    }

    m_buffer = new (std::nothrow) char[size];
    if( !m_buffer )
    {
        fclose( file );
        return false;
    }

    if( fread( m_buffer, size, 1, file ) != 1 )
    {
        msg_Err( getIntf(), "unexpected result for read" );
        fclose( file );
        return false;
    }
    fclose( file );

    err = FT_New_Memory_Face( m_lib, (const FT_Byte*)m_buffer, size, 0,
                              &m_face );
    if ( err == FT_Err_Unknown_File_Format )
    {
        msg_Err( getIntf(), "unsupported font format (%s)", m_name.c_str() );
        return false;
    }
    else if ( err )
    {
        msg_Err( getIntf(), "error opening font %s (%s)",
                 m_name.c_str(), ft2_strerror(err) );
        return false;
    }

    // Select the charset
    if( ( err = FT_Select_Charmap( m_face, ft_encoding_unicode ) ) )
    {
        msg_Err( getIntf(), "font %s has no UNICODE table (%s)",
                 m_name.c_str(), ft2_strerror(err) );
        return false;
    }

    // Set the pixel size
    if( ( err = FT_Set_Pixel_Sizes( m_face, 0, m_size ) ) )
    {
        msg_Warn( getIntf(), "cannot set a pixel size of %d for %s (%s)",
                  m_size, m_name.c_str(), ft2_strerror(err) );
    }

    // Get the font metrucs
    m_height = m_face->size->metrics.height >> 6;
    m_ascender = m_face->size->metrics.ascender >> 6;
    m_descender = m_face->size->metrics.descender >> 6;

    return true;
}
Пример #22
0
FreeTypeLib::FreeTypeLib() {
    FT_Init_FreeType(&lib);
}
Пример #23
0
/**
 * Initialize a new console
 */
Console* new_Console(cairo_t* context, double font_size)
{
  //printf("Console::Console(cairo_t@%p)\n", context);

  Console* self;
  self = malloc(sizeof(Console));
  self->head = null;
  self->tail = null;
  self->cursor = null;
  self->width = default_width;
  self->height = default_height;
  self->pad = 4;
  self->font_filename = "./Monaco_Linux.ttf"; /* TODO */
  self->font_size = font_size;
  self->transparency = 1.0;
  self->antialias_text = false;
  self->antialias_graphics = true;
  
  /* initialize lithp, cairo - and define callbacks */
  self->lithp = new_LithpInterpreter();
  char* cairo_init [] = {
    //"(set 'libcairo             (xl:dlopen \"libcairo.dylib\"))",
    //"(set 'libcairo             (xl:dlopen \"libcairo.so.2\"))",
    //"(set 'libcairo (xl:dlopen \"/Users/antoine/Projects/phlo/install/lib/libcairo.dylib\"))",
#if defined(__linux__)
    "(set 'libcairo             (xl:dlopen \"libcairo.so.2\"))",
#elif defined(__APPLE__) && defined(__MACH__)
    "(set 'libcairo             (xl:dlopen \"libcairo.dylib\"))",
#endif
    "(set 'cairo:set-source-rgb       (xl:dlsym libcairo \"cairo_set_source_rgb\"))",
    "(set 'cairo:rectangle            (xl:dlsym libcairo \"cairo_rectangle\"))",
    "(set 'cairo:fill                 (xl:dlsym libcairo \"cairo_fill\"))",
    "(set 'cairo:translate            (xl:dlsym libcairo \"cairo_translate\"))",
    "(set 'cairo:rotate               (xl:dlsym libcairo \"cairo_rotate\"))",
    "(set 'cairo:move-to              (xl:dlsym libcairo \"cairo_move_to\"))",
    "(set 'cairo:set-source-rgba      (xl:dlsym libcairo \"cairo_set_source_rgba\"))",
    "(set 'console:width 492)",
    "(set 'console:height 344)",
    "(set 'pi 3.141592)",

    "(set 'pretty '(lambda (cr arc theta)                      "
    "  (cond ((lte arc 0.0) 0.0)                               "
    "        ('t (progn                                        "
    "              (cairo:rotate cr theta)                     "
    "              (cairo:rectangle cr 20.0 20.0 140.0 20.0)    "
    "              (cairo:fill cr)                             "
    "              (pretty cr (sub arc theta) theta))))))      ",

    "(set 'console:expose-event '(lambda (context)             "
    "  (cairo:set-source-rgb  context 0.5 0.5 1.0)         "
    "  (cairo:translate context (div console:width 2.0) (div console:height 2.0))"
    "  (pretty context (mul pi 2.0) (div pi 4.0))))",
    //"(set 'console:expose-event '(lambda (context) ()))",
    null
  };
  for (size_t t = 0; cairo_init[t] != null; t++) {
    Expression* callback = Expression_parse_utf8(cairo_init[t], null, &self->lithp->symbol_list); 
    _gc_protect(callback);
    Expression_eval(callback, self->lithp->environment);
    _gc_unprotect(callback);
  }


  /* initialize and configure console font */
  FT_Library  library;
  int error = FT_Init_FreeType(&library);
  if (error) { perror("Could not open FreeType library"); exit(EXIT_FAILURE); }
  self->font_face = malloc(sizeof(FT_Face*));
  error = FT_New_Face(library, self->font_filename, 0, self->font_face);
  if (error) { perror("Could not open font"); exit(EXIT_FAILURE); }
  cairo_set_font_face(context, cairo_ft_font_face_create_for_ft_face(*self->font_face, 0));
  cairo_set_font_size(context, self->font_size);
  cairo_font_options_t* font_options = cairo_font_options_create();
  cairo_get_font_options(context, font_options);
  if (self->antialias_text) {
    cairo_font_options_set_antialias(font_options, CAIRO_ANTIALIAS_NONE);
  }
  cairo_set_font_options(context, font_options);
  self->font_extents = malloc(sizeof(cairo_font_extents_t));
  cairo_font_extents(context, self->font_extents);

  /* some sample text */
  //wchar_t* test_text = L"ABCDEFGHIJKLM\nNOPQRSTUVWXYZ\nabcdefghijklm\nnopqrstuvwxyz\n1234567890\0";
  wchar_t* test_text = L"  \n  ";
  unsigned int n;
  for (n = 0; n < wcslen(test_text); n++) {
    //  Console_append(self, test_text[n]);
    Console_insert(self, test_text[n]);
  }
  self->cursor = self->head;

  return self;
}
Пример #24
0
int
main( int     argc,
      char**  argv )
{
  FT_Library    library;
  FT_Face       face;

  FT_GlyphSlot  slot;
  FT_Matrix     matrix;                 /* transformation matrix */
  FT_Vector     pen;                    /* untransformed origin  */
  FT_Error      error;

  char*         filename;
//  char*         text;

  double        angle;
  int           target_height;
  int           n, num_chars;

  wchar_t *chinese_str = L"ол╣Щ1g";
  unsigned int *p = (unsigned int *)chinese_str;
  int i;

  printf("Uniocde: \n");
  for (i = 0; i < wcslen(chinese_str); i++)
  {
  	printf("0x%x ", p[i]);
  }
  printf("\n");
//  return 0;


  if ( argc != 2 )
  {
    fprintf ( stderr, "usage: %s font\n", argv[0] );
    exit( 1 );
  }

  filename      = argv[1];                           /* first argument     */
//  text          = argv[2];                           /* second argument    */
  num_chars     = wcslen(chinese_str);
  angle         = ( 0.0 / 360 ) * 3.14159 * 2;      /* use 0 degrees     */
  target_height = HEIGHT;

  error = FT_Init_FreeType( &library );              /* initialize library */
  /* error handling omitted */

  error = FT_New_Face( library, argv[1], 0, &face ); /* create face object */
  /* error handling omitted */

  /* use 20pt at 100dpi */
  error = FT_Set_Char_Size( face, 20 * 64, 0,
                            100, 0 );                /* set character size */
  /* error handling omitted */

  slot = face->glyph;

  /* set up matrix */
  matrix.xx = (FT_Fixed)( cos( angle ) * 0x10000L );
  matrix.xy = (FT_Fixed)(-sin( angle ) * 0x10000L );
  matrix.yx = (FT_Fixed)( sin( angle ) * 0x10000L );
  matrix.yy = (FT_Fixed)( cos( angle ) * 0x10000L );

  /* the pen position in 26.6 cartesian space coordinates; */
  /* start at (0,40) relative to the upper left corner  */
  pen.x = 0 * 64;
  pen.y = ( target_height - 40 ) * 64;

  for ( n = 0; n < num_chars; n++ )
  {
    /* set transformation */
    FT_Set_Transform( face, &matrix, &pen );

    /* load glyph image into the slot (erase previous one) */
    error = FT_Load_Char( face, chinese_str[n], FT_LOAD_RENDER );
    if ( error )
      continue;                 /* ignore errors */

    /* now, draw to our target surface (convert position) */
    draw_bitmap( &slot->bitmap,
                 slot->bitmap_left,
                 target_height - slot->bitmap_top );

    /* increment pen position */
    pen.x += slot->advance.x;
    pen.y += slot->advance.y;
  }

  show_image();

  FT_Done_Face    ( face );
  FT_Done_FreeType( library );

  return 0;
}
void DemoEntityManager::CreateOpenGlFont()
{
	FT_Library  library;
	FT_Error error = FT_Init_FreeType (&library);
	if ( !error )
	{
		char fileName[2048];
		//GetWorkingFileName ("arial.ttf", fileName);
		//GetWorkingFileName ("calibri.ttf", fileName);
		GetWorkingFileName ("courbd.ttf", fileName);
				

		FT_Face face[96];   
		int withInPixels = 12;
		int heightInPixels = 16;

		int width = 0;
		int height = 0;
		for (int ch = 0; ch < 96; ch ++) {
			// Load The Glyph For Our Character.
			error = FT_New_Face( library, fileName, 0, &face[ch] );
			dAssert (!error);

			FT_Face bitmap = face[ch];   

			error = FT_Set_Char_Size(bitmap, withInPixels * 64, heightInPixels * 64, 96, 96);
			dAssert (!error);

			FT_UInt index = FT_Get_Char_Index( face[ch], ch + ' ');
			//FT_UInt index = FT_Get_Char_Index (bitmap, 'A');

			error = FT_Load_Glyph (bitmap, index, FT_LOAD_DEFAULT );
			dAssert (!error);

			error = FT_Render_Glyph (bitmap->glyph, FT_RENDER_MODE_NORMAL); 
			dAssert (!error);

			const FT_Glyph_Metrics& metrics = bitmap->glyph->metrics;
			int w = metrics.width / 64;
			int h = metrics.height / 64;

			width += w;
			height = (height > h) ? height : h;
		}

		int imageWidth = TwosPower (width);
		int imageHeight = TwosPower (height);

		char* const image = new char[2 * imageWidth * imageHeight];
		memset (image, 0, 2 * imageWidth * imageHeight);

		int maxWidth = 0;
		int imageBase = 0;
		
		for (int ch = 0; ch < 96; ch ++) {
			FT_Face bitmap = face[ch];   
			FT_GlyphSlot slot = bitmap->glyph;

			const FT_Glyph_Metrics& metrics = slot->metrics;
			int w = metrics.width / 64;
			int h = metrics.height / 64;

			maxWidth = (w > maxWidth) ? w : maxWidth;
			if (w) {
				const unsigned char* const buffer = slot->bitmap.buffer;
				int pitch =  slot->bitmap.pitch;

				int posit = imageBase;
				for (int j = 0; j < h; j ++) {
					for (int i = 0; i < w; i ++) {
						int color = buffer[j * pitch + i];
						image[posit + i * 2 + 0] = color;
						image[posit + i * 2 + 1] = color;
					}
					posit += imageWidth * 2;
				}
				imageBase += w * 2;
			}
		}

		// make th open gl display list here
	    m_fontImage = LoadImage("fontTexture", image, imageWidth, imageHeight, m_luminace);

		m_font = glGenLists(96);
		glBindTexture(GL_TEXTURE_2D, m_fontImage);

		imageBase = 0;
		for (int ch = 0; ch < 96; ch ++) {
			FT_Face bitmap = face[ch];   
			FT_GlyphSlot slot = bitmap->glyph;
			const FT_Glyph_Metrics& metrics = slot->metrics;

			glNewList(m_font + ch, GL_COMPILE);
			glPushMatrix();
//			glTranslatef(slot->bitmap_left, 64 - slot->bitmap_top, 0);
			glTranslatef(slot->bitmap_left, - slot->bitmap_top, 0);

			dFloat w = dFloat (metrics.width / 64);
			dFloat h = dFloat (metrics.height / 64);

			if (w) {
				dFloat u0 = dFloat (imageBase) / imageWidth;
				dFloat u1 = dFloat (imageBase + w - 1.0f) / imageWidth;

				dFloat v0 = 0.0f;
				dFloat v1 = (h - 1.0f) / imageHeight;

				glBegin(GL_QUADS);

				glTexCoord2d (u0, v0); 
				glVertex2i(0, 0);

				glTexCoord2d (u0, v1); 
				glVertex2i(0, h - 1);

				glTexCoord2d (u1, v1); 
				glVertex2i (w - 1, h - 1);

				glTexCoord2d (u1, v0); 
				glVertex2i (w - 1, 0);
				glEnd();

				imageBase += w;
			}
			glPopMatrix();
			
			//glTranslatef(maxWidth, 0, 0);
			glTranslatef(metrics.horiAdvance / 64, 0, 0);

			glEndList();
			FT_Done_Face(bitmap);
		}

		delete[] image; 

		// destroy the free type library	
		FT_Done_FreeType (library);
	}
}
Пример #26
0
//------------------------------------------------------------------
void ofTrueTypeFont::loadFont(string filename, int fontsize, bool _bAntiAliased, bool _bFullCharacterSet, bool makeContours, float simplifyAmt){

	bMakeContours = makeContours;

	//------------------------------------------------
	if (bLoadedOk == true){

		// we've already been loaded, try to clean up :
		unloadTextures();
	}
	//------------------------------------------------


	filename = ofToDataPath(filename);

	bLoadedOk 			= false;
	bAntiAlised 		= _bAntiAliased;
	bFullCharacterSet 	= _bFullCharacterSet;
	fontSize			= fontsize;

	//--------------- load the library and typeface
	FT_Library library;
	if (FT_Init_FreeType( &library )){
		ofLog(OF_LOG_ERROR," PROBLEM WITH FT lib");
		return;
	}

	FT_Face face;
	if (FT_New_Face( library, filename.c_str(), 0, &face )) {
		return;
	}

	FT_Set_Char_Size( face, fontsize << 6, fontsize << 6, 96, 96);
	lineHeight = fontsize * 1.43f;

	//------------------------------------------------------
	//kerning would be great to support:
	//ofLog(OF_LOG_NOTICE,"FT_HAS_KERNING ? %i", FT_HAS_KERNING(face));
	//------------------------------------------------------

	nCharacters = bFullCharacterSet ? 256 : 128 - NUM_CHARACTER_TO_START;

	//--------------- initialize character info and textures
	cps.resize(nCharacters);

	if(bMakeContours){
		charOutlines.clear();
		charOutlines.assign(nCharacters, ofTTFCharacter());
	}

	vector<ofPixels> expanded_data(nCharacters);

	long areaSum=0;

	//--------------------- load each char -----------------------
	for (int i = 0 ; i < nCharacters; i++){

		//------------------------------------------ anti aliased or not:
		if(FT_Load_Glyph( face, FT_Get_Char_Index( face, (unsigned char)(i+NUM_CHARACTER_TO_START) ), FT_LOAD_DEFAULT )){
			ofLog(OF_LOG_ERROR,"error with FT_Load_Glyph %i", i);
		}

		if (bAntiAlised == true) FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL);
		else FT_Render_Glyph(face->glyph, FT_RENDER_MODE_MONO);

		//------------------------------------------
		FT_Bitmap& bitmap= face->glyph->bitmap;


		// prepare the texture:
		/*int width  = ofNextPow2( bitmap.width + border*2 );
		int height = ofNextPow2( bitmap.rows  + border*2 );


		// ------------------------- this is fixing a bug with small type
		// ------------------------- appearantly, opengl has trouble with
		// ------------------------- width or height textures of 1, so we
		// ------------------------- we just set it to 2...
		if (width == 1) width = 2;
		if (height == 1) height = 2;*/


		if(bMakeContours){
			if( printVectorInfo )printf("\n\ncharacter %c: \n", char( i+NUM_CHARACTER_TO_START ) );

			//int character = i + NUM_CHARACTER_TO_START;
			charOutlines[i] = makeContoursForCharacter( face );
			if(simplifyAmt>0)
				charOutlines[i].simplify(simplifyAmt);
			charOutlines[i].getTessellation();
		}


		// -------------------------
		// info about the character:
		cps[i].character		= i;
		cps[i].height 			= face->glyph->bitmap_top;
		cps[i].width 			= face->glyph->bitmap.width;
		cps[i].setWidth 		= face->glyph->advance.x >> 6;
		cps[i].topExtent 		= face->glyph->bitmap.rows;
		cps[i].leftExtent		= face->glyph->bitmap_left;

		int width  = cps[i].width;
		int height = bitmap.rows;


		cps[i].tW				= width;
		cps[i].tH				= height;



		GLint fheight	= cps[i].height;
		GLint bwidth	= cps[i].width;
		GLint top		= cps[i].topExtent - cps[i].height;
		GLint lextent	= cps[i].leftExtent;

		GLfloat	corr, stretch;

		//this accounts for the fact that we are showing 2*visibleBorder extra pixels
		//so we make the size of each char that many pixels bigger
		stretch = 0;//(float)(visibleBorder * 2);

		corr	= (float)(( (fontSize - fheight) + top) - fontSize);

		cps[i].x1		= lextent + bwidth + stretch;
		cps[i].y1		= fheight + corr + stretch;
		cps[i].x2		= (float) lextent;
		cps[i].y2		= -top + corr;


		// Allocate Memory For The Texture Data.
		expanded_data[i].allocate(width, height, 2);
		//-------------------------------- clear data:
		expanded_data[i].set(0,255); // every luminance pixel = 255
		expanded_data[i].set(1,0);


		if (bAntiAlised == true){
			ofPixels bitmapPixels;
			bitmapPixels.setFromExternalPixels(bitmap.buffer,bitmap.width,bitmap.rows,1);
			expanded_data[i].setChannel(1,bitmapPixels);
		} else {
			//-----------------------------------
			// true type packs monochrome info in a
			// 1-bit format, hella funky
			// here we unpack it:
			unsigned char *src =  bitmap.buffer;
			for(int j=0; j <bitmap.rows;j++) {
				unsigned char b=0;
				unsigned char *bptr =  src;
				for(int k=0; k < bitmap.width ; k++){
					expanded_data[i][2*(k+j*width)] = 255;

					if (k%8==0){
						b = (*bptr++);
					}

					expanded_data[i][2*(k+j*width) + 1] = b&0x80 ? 255 : 0;
					b <<= 1;
				}
				src += bitmap.pitch;
			}
			//-----------------------------------
		}

		areaSum += (cps[i].width+border*2)*(cps[i].height+border*2);
	}


	vector<charProps> sortedCopy = cps;
	sort(sortedCopy.begin(),sortedCopy.end(),&compare_cps);

	// pack in a texture, algorithm to calculate min w/h from
	// http://upcommons.upc.edu/pfc/bitstream/2099.1/7720/1/TesiMasterJonas.pdf
	//cout << areaSum << endl;

	bool packed = false;
	float alpha = logf(areaSum)*1.44269;

	int w;
	int h;
	while(!packed){
		w = pow(2,floor((alpha/2.f) + 0.5)); // there doesn't seem to be a round in cmath for windows.
		//w = pow(2,round(alpha/2.f));
		h = w;//pow(2,round(alpha - round(alpha/2.f)));
		int x=0;
		int y=0;
		int maxRowHeight = sortedCopy[0].tH + border*2;
		for(int i=0;i<(int)cps.size();i++){
			if(x+sortedCopy[i].tW + border*2>w){
				x = 0;
				y += maxRowHeight;
				maxRowHeight = sortedCopy[i].tH + border*2;
				if(y + maxRowHeight > h){
					alpha++;
					break;
				}
			}
			x+= sortedCopy[i].tW + border*2;
			if(i==(int)cps.size()-1) packed = true;
		}

	}



	ofPixels atlasPixels;
	atlasPixels.allocate(w,h,2);
	atlasPixels.set(0,255);
	atlasPixels.set(1,0);


	int x=0;
	int y=0;
	int maxRowHeight = sortedCopy[0].tH + border*2;
	for(int i=0;i<(int)cps.size();i++){
		ofPixels & charPixels = expanded_data[sortedCopy[i].character];

		if(x+sortedCopy[i].tW + border*2>w){
			x = 0;
			y += maxRowHeight;
			maxRowHeight = sortedCopy[i].tH + border*2;
		}

		cps[sortedCopy[i].character].t2		= float(x + border)/float(w);
		cps[sortedCopy[i].character].v2		= float(y + border)/float(h);
		cps[sortedCopy[i].character].t1		= float(cps[sortedCopy[i].character].tW + x + border)/float(w);
		cps[sortedCopy[i].character].v1		= float(cps[sortedCopy[i].character].tH + y + border)/float(h);
		charPixels.pasteInto(atlasPixels,x+border,y+border);
		x+= sortedCopy[i].tW + border*2;
	}


	texAtlas.allocate(atlasPixels.getWidth(),atlasPixels.getHeight(),GL_LUMINANCE_ALPHA,false);

	if(bAntiAlised && fontsize>14){
		texAtlas.setTextureMinMagFilter(GL_LINEAR,GL_LINEAR);
	}else{
		texAtlas.setTextureMinMagFilter(GL_NEAREST,GL_NEAREST);
	}

	texAtlas.loadData(atlasPixels.getPixels(),atlasPixels.getWidth(),atlasPixels.getHeight(),GL_LUMINANCE_ALPHA);

	// ------------- close the library and typeface
	FT_Done_Face(face);
	FT_Done_FreeType(library);
  	bLoadedOk = true;
}
Пример #27
0
int main(int argc, char** argv) {
	FT_Error error;
	FT_Library library;
	FT_Face face;
	FT_Glyph_Metrics* m;
	FT_Outline* o;
	FT_Int major, minor, patch;
	int i, j, font_size, no_hinting;

	if (argc != 4) {
		usage(argv);
		return 1;
	}
	font_size = atoi(argv[1]);
	if (font_size <= 0) {
		fprintf(stderr, "invalid font_size\n");
		usage(argv);
		return 1;
	}
	if (!strcmp(argv[3], "with_hinting")) {
		no_hinting = 0;
	} else if (!strcmp(argv[3], "sans_hinting")) {
		no_hinting = 1;
	} else {
		fprintf(stderr, "neither \"with_hinting\" nor \"sans_hinting\"\n");
		usage(argv);
		return 1;
	};
	error = FT_Init_FreeType(&library);
	if (error) {
		fprintf(stderr, "FT_Init_FreeType: error #%d\n", error);
		return 1;
	}
	FT_Library_Version(library, &major, &minor, &patch);
	printf("freetype version %d.%d.%d\n", major, minor, patch);
	error = FT_New_Face(library, argv[2], 0, &face);
	if (error) {
		fprintf(stderr, "FT_New_Face: error #%d\n", error);
		return 1;
	}
	error = FT_Set_Char_Size(face, 0, font_size*64, 0, 0);
	if (error) {
		fprintf(stderr, "FT_Set_Char_Size: error #%d\n", error);
		return 1;
	}
	for (i = 0; i < face->num_glyphs; i++) {
		error = FT_Load_Glyph(face, i, no_hinting ? FT_LOAD_NO_HINTING : FT_LOAD_DEFAULT);
		if (error) {
			fprintf(stderr, "FT_Load_Glyph: glyph %d: error #%d\n", i, error);
			return 1;
		}
		if (face->glyph->format != FT_GLYPH_FORMAT_OUTLINE) {
			fprintf(stderr, "glyph format for glyph %d is not FT_GLYPH_FORMAT_OUTLINE\n", i);
			return 1;
		}
		m = &face->glyph->metrics;
		/* Print what Go calls the AdvanceWidth, and then: XMin, YMin, XMax, YMax. */
		printf("%ld %ld %ld %ld %ld;",
				m->horiAdvance,
				m->horiBearingX,
				m->horiBearingY - m->height,
				m->horiBearingX + m->width,
				m->horiBearingY);
		/* Print the glyph points. */
		o = &face->glyph->outline;
		for (j = 0; j < o->n_points; j++) {
			if (j != 0) {
				printf(", ");
			}
			printf("%ld %ld %d", o->points[j].x, o->points[j].y, o->tags[j] & 0x01);
		}
		printf("\n");
	}
	return 0;
}
Пример #28
0
/* ------------------------------------------------------------------------- */
int
texture_font_load_face( FT_Library * library,
                        const char * filename,
                        const float size,
                        FT_Face * face )
{
    size_t hres = 64;
    FT_Error error;
    FT_Matrix matrix = { (int)((1.0/hres) * 0x10000L),
                         (int)((0.0)      * 0x10000L),
                         (int)((0.0)      * 0x10000L),
                         (int)((1.0)      * 0x10000L) };

    /* Initialize library */
    error = FT_Init_FreeType( library );
    if( error )
    {
        fprintf(stderr, "FT_Error (0x%02x) : %s\n",
                FT_Errors[error].code, FT_Errors[error].message);
        return 0;
    }

    /* Load face */
    error = FT_New_Face( *library, filename, 0, face );
    if( error )
    {
        fprintf(stderr, "FT_Error (line %d, code 0x%02x) : %s\n",
                __LINE__, FT_Errors[error].code, FT_Errors[error].message);
        FT_Done_FreeType( *library );
        return 0;
    }

    /* Select charmap */
    error = FT_Select_Charmap( *face, FT_ENCODING_UNICODE );
    if( error )
    {
        fprintf(stderr, "FT_Error (line %d, code 0x%02x) : %s\n",
                __LINE__, FT_Errors[error].code, FT_Errors[error].message);
        FT_Done_Face( *face );
        FT_Done_FreeType( *library );
        return 0;
    }

    /* Set char size */
    error = FT_Set_Char_Size( *face, (int)(size*64), 0, 72*hres, 72 );

    /* error = FT_Set_Char_Size( *face, size*64, 0, 72, 72 ); */
    if( error )
    {
        fprintf(stderr, "FT_Error (line %d, code 0x%02x) : %s\n",
                __LINE__, FT_Errors[error].code, FT_Errors[error].message);
        FT_Done_Face( *face );
        FT_Done_FreeType( *library );
        return 0;
    }

    /* Set transform matrix */
    FT_Set_Transform( *face, &matrix, NULL );

    return 1;
}
Пример #29
0
void
font_init() {
    if (FT_Init_FreeType(&library)) {
        printf("font init failed");
    }
}
Пример #30
0
void
XeTeXFontInst::initialize(const char* pathname, int index, int &status)
{
    TT_Postscript *postTable;
    TT_OS2* os2Table;
    FT_Error error;
    hb_face_t *hbFace;

    if (!gFreeTypeLibrary) {
        error = FT_Init_FreeType(&gFreeTypeLibrary);
        if (error) {
            fprintf(stderr, "FreeType initialization failed! (%d)\n", error);
            exit(1);
        }
    }

    error = FT_New_Face(gFreeTypeLibrary, pathname, index, &m_ftFace);
    if (error) {
        status = 1;
        return;
    }

    if (!FT_IS_SCALABLE(m_ftFace)) {
        status = 1;
        return;
    }

    /* for non-sfnt-packaged fonts (presumably Type 1), see if there is an AFM file we can attach */
    if (index == 0 && !FT_IS_SFNT(m_ftFace)) {
        char* afm = xstrdup (xbasename (pathname));
        char* p = strrchr (afm, '.');
        if (p != NULL && strlen(p) == 4 && tolower(*(p+1)) == 'p' &&
            tolower(*(p+2)) == 'f')
            strcpy(p, ".afm");
        char *fullafm = kpse_find_file (afm, kpse_afm_format, 0);
        free (afm);
        if (fullafm) {
            FT_Attach_File(m_ftFace, fullafm);
            free (fullafm);
        }
    }

    m_filename = xstrdup(pathname);
    m_index = index;
    m_unitsPerEM = m_ftFace->units_per_EM;
    m_ascent = unitsToPoints(m_ftFace->ascender);
    m_descent = unitsToPoints(m_ftFace->descender);

    postTable = (TT_Postscript *) getFontTable(ft_sfnt_post);
    if (postTable != NULL) {
        m_italicAngle = Fix2D(postTable->italicAngle);
    }

    os2Table = (TT_OS2*) getFontTable(ft_sfnt_os2);
    if (os2Table) {
        m_capHeight = unitsToPoints(os2Table->sCapHeight);
        m_xHeight = unitsToPoints(os2Table->sxHeight);
    }

    // Set up HarfBuzz font
    hbFace = hb_face_create_for_tables(_get_table, m_ftFace, NULL);
    hb_face_set_index(hbFace, index);
    hb_face_set_upem(hbFace, m_unitsPerEM);
    m_hbFont = hb_font_create(hbFace);
    hb_face_destroy(hbFace);

    if (hbFontFuncs == NULL)
        hbFontFuncs = _get_font_funcs();

    hb_font_set_funcs(m_hbFont, hbFontFuncs, m_ftFace, NULL);
    hb_font_set_scale(m_hbFont, m_unitsPerEM, m_unitsPerEM);
    // We don’t want device tables adjustments
    hb_font_set_ppem(m_hbFont, 0, 0);

    return;
}