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

📄 flashfontobj.cpp

📁 这是一个用VC++开发的flashsource端的程序
💻 CPP
字号:
//////////////////////////////////////////////////////////////////////
//
// FlashFontObj.cpp: implementation of the CFlashFontObj class.
//
//////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

#include <windows.h>
#include <math.h>
//#include <hash_map>

#include "ffont.h"
#include "fsprite.h"
#include "fdisplay.h"
#include "ConvertGlyph.h"
#include "FlashFontObj.h"

#include <string>

// underline and strikeout line height TWIPS
#define ULSO		50

// undeline and strikeout extent past the char TWIPS
#define ULSO_OFFSET	100

// The base tells us how big to create a font.  For FLASH the font EM square is 1024 x 1024
#define FONT_BASE	1024	// was 1300

#define EM_SQUARE_SIZE 1024
#define EM_RATIO 0.792




/**************************************************************************************************************************/

void CFlashFontObj::ConvertString (const char* text, char** buf)
{
	long len, i, j;

	len = strlen((LPSTR)text) + 1;
	*buf = new char[len];
	memset (*buf, 0, len);

//COMMENTED OUT BY WBT

	for (i=0,j=0; i<len-1; ++i)
	{
//WBT		if (text[i] >= 32 && text[i] <127)
//WBT		{
				(*buf)[j++] = text[i];
/*WBT		}
		else
		{
			switch (text[i])
			{
			case -110:
				(*buf)[j++] = 39;
				break;
			case -109:
			case -108:
				(*buf)[j++] = '"';
				break;
//			case -70:
//				buf[j++] = '';
//				break;
			default:
				(*buf)[j++] = 64;
				break;
			};
		}
*/	}

}



CFlashFontObj::CFlashFontObj()
{
}

CFlashFontObj::~CFlashFontObj()
{
}

short ShortFromFixed(FIXED f)
{
	short ret = f.value;
	if(f.fract > 0x8000) ret+=1;
	return (short)ret;
}


bool CFlashFontObj::GetGlyphShape(const char *font, WORD charindex, FlashShape* s, long* advance, bool internal_ulines)
{
	HDC tmphdc = CreateDC("DISPLAY", NULL, NULL, NULL); 
	HDC hdcScreen = CreateCompatibleDC(tmphdc); 
    SetMapMode(hdcScreen, MM_TEXT);


	int charset = DEFAULT_CHARSET;

	HFONT myfont = CreateFont(-(EM_SQUARE_SIZE * EM_RATIO),0,0,0,m_weight,m_italics ? TRUE : FALSE,m_underline ? TRUE : FALSE,m_strikeout ? TRUE : FALSE,charset,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH,font);	
	HGDIOBJ obj = SelectObject(hdcScreen,myfont);

	OUTLINETEXTMETRIC metric;
	GetOutlineTextMetrics(hdcScreen, sizeof(OUTLINETEXTMETRIC), &metric);
	int ascent = (-metric.otmsUnderscorePosition);

	TTPOLYGONHEADER *lastheader = NULL;

	unsigned int c2=charindex;
	
	GLYPHMETRICS gm;
	DWORD size;
	MAT2 matrix; 

	FIXED f1;
	f1.value = 1;
	f1.fract = 0;
	FIXED f0;
	f0.value = 0;
	f0.fract = 0;
	matrix.eM11 = f1;
	matrix.eM12 = f0;
	matrix.eM21 = f0;
	matrix.eM22 = f1;
	short x_offset;

	
	short max_x=0;
	short lastx=0;
	short lasty=0;

	if (advance)
		*advance = 0;
	if(c2 != ' ')
	{
		USHORT char2 = GetTTUnicodeGlyphIndex(hdcScreen, c2);

		UINT text_flags;

		if(char2 == 0)
		{
			char2 = c2;
			text_flags = GGO_NATIVE; 
		}
		else
		{
			text_flags = GGO_NATIVE | GGO_GLYPH_INDEX;
		}
		if((size = GetGlyphOutline(hdcScreen,char2,text_flags,&gm,0,NULL,&matrix)) != GDI_ERROR)
		{ 
			char *buffer = new char[size+1];
			if((size = GetGlyphOutline(hdcScreen,char2,text_flags,&gm,size,buffer,&matrix)) != GDI_ERROR)
			{
				char *pos = (char*)buffer;
				while(pos < buffer+size)
				{
					TTPOLYGONHEADER *header = (TTPOLYGONHEADER *)pos;
					lastheader = header;
					pos+=sizeof(TTPOLYGONHEADER);
	
					short hx = ShortFromFixed(header->pfxStart.x);
					short hy = -(ShortFromFixed(header->pfxStart.y)+ascent);

					if (pos == buffer+sizeof(TTPOLYGONHEADER))
					{
						FlashShapeRecordChange c(hx, hy);
						c.ChangeFillStyle1(1);
						c.SetMoveTo(true);					
						s->AddRecord(c);
					}
					else
					{
						FlashShapeRecordChange c(hx, hy);						
						c.SetMoveTo(true);
						s->AddRecord(c);
					}
					if (hx > max_x) max_x = hx;
					lastx = hx;
					lasty = hy;
					while(pos < (char*)header+(header->cb))
					{			
						
						TTPOLYCURVE *curve = (TTPOLYCURVE *)pos;
						// handle polylines
						if(curve->wType == TT_PRIM_LINE)
						{

							for(WORD i=0; i < curve->cpfx; i++)
							{
								short x = ShortFromFixed(curve->apfx[i].x);
								short y = -(ShortFromFixed(curve->apfx[i].y)+ascent);
								
								FlashShapeRecordStraight fsrs(x-lastx, y-lasty);
								s->AddRecord(fsrs);
								
								if (x > max_x) max_x = x;
								lastx += x-lastx;
								lasty += y-lasty;
							}
						}
						
						// handle lines
						else
						{
							POINTFX pfxB,pfxC;
							for (int u = 0; u < curve->cpfx - 1; u++) // Walk through points in spline 
							{
								pfxB = curve->apfx[u];				// B is always the current point
							   
							   short cx_;
							   short cy_;
							   short ax_;
							   short ay_;

							   cx_ = ShortFromFixed(pfxB.x);
							   cy_ = ShortFromFixed(pfxB.y);

							   if (u < curve->cpfx - 2) 		   // If not on last spline, compute C
							   {					  
								  ax_ = (cx_ + ShortFromFixed(curve->apfx[u+1].x)) / 2;  // x midpoint
								  ay_ = (cy_ + ShortFromFixed(curve->apfx[u+1].y)) / 2;  // y midpoint
							   }
							   else 
							   {
								  pfxC = curve->apfx[u+1];
								  
								  ax_ = ShortFromFixed(pfxC.x);
								  ay_ = ShortFromFixed(pfxC.y);
							   }

							   cy_=-(cy_+ascent);
							   ay_=-(ay_+ascent);
							   short cx = cx_-lastx;
							   short cy = cy_-lasty;
							   short rx = ax_-cx_;
							   short ry = ay_-cy_;
							   lastx += ax_-lastx;
							   lasty += ay_-lasty;
  								if (ax_ > max_x) max_x = ax_;

								FlashShapeRecordCurved fsrc(cx,cy,rx,ry);
								s->AddRecord(fsrc);								
#ifdef _DEBUG_GLYPH
								DBG_SET_RECT (cx_, cy_);
								DBG_SET_RECT (ax_, ay_);
								wsprintf (dbgStr, "BezierTo: x:%d, y:%d x2:%d, y2:%d", cx_,cy_,ax_,ay_);
								SaveDebugString(dbgStr);
#endif

						   }
						}
						pos+=(sizeof(WORD)*2) + (sizeof(POINTFX)*curve->cpfx);
					}
					
					if ((hx!=lastx) || (hy!=lasty))
					{
						FlashShapeRecordStraight rs(hx-lastx, hy-lasty);
						s->AddRecord(rs);
#ifdef _DEBUG_GLYPH
						DBG_SET_RECT (hx, hy);
						wsprintf (dbgStr, "LineTo2: x:%d, y:%d", hx,hy);
						SaveDebugString(dbgStr);
#endif
					}
					lastx = hx;
					lasty = hy;
				}
			}
			else 
			{
				return false; // ERROR
			}
			delete[] buffer;
		}
		else 
		{
			return false; // ERROR
		} 
	}

	if (advance)
		*advance = max_x;
	x_offset = max_x;
	if (c2 == ' ')
		x_offset = 512;
	if (m_last_glyph != TRUE)
		x_offset += ULSO_OFFSET;

	if(internal_ulines)
	{
		if(m_underline)
		{
			int lineAdjust = 0;
			int lineWidth  = x_offset+50;
			int lineHeight = ULSO;
						
			FlashShapeRecordChange change = FlashShapeRecordChange(0,lineAdjust);
			change.ChangeFillStyle1(1);
			
			s->AddRecord(change);
			s->AddRecord(FlashShapeRecordStraight(lineWidth, 0));
			s->AddRecord(FlashShapeRecordStraight(0, lineHeight));
			s->AddRecord(FlashShapeRecordStraight(-lineWidth, 0));
			s->AddRecord(FlashShapeRecordStraight(0, -lineHeight));			
		}
		if(m_strikeout)
		{
			int lineAdjust = -512;
			int lineWidth  = x_offset+50;
			int lineHeight = ULSO;
						
			FlashShapeRecordChange change = FlashShapeRecordChange(0,lineAdjust);
			change.ChangeFillStyle1(1);
			
			s->AddRecord(change);
			s->AddRecord(FlashShapeRecordStraight(lineWidth, 0));
			s->AddRecord(FlashShapeRecordStraight(0, lineHeight));
			s->AddRecord(FlashShapeRecordStraight(-lineWidth, 0));
			s->AddRecord(FlashShapeRecordStraight(0, -lineHeight));
		}
	}
#ifdef _DEBUG_GLYPH
	wsprintf (dbgStr, "RECT: left:%d top:%d right:%d bottom:%d", rmax.left, rmax.top, rmax.right, rmax.bottom);
	SaveDebugString(dbgStr);
	wsprintf (dbgStr, "End Shape");
	SaveDebugString(dbgStr);
#endif

	SelectObject(hdcScreen,obj);
	DeleteObject(myfont);
	DeleteObject(hdcScreen);
	DeleteDC (tmphdc);
	return true;
}

int CFlashFontObj::GetGlyphAdvance(const char *fontname, WORD charindex, WORD nextchar, int pointSize, BOOL usekern)
{
	HDC tmphdc, hdcScreen;
	KERNINGPAIR krnpair;
	OUTLINETEXTMETRIC om;
	int i;
	BOOL ret;

	tmphdc = CreateDC("DISPLAY", NULL, NULL, NULL);
	hdcScreen = CreateCompatibleDC(tmphdc);
	SetMapMode (hdcScreen, MM_TEXT);
	GetOutlineTextMetrics(hdcScreen,sizeof(om),&om);
	HFONT myfont = CreateFont(-(16*pointSize),0,0,0,m_weight,m_italics,m_underline,m_strikeout,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH,fontname);
	HGDIOBJ obj = SelectObject(hdcScreen,myfont);

//	charindex = GetTTUnicodeGlyphIndex(hdcScreen, charindex);
	ret=::GetCharWidthW(hdcScreen,charindex,charindex,&i);
#ifdef _DEBUG_INTERFACE
	wsprintf (dbgStr, "GetGlyphAdvance: c1:%c c2:%c advance:%d", charindex, nextchar, i);
	SaveDebugString(dbgStr);
#endif
	// What about sp char?  check for that as well???
	if (usekern && nextchar)
	{
		krnpair.wFirst = charindex;
		krnpair.wSecond = nextchar;
		krnpair.iKernAmount = 0;
		if (GetKerningPairs(hdcScreen, 1, &krnpair))
		{
			i += (krnpair.iKernAmount);
#ifdef _DEBUG_INTERFACE
		wsprintf (dbgStr, "GetGlyphAdvance: kern:%d", krnpair.iKernAmount);
		SaveDebugString(dbgStr);
#endif
		}
	}

	SelectObject(hdcScreen,obj);
	DeleteObject(myfont);
	DeleteObject(hdcScreen);
	DeleteDC (tmphdc);

	if(ret == 0) return -1;
	else return i;

}
void CFlashFontObj::WriteFontInfos(std::ostream &stream)
{
	for(std::vector<FlashTagDefineFont2 *>::iterator i = fonts.begin(); i != fonts.end(); i++)
	{
		FlashTagDefineFont2 *pFont = (*i);
		pFont->Write(stream);
		delete *i;
	}
	fonts.clear();
	font_infos.clear();
}

bool CFlashFontObj::WriteText(const char *fontname_, wchar_t *text, int x, int y, FlashRGB *color, int pointsize, BOOL italics, BOOL underline, BOOL strikeout, long weight, BOOL usekern, bool internal_ulines, std::ostream &stream, int characterId)
{		
	char *fontname = (char*)malloc(strlen(fontname_)+1);
	strcpy(fontname, fontname_);
	
	fontInfo fi;
	fi.italics = italics;
	fi.strikeout = strikeout;
	fi.underline = underline;
	fi.weight = weight;
	fi.name = fontname;

	bool firstUse = true;
	FlashTagDefineFont2* font = NULL;
	for(int index = 0; index < font_infos.size(); index++)
	{
		if(fi == font_infos[index])
		{
			font = fonts[index];
			firstUse = false;
			break;
		}		
	}

	if(font == NULL)
	{
		font = new FlashTagDefineFont2(FTDF2_ANSI, fontname);
		font_infos.push_back(fi);
		fonts.push_back(font);
	}	
	
	FlashTagDefineText2* txt;
	FlashTextRecordGlyph* textGlyphRec;
		
	int i, len, advance;
	long* ibadvance;
	char* ibuf;	
	
	WORD *buf;
	buf = (WORD *)text;
	//	double val;

	m_italics = italics;
	m_underline = underline;
	m_strikeout = strikeout;
	m_weight = weight;
	m_last_glyph = FALSE;

	m_width = 0;
	m_height = 0;

	int length = wcslen(buf);
	len = length;

	ibuf = new char[len];
	ibadvance = new long[len];
	memset (ibuf, 0, len);
	
	//dfi = new FlashTagDefineFontInfo(const_cast<char *>(fontname), FTDFI_ANSI, font->GetID());
	
	textGlyphRec = new FlashTextRecordGlyph();
	
	for (i=0,len=0; i < length && buf[i] != 0; ++i)
	{ 
		int charId = i;
		//if (!wcschr (buf, buf[i]))
		{

			if (!buf[i+1])
				m_last_glyph = TRUE;

			int definedId = font->GetGlyphId(buf[i]);
			if(definedId == -1)
			{
				FlashShape shape;
				GetGlyphShape(fontname, (WORD)buf[i], &shape, NULL, internal_ulines);
				charId = font->AddShape(shape, (int)buf[i]);
				//dfi->AddCode(text[i]);
			}
			else
			{
				charId = definedId;
			}
			ibuf[len++] = (char)charId;
		}
	
		advance = GetGlyphAdvance(fontname, buf[i], buf[i+1], pointsize, usekern);
		FlashGlyphEntry e;		
		e.first = charId;
		e.second = advance;
		textGlyphRec->AddGlyph(e);		
		m_width += advance;
	}
	m_height = pointsize*24;

	FlashMatrix m;
	FlashRect rect(x-500, y-m_height, x+m_width+1000, y+m_height*2);

	txt = new FlashTagDefineText2(rect, m);

	if(characterId != 0)
	{
		txt->SetID(characterId);
	}
	
	FlashTextRecordStyle recStyle(true, true, true, true, font->GetID(), pointsize*20, *color, x, y);
	txt->AddTextRecord( &recStyle );
	txt->AddTextRecord( textGlyphRec );
	
	txt->Write(stream);

	if(!internal_ulines)	
	{
		FlashTagSprite *sprite = new FlashTagSprite();
		m_oID = sprite->GetID();
				
		sprite->Add(new FlashTagPlaceObject2( 1, txt->GetID()));		
		
		if(m_underline)
		{
			int lineAdjust = 0;
			int lineWidth  = m_width;
			int lineHeight = 45;

			FlashShapeWithStyle shapeUnderline;
			shapeUnderline.AddFillStyle(new FlashFillStyleSolid(*color));
			FlashShapeRecordChange change = FlashShapeRecordChange(x,y+lineAdjust);
			change.ChangeFillStyle1(1);
			shapeUnderline.AddRecord(change);
			shapeUnderline.AddRecord(FlashShapeRecordStraight(lineWidth, 0));
			shapeUnderline.AddRecord(FlashShapeRecordStraight(0, lineHeight));
			shapeUnderline.AddRecord(FlashShapeRecordStraight(-lineWidth, 0));
			shapeUnderline.AddRecord(FlashShapeRecordStraight(0, -lineHeight));
			
			FlashTagDefineShape3 *underlineShapeDef = new FlashTagDefineShape3(shapeUnderline);	
					
			stream << *underlineShapeDef;

			sprite->Add(new FlashTagPlaceObject2( 2, underlineShapeDef->GetID()));
		
			delete underlineShapeDef;
		}
		if(m_strikeout)
		{
			int lineAdjust = pointsize*11;
			int lineWidth  = m_width;
			int lineHeight = pointsize*2;

			FlashShapeWithStyle shapeUnderline;
			shapeUnderline.AddFillStyle(new FlashFillStyleSolid(*color));
			FlashShapeRecordChange change = FlashShapeRecordChange(x,y+lineAdjust);
			change.ChangeFillStyle1(1);
			shapeUnderline.AddRecord(change);
			shapeUnderline.AddRecord(FlashShapeRecordStraight(lineWidth, 0));
			shapeUnderline.AddRecord(FlashShapeRecordStraight(0, lineHeight));
			shapeUnderline.AddRecord(FlashShapeRecordStraight(-lineWidth, 0));
			shapeUnderline.AddRecord(FlashShapeRecordStraight(0, -lineHeight));
			
			FlashTagDefineShape3 *underlineShapeDef = new FlashTagDefineShape3(shapeUnderline);	
					
			stream << *underlineShapeDef;
			sprite->Add(new FlashTagPlaceObject( underlineShapeDef->GetID(), 1, FlashMatrix()));
			
			delete underlineShapeDef;
		}
		
		sprite->Add(new FlashTagShowFrame());

		stream << *sprite;
		sprite->DeleteChildren();
		delete sprite;
	}
	else
	{
		m_oID = txt->GetID();	
	}
	delete txt;
	delete ibuf;
	return true;
}

std::vector <fontInfo> CFlashFontObj::font_infos;
std::vector <FlashTagDefineFont2*> CFlashFontObj::fonts;

⌨️ 快捷键说明

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