📄 text.c
字号:
return SWFFont_getScaledLeading(font) * height / 1024;}void SWFText_setFont(SWFText text, void* font){ SWFTextRecord textRecord = text->currentRecord; if ( textRecord == NULL || textRecord->string != NULL ) textRecord = SWFText_addTextRecord(text); textRecord->flags |= SWF_TEXT_HAS_FONT; /* XXX */ textRecord->isBrowserFont = (BLOCK(font)->type == SWF_DEFINEEDITTEXT); if ( textRecord->isBrowserFont ) SWF_error("cannot use browser font for SWFText");// textRecord->font.browserFont = (SWFBrowserFont)font; else textRecord->font.font = (SWFFont)font;}voidSWFText_setScaledHeight(SWFText text, int height){ SWFTextRecord textRecord = text->currentRecord; if ( textRecord == NULL || (textRecord->string != NULL && height != textRecord->height) ) { textRecord = SWFText_addTextRecord(text); } textRecord->flags |= SWF_TEXT_HAS_FONT; textRecord->height = height;}voidSWFText_setScaledSpacing(SWFText text, int spacing){ SWFTextRecord textRecord = text->currentRecord; if ( textRecord == NULL || textRecord->string != NULL ) textRecord = SWFText_addTextRecord(text); textRecord->spacing = spacing;}voidSWFText_setColor(SWFText text, byte r, byte g, byte b, byte a){ SWFTextRecord textRecord = text->currentRecord; if ( textRecord == NULL || textRecord->string != NULL ) textRecord = SWFText_addTextRecord(text); textRecord->flags |= SWF_TEXT_HAS_COLOR; textRecord->r = r; textRecord->g = g; textRecord->b = b; textRecord->a = a;}voidSWFText_scaledMoveTo(SWFText text, int x, int y){ SWFTextRecord textRecord = text->currentRecord; if ( textRecord == NULL || textRecord->string != NULL ) textRecord = SWFText_addTextRecord(text); if ( x != 0 ) { textRecord->flags |= SWF_TEXT_HAS_X; textRecord->x = x; } if ( y != 0 ) { textRecord->flags |= SWF_TEXT_HAS_Y; textRecord->y = y; }}/* adds textrecord type 0 to output *//* font defn is normalized to height 1024 *//* glyph codes changed to (correct) character codes by Raff */voidSWFText_addWideString(SWFText text, const unsigned short* widestring, int len, int* advance){ SWFTextRecord textRecord = text->currentRecord; SWFFont font = textRecord->font.font; if ( font == NULL ) SWF_error("font must be set before calling addString"); /* marginally sloppy to tack on a new record, but I don't want to deal with concats */ if ( textRecord == NULL || textRecord->string != NULL ) textRecord = SWFText_addTextRecord(text); textRecord->advance = advance; textRecord->strlen = len; textRecord->string = (unsigned short*)malloc(sizeof(unsigned short) * len); memcpy(textRecord->string, widestring, sizeof(unsigned short) * len);}voidSWFText_addUTF8String(SWFText text, const char* string, int* advance){ unsigned short* widestring; int len = UTF8ExpandString(string, &widestring); SWFTextRecord textRecord = text->currentRecord; SWFFont font = textRecord->font.font; if ( font == NULL ) SWF_error("font must be set before calling addString"); /* marginally sloppy to tack on a new record, but I don't want to deal with concats */ if ( textRecord == NULL || textRecord->string != NULL ) textRecord = SWFText_addTextRecord(text); textRecord->advance = advance; textRecord->strlen = len; textRecord->string = widestring;}voidSWFText_addString(SWFText text, const char* string, int* advance){ int len = strlen(string); unsigned short* widestring = (unsigned short*)malloc(len * sizeof(unsigned short)); int i; for ( i = 0; i < len; ++i ) widestring[i] = string[i] & 0xff; SWFText_addWideString(text, widestring, len, advance);}static voidSWFTextRecord_computeAdvances(SWFTextRecord textRecord){ int i; int len = textRecord->strlen; unsigned short* widestring = textRecord->string; unsigned short glyph; SWFFontCharacter fontchar = textRecord->font.fontchar; SWFFont font = SWFFontCharacter_getFont(fontchar); if(!len) return; // do not try to calculate 1st char of null string /* compute advances (spacing) from spacing, advance and kern table */ if ( textRecord->advance == NULL ) { textRecord->advance = (int*)malloc(sizeof(int) * len); memset(textRecord->advance, 0, sizeof(int) * len); } glyph = SWFFontCharacter_getGlyphCode(fontchar, widestring[0]); for ( i=0; i<len; ++i ) { int adv; unsigned short nextglyph; adv = SWFFont_getCharacterAdvance(font, (unsigned short)glyph); adv += textRecord->spacing; /* get kerning from font's kern table */ if ( i < len-1 ) { nextglyph = SWFFontCharacter_getGlyphCode(fontchar, widestring[i+1]); adv += SWFFont_getCharacterKern(font, glyph, nextglyph); glyph = nextglyph; } if ( textRecord->advance != NULL ) adv += textRecord->advance[i]; textRecord->advance[i] = adv * textRecord->height / 1024; textRecord->nAdvanceBits = max(textRecord->nAdvanceBits, SWFOutput_numSBits(textRecord->advance[i])); }}/* turn textRecord list into output code */voidSWFText_resolveCodes(SWFText text){ SWFTextRecord textRecord, oldRecord; SWFOutput out = text->out; int nGlyphBits = 0; int len, i; int curX = 0, curY = 0, curH = 0; textRecord = text->initialRecord; while ( textRecord != NULL ) { SWFTextRecord_computeAdvances(textRecord); text->nAdvanceBits = max(text->nAdvanceBits, textRecord->nAdvanceBits); if ( textRecord->flags & SWF_TEXT_HAS_FONT ) { if ( textRecord->isBrowserFont ) { /* XXX - assume browser fonts have 8bit glyph table? */ nGlyphBits = max(nGlyphBits, 8); } else { int fontGlyphs = SWFFontCharacter_getNGlyphs(textRecord->font.fontchar); nGlyphBits = max(nGlyphBits, SWFOutput_numBits(fontGlyphs-1)); } } textRecord = textRecord->next; } textRecord = text->initialRecord; while ( textRecord != NULL ) { oldRecord = textRecord; if ( textRecord->string == NULL || textRecord->strlen == 0 ) { textRecord = textRecord->next; destroySWFTextRecord(oldRecord); continue; } SWFOutput_byteAlign(out); /* Raff says the spec lies- there's always a change record, even if it's empty, and the string record length is the full 8 bits. */ SWFOutput_writeUInt8(out, textRecord->flags | SWF_TEXT_STATE_CHANGE); if ( textRecord->flags & SWF_TEXT_HAS_FONT ) { if ( textRecord->isBrowserFont ) SWFOutput_writeUInt16(out, CHARACTERID(textRecord->font.browserFont)); else SWFOutput_writeUInt16(out, CHARACTERID(textRecord->font.fontchar)); } if ( textRecord->flags & SWF_TEXT_HAS_COLOR ) { SWFOutput_writeUInt8(out, textRecord->r); SWFOutput_writeUInt8(out, textRecord->g); SWFOutput_writeUInt8(out, textRecord->b); if ( BLOCK(text)->type == SWF_DEFINETEXT2 ) SWFOutput_writeUInt8(out, textRecord->a); } if ( textRecord->flags & SWF_TEXT_HAS_X ) { SWFOutput_writeUInt16(out, textRecord->x); curX = textRecord->x; } if ( textRecord->flags & SWF_TEXT_HAS_Y ) { SWFOutput_writeUInt16(out, textRecord->y); curY = textRecord->y; } if ( textRecord->flags & SWF_TEXT_HAS_FONT ) { SWFOutput_writeUInt16(out, textRecord->height); curH = textRecord->height; } /* record type 0: string data */ len = textRecord->strlen; if ( len >= 256 ) SWF_error("Found text record >= 256 characters!"); SWFOutput_writeUInt8(out, len); /* XXX - er, browser fonts in text objects crash the player.. Maybe because there's no definefontinfo block? */ if ( textRecord->isBrowserFont ) { for ( i=0; i<len; ++i ) { SWFOutput_writeBits(out, textRecord->string[i], nGlyphBits); SWFOutput_writeBits(out, textRecord->advance[i], text->nAdvanceBits); /* XXX - fudging the text character bounds since we don't have font metrics */ if ( CHARACTER(text)->bounds ) { SWFRect_includePoint(CHARACTER(text)->bounds, curX, curY, 0); SWFRect_includePoint(CHARACTER(text)->bounds, curX + curH, curY + curH, 0); } else { CHARACTER(text)->bounds = newSWFRect(curX, curX + curH, curY, curY + curH); } curX += curH; } } else { SWFFontCharacter fontchar = textRecord->font.fontchar; SWFFont font = SWFFontCharacter_getFont(fontchar); if ( font == NULL ) SWF_error("Couldn't find font"); for ( i=0; i<len; ++i ) { SWFRect glyphBounds; int minX, maxX, minY, maxY; unsigned short code = SWFFontCharacter_getGlyphCode(fontchar, textRecord->string[i]); glyphBounds = SWFFont_getGlyphBounds(font, code); SWFRect_getBounds(glyphBounds, &minX, &maxX, &minY, &maxY); SWFOutput_writeBits(out, textRecord->string[i], nGlyphBits); SWFOutput_writeBits(out, textRecord->advance[i], text->nAdvanceBits); if ( CHARACTER(text)->bounds ) { SWFRect_includePoint(CHARACTER(text)->bounds, curX + minX * curH / 1024, curY + minY * curH / 1024, 0); SWFRect_includePoint(CHARACTER(text)->bounds, curX + maxX * curH / 1024, curY + maxY * curH / 1024, 0); } else { CHARACTER(text)->bounds = newSWFRect(curX + minX * curH /1024, curX + maxX * curH /1024, curY + minY * curH /1024, curY + maxY * curH /1024); } if ( textRecord->advance != NULL ) curX += textRecord->advance[i]; } } textRecord = textRecord->next; destroySWFTextRecord(oldRecord); } SWFOutput_writeUInt8(out, 0); /* end text records */ text->nGlyphBits = nGlyphBits; text->initialRecord = NULL; text->currentRecord = NULL;}/* * Local variables: * tab-width: 2 * c-basic-offset: 2 * End: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -