📄 text.c
字号:
/* 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: text.c,v 1.39 2008/06/24 19:38:38 krechert Exp $ */#include <stdlib.h>#include <string.h>#include <math.h>#include "text.h"#include "rect.h"#include "utf8.h"#include "character.h"#include "matrix.h"#include "font.h"#include "libming.h"struct SWFText_s{ struct SWFCharacter_s character; SWFOutput out; SWFMatrix matrix; byte nAdvanceBits; byte nGlyphBits; SWFTextRecord initialRecord; SWFTextRecord currentRecord;#if TRACK_ALLOCS /* memory node for garbage collection */ mem_node *gcnode;#endif};struct SWFTextRecord_s{ struct SWFTextRecord_s *next; byte flags; // if it's not a browser font, is it a font or a fontchar? BOOL isResolved; union { SWFFont font; SWFFontCharacter fontchar; } font; // color byte r; byte g; byte b; byte a; // position int x; int y; // metrics int height; int spacing; int strlen; unsigned short* string; int* advance; int advAllocated; int nAdvanceBits;};static voidwriteSWFTextToMethod(SWFBlock block, SWFByteOutputMethod method, void *data){ SWFText text = (SWFText)block; int length = 0; SWFOutput out; if ( text->matrix == NULL ) text->matrix = newSWFMatrix(0, 0, 0, 0, 0, 0); length += (SWFMatrix_numBits(text->matrix)+7)/8; length += (SWFRect_numBits(CHARACTER(text)->bounds)+7)/8; length += 4; out = newSizedSWFOutput(length); SWFOutput_writeUInt16(out, CHARACTERID(text)); SWFOutput_writeRect(out, CHARACTER(text)->bounds); SWFOutput_writeMatrix(out, text->matrix); SWFOutput_writeUInt8(out, text->nGlyphBits); SWFOutput_writeUInt8(out, text->nAdvanceBits); SWFOutput_writeToMethod(out, method, data); SWFOutput_writeToMethod(text->out, method, data); destroySWFOutput(out);}static intcompleteSWFText(SWFBlock block){ int length = 4; SWFText text = (SWFText)block; SWFText_resolveCodes(text); length += SWFOutput_getLength(text->out); if ( text->matrix ) length += (SWFMatrix_numBits(text->matrix)+7)/8; else ++length; length += (SWFRect_numBits(CHARACTER(text)->bounds)+7)/8; return length;}voiddestroySWFText(SWFText text){ SWFTextRecord record = text->initialRecord, next; destroySWFOutput(text->out); if ( text->matrix != NULL ) destroySWFMatrix(text->matrix); while ( record != NULL ) { next = record->next; destroySWFTextRecord(record); record = next; }#if TRACK_ALLOCS ming_gc_remove_node(text->gcnode);#endif destroySWFCharacter((SWFCharacter) text);}SWFTextnewSWFText(){ SWFRect temp_rect; SWFText text = (SWFText)malloc(sizeof(struct SWFText_s)); /* If malloc failed, return NULL to signify this */ if (NULL == text) return NULL; SWFCharacterInit((SWFCharacter)text); CHARACTERID(text) = ++SWF_gNumCharacters; BLOCK(text)->type = SWF_DEFINETEXT; BLOCK(text)->writeBlock = writeSWFTextToMethod; BLOCK(text)->complete = completeSWFText; BLOCK(text)->dtor = (destroySWFBlockMethod) destroySWFText; temp_rect = newSWFRect(0,0,0,0); /* If newSWFRect() failed, return NULL to signify this */ if (NULL == temp_rect) { free(text); return NULL; } CHARACTER(text)->bounds = temp_rect; text->out = newSWFOutput(); /* If newSWFOutput() failed, return NULL to signify this */ if (NULL == text->out) { destroySWFRect(temp_rect); free(text); return NULL; } text->currentRecord = NULL; text->initialRecord = NULL; text->matrix = NULL; text->nAdvanceBits = 0;#if TRACK_ALLOCS text->gcnode = ming_gc_add_node(text, (dtorfunctype) destroySWFBitmap);#endif return text;}/* only dif is type 2 allows transparency.. */SWFTextnewSWFText2(){ SWFText text = newSWFText(); /* If malloc failed, return NULL to signify this */ if (NULL == text) return NULL; BLOCK(text)->type = SWF_DEFINETEXT2; return text;}SWFTextRecordSWFText_addTextRecord(SWFText text){ SWFTextRecord textRecord = (SWFTextRecord)malloc(sizeof(struct SWFTextRecord_s)); /* If malloc failed, return NULL to signify this */ if (NULL == text) return NULL; SWFTextRecord current = text->currentRecord; textRecord->flags = 0; textRecord->string = NULL; textRecord->strlen = 0; textRecord->next = NULL; textRecord->x = 0; textRecord->y = 0; textRecord->advance = NULL; textRecord->advAllocated = 0; textRecord->nAdvanceBits = 0; if ( current == NULL ) { textRecord->isResolved = FALSE; textRecord->font.font = NULL; textRecord->spacing = 0; textRecord->height = 240; textRecord->r = 0; textRecord->g = 0; textRecord->b = 0; textRecord->a = 0; text->initialRecord = textRecord; } else { textRecord->isResolved = current->isResolved; textRecord->font = current->font; textRecord->spacing = current->spacing; textRecord->height = current->height; textRecord->r = current->r; textRecord->g = current->g; textRecord->b = current->b; textRecord->a = current->a; current->next = textRecord; } text->currentRecord = textRecord; return textRecord;}voiddestroySWFTextRecord(SWFTextRecord record){ if ( record->string != NULL ) free(record->string); if ( record->advance != NULL && record->advAllocated) free(record->advance); if ( record != NULL ) free(record);}intSWFTextRecord_getString(SWFTextRecord record, unsigned short** outStr){ *outStr = record->string; return record->strlen;}SWFTextRecordSWFText_getInitialRecord(SWFText text){ return text->initialRecord;}SWFTextRecordSWFTextRecord_getNextRecord(SWFTextRecord record){ return record->next;}SWFFontSWFTextRecord_getUnresolvedFont(SWFTextRecord record){ if ( !record->isResolved ) return record->font.font; return NULL;}voidSWFTextRecord_setFontCharacter(SWFTextRecord record, SWFFontCharacter font){ record->font.fontchar = font; record->isResolved = TRUE; SWFFontCharacter_addTextToList(font, record);}intSWFText_getScaledStringWidth(SWFText text, const char *string){ SWFFont font; int height; unsigned short* widestr; int len = strlen(string); int n, ret; if(text->currentRecord == NULL) return -1; height = text->currentRecord->height; widestr = (unsigned short *)malloc(2 * len); /* If malloc failed, return -1 to signify this */ if (NULL == text) return -1; for(n = 0 ; n < len ; n++) widestr[n] = (unsigned char)string[n]; if ( text->currentRecord->isResolved ) font = SWFFontCharacter_getFont(text->currentRecord->font.fontchar); else font = text->currentRecord->font.font; ret = SWFFont_getScaledWideStringWidth(font, widestr, len) * height / 1024; free(widestr); return ret;}intSWFText_getScaledUTF8StringWidth(SWFText text, const char *string){ SWFFont font; int height; unsigned short* widestr; int len, ret; if(text->currentRecord == NULL) return -1; height = text->currentRecord->height; len = UTF8ExpandString(string, &widestr); if ( text->currentRecord->isResolved ) font = SWFFontCharacter_getFont(text->currentRecord->font.fontchar); else font = text->currentRecord->font.font; ret = SWFFont_getScaledWideStringWidth(font, widestr, len) * height / 1024; free(widestr); return ret;}intSWFText_getScaledWideStringWidth(SWFText text, const unsigned short *string){ SWFFont font; int height; int len; if(text->currentRecord == NULL) return -1; height = text->currentRecord->height; for(len = 0 ; *(string + len); len++) ; if ( text->currentRecord->isResolved ) font = SWFFontCharacter_getFont(text->currentRecord->font.fontchar); else font = text->currentRecord->font.font; return SWFFont_getScaledWideStringWidth(font, string, len) * height / 1024;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -