+
+ if(charname) {
+ int t;
+ for(t=0;t<font->num_glyphs;t++) {
+ if(font->glyphs[t].name && !strcmp(font->glyphs[t].name,charname)) {
+ msg("<debug> Char [%d,>%s<,%d] maps to %d\n", charnr, charname, u, t);
+ return t;
+ }
+ }
+ /* if we didn't find the character, maybe
+ we can find the capitalized version */
+ for(t=0;t<font->num_glyphs;t++) {
+ if(font->glyphs[t].name && !strcasecmp(font->glyphs[t].name,charname)) {
+ msg("<debug> Char [%d,>>%s<<,%d] maps to %d\n", charnr, charname, u, t);
+ return t;
+ }
+ }
+ }
+
+ if(uniname) {
+ int t;
+ for(t=0;t<font->num_glyphs;t++) {
+ if(font->glyphs[t].name && !strcmp(font->glyphs[t].name,uniname)) {
+ msg("<debug> Char [%d,%s,>%d(%s)<] maps to %d\n", charnr, charname, u, uniname, t);
+ return t;
+ }
+ }
+ /* if we didn't find the character, maybe
+ we can find the capitalized version */
+ for(t=0;t<font->num_glyphs;t++) {
+ if(font->glyphs[t].name && !strcasecmp(font->glyphs[t].name,uniname)) {
+ msg("<debug> Char [%d,%s,>>%d(%s)<<] maps to %d\n", charnr, charname, u, uniname, t);
+ return t;
+ }
+ }
+ }
+
+ /* try to use the unicode id */
+ if(u>=0 && u<font->max_unicode && font->unicode2glyph[u]>=0) {
+ msg("<debug> Char [%d,%s,>%d<] maps to %d\n", charnr, charname, u, font->unicode2glyph[u]);
+ return font->unicode2glyph[u];
+ }
+
+ if(charnr>=0 && charnr<font->num_glyphs) {
+ msg("<debug> Char [>%d<,%s,%d] maps to %d\n", charnr, charname, u, charnr);
+ return charnr;
+ }
+
+ return -1;
+}
+
+
+void SWFOutputDev::beginString(GfxState *state, GString *s)
+{
+ int render = state->getRender();
+ if(current_text_stroke) {
+ msg("<error> Error: Incompatible change of text rendering to %d while inside cliptext", render);
+ }
+
+ msg("<trace> beginString(%s) render=%d", makeStringPrintable(s->getCString()), render);
+ double m11,m21,m12,m22;
+// msg("<debug> %s beginstring \"%s\"\n", gfxstate2str(state), s->getCString());
+ state->getFontTransMat(&m11, &m12, &m21, &m22);
+ m11 *= state->getHorizScaling();
+ m21 *= state->getHorizScaling();
+
+ this->current_font_matrix.m00 = m11 / 1024.0;
+ this->current_font_matrix.m01 = m12 / 1024.0;
+ this->current_font_matrix.m10 = -m21 / 1024.0;
+ this->current_font_matrix.m11 = -m22 / 1024.0;
+ this->current_font_matrix.tx = 0;
+ this->current_font_matrix.ty = 0;
+
+ gfxmatrix_t m = this->current_font_matrix;
+
+ /*if(render != 3 && render != 0)
+ msg("<warning> Text rendering mode %d (%s) not fully supported yet (for text \"%s\")", render, renderModeDesc[render&7], makeStringPrintable(s->getCString()));*/
+ states[statepos].textRender = render;
+}
+
+void SWFOutputDev::drawChar(GfxState *state, double x, double y,
+ double dx, double dy,
+ double originX, double originY,
+ CharCode c, int nBytes, Unicode *_u, int uLen)
+{
+ int render = state->getRender();
+ // check for invisible text -- this is used by Acrobat Capture
+ if (render == 3) {
+ msg("<debug> Ignoring invisible text: char %d at %f,%f", c, x, y);
+ return;
+ }
+
+ if(states[statepos].textRender != render)
+ msg("<error> Internal error: drawChar.render!=beginString.render");
+
+ gfxcolor_t col = getFillColor(state);
+
+ Gushort *CIDToGIDMap = 0;
+ GfxFont*font = state->getFont();
+
+ if(font->getType() == fontType3) {
+ /* type 3 chars are passed as graphics */
+ msg("<debug> type3 char at %f/%f", x, y);
+ return;
+ }
+
+ Unicode u=0;
+ char*name=0;
+
+ if(font->isCIDFont()) {
+ GfxCIDFont*cfont = (GfxCIDFont*)font;
+
+ if(font->getType() == fontCIDType2)
+ CIDToGIDMap = cfont->getCIDToGID();
+ } else {
+ Gfx8BitFont*font8;
+ font8 = (Gfx8BitFont*)font;
+ char**enc=font8->getEncoding();
+ name = enc[c];
+ }
+ if (CIDToGIDMap) {
+ msg("<debug> drawChar(%f, %f, c='%c' (%d), GID=%d, u=%d <%d>) CID=%d name=\"%s\" render=%d\n", x, y, (c&127)>=32?c:'?', c, CIDToGIDMap[c], u, uLen, font->isCIDFont(), FIXNULL(name), render);
+ c = CIDToGIDMap[c];
+ } else {
+ msg("<debug> drawChar(%f,%f,c='%c' (%d), u=%d <%d>) CID=%d name=\"%s\" render=%d\n",x,y,(c&127)>=32?c:'?',c,u, uLen, font->isCIDFont(), FIXNULL(name), render);
+ }
+
+ int charid = -1;
+
+ if(uLen<=1) {
+ charid = getGfxCharID(current_gfxfont, c, name, u);
+ } else {
+ charid = getGfxCharID(current_gfxfont, c, name, -1);
+
+ if(charid < 0) {
+ /* multiple unicodes- should usually map to a ligature.
+ if the ligature doesn't exist, we need to draw
+ the characters one-by-one. */
+ int t;
+ msg("<warning> ligature %d missing in font %s\n", c, current_font_id);
+ for(t=0;t<uLen;t++) {
+ drawChar(state, x, y, dx, dy, originX, originY, c, nBytes, _u+t, 1);
+ }
+ return;
+ }
+ }
+ if(charid<0) {
+ msg("<warning> Didn't find character '%s' (c=%d,u=%d) in current charset (%s, %d characters)",
+ FIXNULL(name),c, u, FIXNULL((char*)current_font_id), current_gfxfont->num_glyphs);
+ return;
+ }
+
+ gfxmatrix_t m = this->current_font_matrix;
+ state->transform(x, y, &m.tx, &m.ty);
+ m.tx += user_movex;
+ m.ty += user_movey;
+
+ if(render == RENDER_FILL) {
+ output->drawchar(output, current_font_id, charid, &col, &m);
+ } else {
+ msg("<debug> Drawing glyph %d as shape", charid);
+ if(!textmodeinfo) {
+ msg("<notice> Some texts will be rendered as shape");
+ textmodeinfo = 1;
+ }
+ gfxline_t*glyph = current_gfxfont->glyphs[charid].line;
+ gfxline_t*tglyph = gfxline_clone(glyph);
+ gfxline_transform(tglyph, &m);
+ if((render&3) != RENDER_INVISIBLE) {
+ gfxline_t*add = gfxline_clone(tglyph);
+ current_text_stroke = gfxline_append(current_text_stroke, add);
+ }
+ if(render&RENDER_CLIP) {
+ gfxline_t*add = gfxline_clone(tglyph);
+ current_text_clip = gfxline_append(current_text_clip, add);
+ }
+ gfxline_free(tglyph);
+ }