/*--------------------------------------------------------------------------------* * Reads SWF to memory *--------------------------------------------------------------------------------*/ int swf_ReadSWF2(reader_t* reader, SWF* swf) { char b[32]; int len; int tc; /* tag counter */ TAG* t; TAG t1; reader_t zreader; if(NULL == swf) return -1; memset(swf, 0x00, sizeof(SWF)); len = reader->read(reader, b, 8); if(len < 8) return -1; if(b[0] != 'F' && b[0] != 'C') return -1; if(b[1] != 'W') return -1; if(b[2] != 'S') return -1; swf->fileVersion = b[3]; swf->compressed = (b[0]=='C') ? 1 : 0; swf->fileSize = GET32(&b[4]); if(swf->compressed) { /* at first, we do not care about SWC */ return -1; } swf->compressed = 0; reader_GetRect(reader, &swf->movieSize); reader->read(reader, &swf->frameRate, 2); swf->frameRate = LE_16_TO_NATIVE(swf->frameRate); reader->read(reader, &swf->frameCount, 2); swf->frameCount = LE_16_TO_NATIVE(swf->frameCount); /* read tags and connect to list */ t1.next = 0; t = &t1; tc = 0; while (t) { t = swf_ReadTag(reader, t); if(NULL == t) break; tc++; if(t->id == ST_FILEATTRIBUTES) { swf->fileAttributes = swf_GetU32(t); swf_ResetReadBits(t); } } /* printf("swf->frameCount:%d <--> tag count:%d\n", swf->frameCount, tc); */ swf->firstTag = t1.next; if(t1.next) t1.next->prev = NULL; return reader->pos; }
int swf_FontExtract_DefineFont2(int id, SWFFONT *font, TAG *tag) { int t, glyphcount; int maxcode; int fid; uint32_t offset_start; uint32_t *offset; uint8_t flags1, /*langcode, */namelen; swf_SetTagPos(tag, 0); font->version = tag->id == ST_DEFINEFONT3 ? 3 : 2; fid = swf_GetU16(tag); if (id && id != fid) return id; font->id = fid; flags1 = swf_GetU8(tag); /*langcode = */swf_GetU8(tag); //reserved flags if (flags1 & 1) font->style |= FONT_STYLE_BOLD; if (flags1 & 2) font->style |= FONT_STYLE_ITALIC; if (flags1 & 16) font->encoding |= FONT_ENCODING_ANSI; if (flags1 & 32) font->encoding |= FONT_ENCODING_UNICODE; if (flags1 & 64) font->encoding |= FONT_ENCODING_SHIFTJIS; namelen = swf_GetU8(tag); font->name = (uint8_t *) malloc(namelen + 1); font->name[namelen] = 0; swf_GetBlock(tag, font->name, namelen); glyphcount = swf_GetU16(tag); font->numchars = glyphcount; font->glyph = (SWFGLYPH *) calloc(1, sizeof(SWFGLYPH) * glyphcount); font->glyph2ascii = (uint16_t *) calloc(1, sizeof(uint16_t) * glyphcount); offset = (uint32_t*)calloc(1, sizeof(uint32_t)*(glyphcount + 1)); offset_start = tag->pos; if (flags1 & 8) { // wide offsets for (t = 0; t < glyphcount; t++) offset[t] = swf_GetU32(tag); //offset[t] if (glyphcount) /* this _if_ is not in the specs */ offset[glyphcount] = swf_GetU32(tag); // fontcodeoffset else offset[glyphcount] = tag->pos; } else { for (t = 0; t < glyphcount; t++) offset[t] = swf_GetU16(tag); //offset[t] if (glyphcount) /* this _if_ is not in the specs */ offset[glyphcount] = swf_GetU16(tag); // fontcodeoffset else offset[glyphcount] = tag->pos; } for (t = 0; t < glyphcount; t++) { swf_SetTagPos(tag, offset[t] + offset_start); swf_GetSimpleShape(tag, &(font->glyph[t].shape)); } if (glyphcount) swf_SetTagPos(tag, offset[glyphcount] + offset_start); free(offset); maxcode = 0; for (t = 0; t < glyphcount; t++) { int code; if (flags1 & 4) // wide codes (always on for definefont3) code = swf_GetU16(tag); else code = swf_GetU8(tag); font->glyph2ascii[t] = code; if (code > maxcode) maxcode = code; } maxcode++; if (maxcode < 256) maxcode = 256; font->maxascii = maxcode; font->ascii2glyph = (int *) malloc(sizeof(int) * maxcode); memset(font->ascii2glyph, -1, sizeof(int) * maxcode); for (t = 0; t < glyphcount; t++) { font->ascii2glyph[font->glyph2ascii[t]] = t; } if (flags1 & 128) { // has layout uint16_t kerningcount; font->layout = (SWFLAYOUT *) malloc(sizeof(SWFLAYOUT)); font->layout->ascent = swf_GetU16(tag); font->layout->descent = swf_GetU16(tag); font->layout->leading = swf_GetU16(tag); for (t = 0; t < glyphcount; t++) { int16_t advance = swf_GetS16(tag); font->glyph[t].advance = advance; } font->layout->bounds = (SRECT*)malloc(glyphcount * sizeof(SRECT)); for (t = 0; t < glyphcount; t++) { swf_ResetReadBits(tag); swf_GetRect(tag, &font->layout->bounds[t]); SRECT b = font->layout->bounds[t]; if ((b.xmin | b.xmax | b.ymin | b.ymax) == 0) { // recalculate bounding box SHAPE2 *shape2 = swf_ShapeToShape2(font->glyph[t].shape); font->layout->bounds[t] = swf_GetShapeBoundingBox(shape2); swf_Shape2Free(shape2); free(shape2); } } kerningcount = swf_GetU16(tag); font->layout->kerningcount = kerningcount; font->layout->kerning = (SWFKERNING *) malloc(sizeof(SWFKERNING) * kerningcount); if (kerningcount) { font->layout->kerning = (SWFKERNING*)malloc(sizeof(*font->layout->kerning) * kerningcount); for (t = 0; t < kerningcount; t++) { if (flags1 & 4) { // wide codes font->layout->kerning[t].char1 = swf_GetU16(tag); font->layout->kerning[t].char2 = swf_GetU16(tag); } else { font->layout->kerning[t].char1 = swf_GetU8(tag); font->layout->kerning[t].char2 = swf_GetU8(tag); } font->layout->kerning[t].adjustment = swf_GetS16(tag); } } } return font->id; }