⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 font.c

📁 flash swf file player
💻 C
📖 第 1 页 / 共 2 页
字号:
/*		Ming, an SWF output library		Copyright (C) 2002	Opaque Industries - http://www.opaque.net/		This library is free software; you can redistribute it and/or		modify it under the terms of the GNU Lesser General Public		License as published by the Free Software Foundation; either		version 2.1 of the License, or (at your option) any later version.		This library is distributed in the hope that it will be useful,		but WITHOUT ANY WARRANTY; without even the implied warranty of		MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	See the GNU		Lesser General Public License for more details.		You should have received a copy of the GNU Lesser General Public		License along with this library; if not, write to the Free Software		Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA	02111-1307	USA*//* $Id: font.c,v 1.28 2003/12/14 11:48:01 whamann Exp $ */#include <math.h>#include <stdio.h>#include <string.h>#include <stdlib.h>#include "font.h"#include "method.h"#include "utf8.h"#include "character.h"#include "error.h"#include "movie.h"// #define HAS_MMAP 1#ifdef HAS_MMAP	#include <unistd.h>	#include <sys/mman.h>#endifstruct kernInfo{	byte code1;	byte code2;	short adjustment;};struct kernInfo16{	unsigned short code1;	unsigned short code2;	short adjustment;};struct textList{	struct textList* next;	SWFTextRecord text;};struct SWFFontCharacter_s{	struct SWFCharacter_s character;	SWFFont font;	byte flags;	// list of text records that reference this font	struct textList* textList;	struct textList* currentList;	// list of chars used in text objects that reference this font-	// idx into this table is stored in text records	int nGlyphs;	unsigned short* codeTable;};#define glyphLength(font,glyph) \	((font)->glyphOffset[(glyph)+1] - (font)->glyphOffset[(glyph)])static voidSWFFontCharacter_resolveTextCodes(SWFFontCharacter font);intcompleteSWFFontCharacter(SWFBlock block){	SWFFontCharacter inst = (SWFFontCharacter)block;	SWFFont font = inst->font;	int size = 0;	int i, nbits;	// get charcodes from text records, translate into local code map	SWFFontCharacter_resolveTextCodes(inst);	size += 2; // character id	size += 2; // flags	size += 1; // name length	size += strlen((const char*)font->name); // font name	size += 2; // nglyphs	size += 2 * (inst->nGlyphs + 1); // offset table	/* get length of each glyph from its output buffer */	for ( i=0; i<inst->nGlyphs; ++i )		size += glyphLength(font, inst->codeTable[i]);	if ( font->flags & SWF_FONT_WIDECODES )		size += 2 * inst->nGlyphs;	else		size += inst->nGlyphs;	if ( size > 65500 )	{		size += 2 * (inst->nGlyphs+1);		inst->flags |= SWF_FONT_WIDEOFFSETS;	}	if( inst->flags & SWF_FONT_HASLAYOUT )	{			size += 8;	// ascent, descent, leading, 0 kern pairs		size += 2 * inst->nGlyphs;	// width table		for(i = 0 ; i < inst->nGlyphs ; i++)		{			nbits = SWFRect_numBits(font->bounds + inst->codeTable[i]);			size += (nbits+7) >> 3;		}	}	return size;}voidwriteSWFFontCharacterToMethod(SWFBlock block,															SWFByteOutputMethod method, void *data){	SWFFontCharacter inst = (SWFFontCharacter)block;	SWFFont font = inst->font;	SWFOutput bounds;	int offset, i;	byte *p, *s;	methodWriteUInt16(CHARACTERID(inst), method, data);	method(inst->flags, data); /* main flags */	method(0, data);																					/* more flags */	method((unsigned char)strlen((const char*)font->name), data);	for ( p = font->name; *p != '\0'; ++p )		method(*p, data);	methodWriteUInt16(inst->nGlyphs, method, data);	offset = (inst->nGlyphs+1) * (inst->flags & SWF_FONT_WIDEOFFSETS ? 4 : 2);	/* write offset table for glyphs */	for ( i=0; i<=inst->nGlyphs; ++i )	{		if ( inst->flags & SWF_FONT_WIDEOFFSETS )			methodWriteUInt32(offset, method, data);		else			methodWriteUInt16(offset, method, data);		if ( i < inst->nGlyphs )			offset += glyphLength(font, inst->codeTable[i]);	}	/* write shape records for glyphs */	for ( i=0; i<inst->nGlyphs; ++i )	{		p = font->glyphOffset[inst->codeTable[i]];		s = font->glyphOffset[inst->codeTable[i]+1];		SWF_assert(p < s);		while(p < s)			method(*(p++), data);	}		/* write glyph to code map */	if ( inst->flags & SWF_FONT_WIDECODES )	{		for ( i=0; i<inst->nGlyphs; ++i )			methodWriteUInt16(font->glyphToCode[inst->codeTable[i]], method, data);	}	else	{		for ( i=0; i<inst->nGlyphs; ++i )			method((byte)font->glyphToCode[inst->codeTable[i]], data);	}	/* write font layout */	if (inst->flags & SWF_FONT_HASLAYOUT )	{	methodWriteUInt16(font->ascent, method, data);		methodWriteUInt16(font->descent, method, data);		methodWriteUInt16(font->leading, method, data);		for ( i=0; i<inst->nGlyphs; ++i )			methodWriteUInt16(font->advances[inst->codeTable[i]], method, data);		bounds = newSWFOutput();		for ( i=0; i<inst->nGlyphs; ++i )		{	SWFOutput_writeRect(bounds, font->bounds + inst->codeTable[i]);			SWFOutput_byteAlign(bounds);		}		SWFOutput_writeToMethod(bounds, method, data);		destroySWFOutput(bounds);		methodWriteUInt16(0, method, data);		/* no kerning */	}			}voiddestroySWFFont(SWFFont font){	if ( font->shapes != NULL )	{#if HAS_MMAP		// XXX - if mmap failed, we malloced this!		int len = font->glyphOffset[font->nGlyphs] - font->glyphOffset[0];		munmap(font->shapes, len);#else		free(font->shapes);#endif	}	if ( font->flags & SWF_FONT_WIDECODES )	{		if ( font->codeToGlyph.wideMap != NULL )		{			int i;			for ( i = 0; i < 256; ++i )			{				if ( font->codeToGlyph.wideMap[i] != NULL )					free(font->codeToGlyph.wideMap[i]);			}			free(font->codeToGlyph.wideMap);		}	}	else	{		if ( font->codeToGlyph.charMap != NULL )			free(font->codeToGlyph.charMap);	}	if ( font->bounds != NULL )		free(font->bounds);	if ( font->name != NULL )		free(font->name);	if ( font->kernTable.k != NULL )	// union of pointers ...		free(font->kernTable.k);	if ( font->glyphOffset != NULL )		free(font->glyphOffset);	if ( font->glyphToCode != NULL )		free(font->glyphToCode);	if ( font->advances != NULL )		free(font->advances);	free(font);}voiddestroySWFFontCharacter(SWFFontCharacter font){	struct textList* text = font->textList;	while ( text != NULL )	{		struct textList* next = text->next;		free(text);		text = next;	}	if ( font->codeTable != NULL )		free(font->codeTable);	free(font);}SWFFontnewSWFFont(){	SWFFont font = (SWFFont) malloc(sizeof(struct SWFFont_s));	SWFBlockInit((SWFBlock)font);	BLOCK(font)->type = SWF_UNUSEDBLOCK;	BLOCK(font)->writeBlock = NULL;	BLOCK(font)->complete = NULL;	BLOCK(font)->dtor = (destroySWFBlockMethod) destroySWFFont;	font->name = NULL;	font->flags = 0;	font->nGlyphs = 0;	font->glyphToCode = NULL;	font->codeToGlyph.charMap = NULL;	font->glyphOffset = NULL;	font->advances = NULL;	font->bounds = NULL;	font->ascent = 0;	font->descent = 0;	font->leading = 0;	font->kernCount = 0;	font->kernTable.k = NULL;	font->shapes = NULL;	return font;}SWFFontCharacternewSWFFontCharacter(SWFFont font){	SWFFontCharacter inst = (SWFFontCharacter) malloc(sizeof(struct SWFFontCharacter_s));	SWFCharacterInit((SWFCharacter)inst);	BLOCK(inst)->type = SWF_DEFINEFONT2;	BLOCK(inst)->writeBlock = writeSWFFontCharacterToMethod;	BLOCK(inst)->complete = completeSWFFontCharacter;	BLOCK(inst)->dtor = (destroySWFBlockMethod) destroySWFFontCharacter;	CHARACTERID(inst) = ++SWF_gNumCharacters;	inst->font = font;	inst->flags = (unsigned char)(font->flags & /*(~SWF_FONT_HASLAYOUT) &*/ (~SWF_FONT_WIDEOFFSETS));	inst->nGlyphs = 0;	inst->codeTable = NULL;	inst->textList = NULL;	inst->currentList = NULL;	return inst;}SWFFontCharacternewSWFDummyFontCharacter(){	SWFFontCharacter ret = (SWFFontCharacter) malloc(sizeof (struct SWFFontCharacter_s));	SWFCharacterInit((SWFCharacter) ret);	BLOCK(ret)->type = SWF_DEFINEFONT;	BLOCK(ret)->complete = completeSWFImportCharacter;	BLOCK(ret)->writeBlock = NULL;	BLOCK(ret)->dtor = NULL;	CHARACTERID(ret) = ++SWF_gNumCharacters;		ret->flags = SWF_FONT_HASLAYOUT;	ret->nGlyphs = 1;	ret->codeTable = NULL;		return ret;}	static voidSWFFont_buildReverseMapping(SWFFont font){	int i;	if ( font->flags & SWF_FONT_WIDECODES )	{		font->codeToGlyph.wideMap = (unsigned short**)malloc(256 * sizeof(unsigned short*));		for ( i=0; i<256; ++i )			font->codeToGlyph.wideMap[i] = NULL;		for ( i=0; i<font->nGlyphs; ++i )		{			unsigned short charcode = font->glyphToCode[i];			byte high = charcode >> 8;			byte low = charcode & 0xff;			if ( font->codeToGlyph.wideMap[high] == NULL )			{				font->codeToGlyph.wideMap[high] = (unsigned short*)malloc(256 * sizeof(unsigned short));				memset(font->codeToGlyph.wideMap[high], 0, 256 * sizeof(unsigned short));			}			font->codeToGlyph.wideMap[high][low] = i;		}	}	else	{		font->codeToGlyph.charMap = (byte*) malloc(256 * sizeof(char));		memset(font->codeToGlyph.charMap, 0, 256 * sizeof(char));		for ( i=0; i<font->nGlyphs; ++i )			font->codeToGlyph.charMap[font->glyphToCode[i]] = i;	}}static intSWFFont_findGlyphCode(SWFFont font, unsigned short c){	if ( font->flags & SWF_FONT_WIDECODES )	{		byte high = c >> 8;		byte low = c & 0xff;		if ( font->codeToGlyph.wideMap[high] != NULL )			return font->codeToGlyph.wideMap[high][low];		else			return -1;	}	else	{		if ( (c & 0xff00) == 0 )			return font->codeToGlyph.charMap[(byte)c];		else			return -1;	}}byte*SWFFont_findGlyph(SWFFont font, unsigned short c){	int code = SWFFont_findGlyphCode(font, c);	if ( code >= 0 )		return font->glyphOffset[code];	return NULL;}voidSWFFontCharacter_addTextToList(SWFFontCharacter font, SWFTextRecord text){	struct textList* textList = (struct textList* )malloc(sizeof(struct textList));	textList->next = font->textList;	textList->text = text;	font->textList = textList;}static intfindCodeValue(unsigned short c, unsigned short* list, int start, int end){	int pos;	if ( start == end )		return start;	if ( c <= list[start] )		return start;	pos = (start + end) / 2;	if ( c < list[pos] )		return findCodeValue(c, list, start, pos);	else if ( c > list[pos] )		return findCodeValue(c, list, pos+1, end);	else		return pos;}#define CODETABLE_INCREMENT 32voidSWFFontCharacter_addCharToTable(SWFFontCharacter font, unsigned short c){	// insert the char into font's codeTable if it isn't already there	int p;	p = findCodeValue(c, font->codeTable, 0, font->nGlyphs);	if ( font->codeTable != NULL && font->codeTable[p] == c )		return;	if ( font->nGlyphs % CODETABLE_INCREMENT == 0 )	{		font->codeTable = (unsigned short*) realloc(font->codeTable,															(font->nGlyphs + CODETABLE_INCREMENT) *															sizeof(unsigned short));	}	// keep list sorted	if ( p < font->nGlyphs )	{		memmove(&font->codeTable[p + 1], &font->codeTable[p],						(font->nGlyphs - p) * sizeof(*font->codeTable));	}	font->codeTable[p] = c;	++font->nGlyphs;}voidSWFFontCharacter_addWideChars(SWFFontCharacter font, unsigned short *string, int len){	while(--len >= 0)		SWFFontCharacter_addCharToTable(font, *string++);}voidSWFFontCharacter_addUTF8Chars(SWFFontCharacter font, const char *string){	unsigned short *widestring;	int len;	len = UTF8ExpandString(string, &widestring);	SWFFontCharacter_addWideChars(font, widestring, len);	free(widestring);}voidSWFFontCharacter_addChars(SWFFontCharacter font, const char *string){	while(*string)		SWFFontCharacter_addCharToTable(font, *string++ & 0xff);}SWFFontSWFFontCharacter_getFont(SWFFontCharacter font){	return font->font;}voidSWFFontCharacter_exportCharacterRange(SWFFontCharacter font,						 unsigned short start, unsigned short end){	// insert the char into font's codeTable if it isn't already there	//int p = findCodeValue(start, font->codeTable, 0, font->nGlyphs);	//int q = findCodeValue(end, font->codeTable, 0, font->nGlyphs);		// XXX}static intSWFFontCharacter_findCharCode(SWFFontCharacter font, unsigned short c){	// return the index in font->codeTable for the given character	int p = findCodeValue(c, font->codeTable, 0, font->nGlyphs);	if ( font->codeTable[p] == c )		return p;	return -1;}static voidSWFFontCharacter_resolveTextCodes(SWFFontCharacter font){	struct textList* text = font->textList;	unsigned short* string;	int len, i;	// find out which characters from this font are being used	while ( text != NULL )	{		len = SWFTextRecord_getString(text->text, &string);		for ( i=0; i<len; ++i )			SWFFontCharacter_addCharToTable(font, string[i]);		text = text->next;	}	// translate text records' strings into lists of font char codes	text = font->textList;	while ( text != NULL )	{		len = SWFTextRecord_getString(text->text, &string);		for ( i=0; i<len; ++i )		{			int code = SWFFontCharacter_findCharCode(font, string[i]);			if ( code >= 0 )				string[i] = (unsigned short)code;			// XXX - else?		}		text = text->next;	}	// translate codeTable's char codes into glyph codes	for ( i=0; i<font->nGlyphs; ++i )	{		// XXX - if font doesn't have the character?		font->codeTable[i] = SWFFont_findGlyphCode(font->font, font->codeTable[i]);	}}const char*SWFFont_getName(SWFFont font){	return (const char*) font->name;}byteSWFFont_getFlags(SWFFont font){	return font->flags;}intSWFFontCharacter_getNGlyphs(SWFFontCharacter font){	return font->nGlyphs;}intSWFFont_getScaledWideStringWidth(SWFFont font,														 const unsigned short* string, int len){	/* return length of given string in whatever units these are we're using */	int i, j;	int width = 0;	int glyph, glyph2;	for ( i=0; i<len; ++i )	{		glyph = SWFFont_findGlyphCode(font, string[i]);		if ( glyph == -1 )			continue; // XXX - ???		if ( font->advances )			width += font->advances[glyph];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -