void swfMetricInfo(int c, const pGEcontext gc, double* ascent, double* descent, double* width, pDevDesc dd) { #ifdef SWF_DEBUG Rprintf("metricInfo called\n"); Rprintf("** family = %s, c = %d\n", gc->fontfamily, c); #endif FT_Face face = swfGetFTFace(gc); FT_Error err; double fontSize = gc->ps * gc->cex; double ratio = fontSize / face->units_per_EM; if(c == 0) c = 77; if(c < 0) { c = -c; } /* c is the unicode of the character */ FT_Set_Char_Size(face, 0, fontSize * 64, 72, 0); err = FT_Load_Char(face, c, FT_LOAD_NO_SCALE); if(err) { errorcode(err); *ascent = *descent = *width = 0.0; return; } *ascent = face->glyph->metrics.horiBearingY * ratio; *descent = face->glyph->metrics.height * ratio - *ascent; *width = face->glyph->metrics.horiAdvance * ratio; #ifdef SWF_DEBUG Rprintf("** metricInfo(ascent = %f, descent = %f, width = %f)\n", *ascent, *descent, *width); #endif }
static inline void open_close_stream(int level, uint8_t hdr, struct frame *frm) { switch (hdr & 0x03) { case 0x00: acp_seid(level, frm); break; case 0x03: errorcode(level, frm); break; } }
static inline void start_suspend_stream(int level, uint8_t hdr, struct frame *frm) { switch (hdr & 0x03) { case 0x00: while (frm->len > 0) acp_seid(level, frm); break; case 0x03: acp_seid(level, frm); errorcode(level, frm); break; } }
static inline void get_configuration(int level, uint8_t hdr, struct frame *frm) { switch (hdr & 0x03) { case 0x00: acp_seid(level, frm); case 0x02: capabilities(level, frm); break; case 0x03: errorcode(level, frm); break; } }
static inline void security(int level, uint8_t hdr, struct frame *frm) { switch (hdr & 0x03) { case 0x00: acp_seid(level, frm); case 0x02: hex_dump(level + 1, frm, frm->len); frm->ptr += frm->len; frm->len = 0; break; case 0x03: errorcode(level, frm); break; } }
void SWFShape_addString(SWFShape shape, const wchar_t* str, size_t nchar, double fontSize, FT_Face face, FT_Outline_Funcs *funs) { OutlineData data; FT_Outline outline; FT_Error err; int i; data.shape = shape; data.ratio_EM = fontSize / face->units_per_EM; data.deltax = 0.0; for(i = 0; i < nchar; i++) { /* str should be Unicode */ err = FT_Load_Char(face, str[i], FT_LOAD_NO_SCALE); if(err) { errorcode(err); continue; } outline = face->glyph->outline; err = FT_Outline_Decompose(&outline, funs, &data); if(err) { errorcode(err); continue; } /* After we draw a character, we move the pen right to a distance of the advance */ /* See the picture in http://www.freetype.org/freetype2/docs/tutorial/step2.html */ data.deltax += face->glyph->metrics.horiAdvance * data.ratio_EM; } }
static inline void reconfigure(int level, uint8_t hdr, struct frame *frm) { uint8_t cat; switch (hdr & 0x03) { case 0x00: acp_seid(level, frm); capabilities(level, frm); break; case 0x03: p_indent(level, frm); cat = get_u8(frm); printf("%s\n", cat2str(cat)); errorcode(level, frm); break; } }
static inline void delay_report(int level, uint8_t hdr, struct frame *frm) { uint8_t seid; uint16_t delay; switch (hdr & 0x03) { case 0x00: p_indent(level, frm); seid = get_u8(frm); delay = get_u16(frm); printf("ACP SEID %d delay %u.%ums\n", seid >> 2, delay / 10, delay % 10); break; case 0x03: errorcode(level, frm); break; } }
static inline void discover(int level, uint8_t hdr, struct frame *frm) { uint8_t seid, type; switch (hdr & 0x03) { case 0x02: while (frm->len > 1) { p_indent(level, frm); seid = get_u8(frm); type = get_u8(frm); printf("ACP SEID %d - %s %s%s\n", seid >> 2, media2str(type >> 4), type & 0x08 ? "Sink" : "Source", seid & 0x02 ? " (InUse)" : ""); } break; case 0x03: errorcode(level, frm); break; } }
double swfStrWidthUTF8(const char *str, const pGEcontext gc, pDevDesc dd) { #ifdef SWF_DEBUG Rprintf("strWidthUTF8 called\n"); Rprintf("** family = %s, str[0] = %d, str[1] = %d\n", gc->fontfamily, str[0], str[1]); #endif /* Convert UTF-8 string to Unicode array */ int maxLen = strlen(str); wchar_t *unicode = (wchar_t *) calloc(maxLen + 1, sizeof(wchar_t)); int len = utf8towcs(unicode, str, maxLen); /* Get the font face object */ FT_Face face = swfGetFTFace(gc); FT_Error err; double fontSize = gc->ps * gc->cex; double ratio = fontSize / face->units_per_EM; double width = 0.0; int i; /* Add up the 'advance' of each character */ for(i = 0; i < len; i++) { err = FT_Load_Char(face, unicode[i], FT_LOAD_NO_SCALE); if(err) { errorcode(err); continue; } width += face->glyph->metrics.horiAdvance * ratio; } free(unicode); #ifdef SWF_DEBUG Rprintf("** strWidthUTF8(width = %f)\n", width); #endif return width; }