fixed compiler warnings.
[swftools.git] / lib / modules / swftext.c
index a5db863..5ebe89f 100644 (file)
@@ -33,8 +33,8 @@
 #define FF2_SHIFTJIS     0x40
 #define FF2_LAYOUT      0x80
 
-int swf_FontIsItalic(SWFFONT * f) { return f->version==2?f->flags&FF2_ITALIC:f->flags&FF_ITALIC; }
-int swf_FontIsBold(SWFFONT * f)   { return f->version==2?f->flags&FF2_BOLD:f->flags&FF_BOLD; }
+int swf_FontIsItalic(SWFFONT * f) { return f->style&FONT_STYLE_ITALIC;}
+int swf_FontIsBold(SWFFONT * f)   { return f->style&FONT_STYLE_BOLD;}
 
 static const int WRITEFONTID = 0x4e46; // font id for WriteFont and ReadFont
 
@@ -80,7 +80,7 @@ int swf_FontExtract_DefineFont(int id,SWFFONT * f,TAG * t)
 
   fid = swf_GetU16(t);
   if ((!id)||(id==fid))
-  { U16 of,*ofs;
+  { U16 of;
     int n,i;
       
     id = fid;
@@ -104,19 +104,20 @@ int swf_FontExtract_DefineFont(int id,SWFFONT * f,TAG * t)
 int swf_FontExtract_DefineFontInfo(int id,SWFFONT * f,TAG * t)
 { U16 fid;
   U16 maxcode;
+  U8 flags;
   swf_SaveTagPos(t);
   swf_SetTagPos(t,0);
 
-  if(f->version>1) {
-      // DefineFont2 doesn't have FontInfo fields
-      fprintf(stderr, "fixme: FontInfo field for DefineFont2 encountered\n");
-      return -1;
-  }
-
   fid = swf_GetU16(t);
   if (fid==id)
   { U8 l = swf_GetU8(t);
     int i;
+  
+    if(f->version>1) {
+      // DefineFont2 doesn't have FontInfo fields
+      fprintf(stderr, "fixme: FontInfo field for DefineFont2 encountered\n");
+      return -1;
+    }
     
     if (l)
     { if (f->name) free(f->name);
@@ -130,12 +131,22 @@ int swf_FontExtract_DefineFontInfo(int id,SWFFONT * f,TAG * t)
         return -1;
       }
     }
-    f->flags = swf_GetU8(t);
+    flags = swf_GetU8(t);
+    if(flags & 2)
+       f->style |= FONT_STYLE_BOLD;
+    if(flags & 4)
+       f->style |= FONT_STYLE_ITALIC;
+    if(flags & 8)
+       f->encoding |= FONT_ENCODING_ANSI;
+    if(flags & 16)
+       f->encoding |= FONT_ENCODING_SHIFTJIS;
+    if(flags & 32)
+       f->encoding |= FONT_ENCODING_UNICODE;
 
     f->glyph2ascii = (U16*)malloc(sizeof(U16)*f->numchars);
     maxcode = 0;
     for(i=0; i < f->numchars; i++) {
-      f->glyph2ascii[i] = ((f->flags&FF_WIDECODES)?swf_GetU16(t):swf_GetU8(t));
+      f->glyph2ascii[i] = ((flags&FF_WIDECODES)?swf_GetU16(t):swf_GetU8(t));
       if(f->glyph2ascii[i] > maxcode)
          maxcode = f->glyph2ascii[i];
     }
@@ -165,12 +176,23 @@ int swf_FontExtract_DefineFont2(int id,SWFFONT * font,TAG * tag)
     font->version=2;
     fid = swf_GetU16(tag);
     if(id && id!=fid)
-       return;
+       return id;
     font->id = fid;
     flags1 = swf_GetU8(tag);
     flags2 = 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->flags = flags1;
     font->name = (U8*)malloc(namelen+1);
     font->name[namelen]=0;
     swf_GetBlock(tag, font->name, namelen);
@@ -303,8 +325,10 @@ int swf_FontExtract_DefineTextCallback(int id,SWFFONT * f,TAG * t,int jobs,
         glyph = swf_GetBits(t,gbits);
         adv = swf_GetBits(t,abits);
         if (id==fid)                    // mitlesen ?
-        { int code = f->glyph2ascii[glyph];
-          if (jobs&FEDTJ_PRINT) printf("%c",code);
+          if (jobs&FEDTJ_PRINT) {
+           { int code = f->glyph2ascii[glyph];
+             printf("%c",code);
+         }
           if (jobs&FEDTJ_MODIFY)
             /*if (!f->glyph[code].advance)*/ f->glyph[glyph].advance = adv;
         }
@@ -368,7 +392,7 @@ int swf_FontExtract(SWF * swf,int id,SWFFONT * * font)
 int swf_FontSetID(SWFFONT * f,U16 id) { if (!f) return -1; f->id = id; return 0; }
 
 int swf_FontReduce(SWFFONT * f,FONTUSAGE * use)
-{ int i,j,num;
+{ int i,j;
   if ((!f)||(!use)) return -1;
 
   j = 0;
@@ -436,9 +460,108 @@ int swf_FontSetDefine(TAG * t,SWFFONT * f)
   return 0;
 }
 
+int swf_FontSetDefine2(TAG *tag, SWFFONT * f)
+{
+    U8 flags = 0;
+    int t;
+    int pos;
+    int pos2;
+    swf_SetU16(tag, f->id);
+    if(f->layout) 
+       flags |= 128; // haslayout
+    if(f->numchars>256)
+       flags |= 4; // widecodes
+    if(f->style & FONT_STYLE_BOLD)
+       flags |= 1; // bold
+    if(f->style & FONT_STYLE_ITALIC)
+       flags |= 2; // italic
+    /* wideoffs 8 */
+    if(f->encoding & FONT_ENCODING_ANSI)
+       flags |= 16; // ansi
+    if(f->encoding & FONT_ENCODING_UNICODE)
+       flags |= 32; // unicode
+    if(f->encoding & FONT_ENCODING_SHIFTJIS)
+       flags |= 64; // shiftjis
+
+    swf_SetU8(tag, flags);
+    swf_SetU8(tag, 0); //reserved flags
+    if(f->name) {
+       /* font name */
+       swf_SetU8(tag, strlen(f->name));
+       swf_SetBlock(tag, f->name, strlen(f->name));
+    } else {
+       /* font name (="") */
+       swf_SetU8(tag, 0); /*placeholder*/
+    }
+    /* number of glyphs */
+    swf_SetU16(tag, f->numchars);
+    /* font offset table */
+    pos = tag->len;
+    for(t=0;t<f->numchars;t++)
+    {
+       swf_SetU16(tag, /* fontoffset */ 0); /*placeholder*/
+    }
+    pos2 = tag->len;
+    swf_SetU16(tag, 0); //fontcode-fontoffset
+    for(t=0;t<f->numchars;t++) {
+       tag->data[pos + t*2] = (tag->len-pos);
+       tag->data[pos + t*2 + 1] = (tag->len-pos) >> 8;
+       swf_SetSimpleShape(tag, f->glyph[t].shape);
+    }
+
+    tag->data[pos2] = tag->len - pos;
+    tag->data[pos2 + 1] = (tag->len - pos) >> 8;
+    
+    /* font code table */
+    if(flags & 4) /* wide codes */ {
+       for(t=0;t<f->numchars;t++)
+           swf_SetU16(tag,f->glyph2ascii[t]);
+    } else {
+       for(t=0;t<f->numchars;t++)
+           swf_SetU8(tag,f->glyph2ascii[t]);
+    }
+    if(f->layout) 
+    {
+       swf_SetU16(tag,f->layout->ascent);
+       swf_SetU16(tag,f->layout->descent);
+       swf_SetU16(tag,f->layout->leading);
+       for(t=0;t<f->numchars;t++)
+           swf_SetU16(tag,f->glyph[t].advance);
+       for(t=0;t<f->numchars;t++) {
+           swf_ResetWriteBits(tag);
+           swf_SetRect(tag,&f->layout->bounds[t]);
+       }
+       swf_SetU16(tag, f->layout->kerningcount);
+       for(t=0;t<f->layout->kerningcount;t++) {
+           if(flags & 4) /* wide codes */ {
+               swf_SetU8(tag,f->layout->kerning[t].char1);
+               swf_SetU8(tag,f->layout->kerning[t].char2);
+           } else {
+               swf_SetU16(tag,f->layout->kerning[t].char1);
+               swf_SetU16(tag,f->layout->kerning[t].char2);
+           }
+           swf_SetU16(tag,f->layout->kerning[t].adjustment);
+       }
+    }
+    return 0;
+}
+    
+void swf_FontAddLayout(SWFFONT * f, int ascent, int descent, int leading)
+{
+    f->layout = (SWFLAYOUT*)malloc(sizeof(SWFLAYOUT));
+    f->layout->ascent = ascent;
+    f->layout->descent = descent;
+    f->layout->leading = leading;
+    f->layout->kerningcount = 0;
+    f->layout->kerning = 0;
+    f->layout->bounds = (SRECT*)malloc(sizeof(SRECT)*f->numchars);
+    memset(f->layout->bounds, 0, sizeof(SRECT)*f->numchars);
+}
+
 int swf_FontSetInfo(TAG * t,SWFFONT * f)
 { int l,i;
   U8 wide=0;
+  U8 flags = 0;
   if ((!t)||(!f)) return -1;
   swf_ResetWriteBits(t);
   swf_SetU16(t,f->id);
@@ -447,7 +570,19 @@ int swf_FontSetInfo(TAG * t,SWFFONT * f)
   swf_SetBlock(t,f->name,l);
   if(f->numchars>=256)
       wide=1;
-  swf_SetU8(t,(f->flags&0xfe)|wide);
+
+  if(f->style & FONT_STYLE_BOLD)
+      flags |= 2;
+  if(f->style & FONT_STYLE_ITALIC)
+      flags |= 4;
+  if(f->style & FONT_ENCODING_ANSI)
+      flags |= 8;
+  if(f->style & FONT_ENCODING_SHIFTJIS)
+      flags |= 16;
+  if(f->style & FONT_ENCODING_UNICODE)
+      flags |= 32;
+    
+  swf_SetU8(t,(flags&0xfe)|wide);
 
   for (i=0;i<f->numchars;i++) {
     if (f->glyph[i].shape)
@@ -711,12 +846,11 @@ void swf_WriteFont(SWFFONT*font, char* filename)
   SRECT r;
   RGBA rgb;
   int f;
-  int useDefineFont2 = 1;
+  int useDefineFont2 = 0;
 
-  if(useDefineFont2) {
-      //fprintf(stderr, "DefineFont2 is not yet supported!\n");
-      useDefineFont2 = 0;
-  }
+  if(font->layout)
+      useDefineFont2 = 1; /* the only thing new in definefont2 
+                            is layout information. */
 
   font->id = WRITEFONTID; //"FN"
 
@@ -724,50 +858,46 @@ void swf_WriteFont(SWFFONT*font, char* filename)
 
   swf.fileVersion    = 4;
   swf.frameRate      = 0x4000;
-  swf.movieSize.xmax = 20*640;
-  swf.movieSize.ymax = 20*480;
 
-  if(!useDefineFont2)
   /* if we use DefineFont1 to store the characters,
      we have to build a textfield to store the
      advance values. While at it, we can also
      make the whole .swf viewable */
-  {
-      t = swf_InsertTag(NULL,ST_SETBACKGROUNDCOLOR);
-      swf.firstTag = t;
-            rgb.r = 0xff;
-            rgb.g = 0xff;
-            rgb.b = 0xff;
-            swf_SetRGB(t,&rgb);
-      t = swf_InsertTag(t,ST_DEFINEFONT);
-  }
-  else
-  {
-      t = swf_InsertTag(NULL,ST_DEFINEFONT);
-      swf.firstTag = t;
-  }
 
-        swf_FontSetDefine(t,font);
-  
-  t = swf_InsertTag(t,ST_DEFINEFONTINFO);
-        swf_FontSetInfo(t,font);
+  /* we now always create viewable swfs, even if we
+     did use definefont2 -mk*/
+  t = swf_InsertTag(NULL,ST_SETBACKGROUNDCOLOR);
+  swf.firstTag = t;
+       rgb.r = 0xff;
+       rgb.g = 0xff;
+       rgb.b = 0xff;
+       swf_SetRGB(t,&rgb);
+  if(!useDefineFont2) {
+    t = swf_InsertTag(t,ST_DEFINEFONT);
+    swf_FontSetDefine(t,font);
+    t = swf_InsertTag(t,ST_DEFINEFONTINFO);
+    swf_FontSetInfo(t,font);
+  } else {
+    t = swf_InsertTag(t,ST_DEFINEFONT2);
+    swf_FontSetDefine2(t,font);
+  }
 
-  if(!useDefineFont2)
+  if(1) //useDefineFont2
   {     int textscale = 400;
        int s;
        int xmax = 0;
-       int ymax = textscale * 2 * 20;
+       int ymax = textscale * 2 * (font->maxascii/16+1);
        U8 gbits,abits;
-       char text[257];
+       char text[MAX_CHAR_PER_FONT+1];
        int x,y;
-       text[256]=0;
-       for(s=0;s<256;s++)
+       text[MAX_CHAR_PER_FONT]=0;
+       for(s=0;s<font->maxascii;s++)
        {
            int g = font->ascii2glyph[s];
            text[s] = s;
            if(g>=0) {
-              if(font->glyph[g].advance*textscale/100 > xmax)
-                  xmax = font->glyph[g].advance*textscale/100;
+              if(font->glyph[g].advance*textscale/200 > xmax)
+                  xmax = font->glyph[g].advance*textscale/200;
            }
        }
        swf.movieSize.xmax = xmax*20;
@@ -795,11 +925,12 @@ void swf_WriteFont(SWFFONT*font, char* filename)
            rgb.r = 0x00;
            rgb.g = 0x00;
            rgb.b = 0x00;
-           for(y=0;y<16;y++)
+           for(y=0;y<=((font->maxascii-1)/16);y++)
            {
-               int c=0,lastx=-1, firstx=0;
+               int c=0,lastx=-1;
+               /* TODO: firstx?? */
                for(x=0;x<16;x++) {
-                   int g = font->ascii2glyph[y*16+x];
+                   int g = (y*16+x<font->maxascii)?font->ascii2glyph[y*16+x]:-1;
                    if(g>=0 && font->glyph[g].shape) {
                        c++;
                        if(lastx<0) 
@@ -810,7 +941,7 @@ void swf_WriteFont(SWFFONT*font, char* filename)
                  swf_TextSetInfoRecord(t,font,textscale,&rgb,lastx+1,textscale*y*2);
                  for(x=0;x<16;x++)
                  {
-                     int g = font->ascii2glyph[y*16+x];
+                     int g = (y*16+x<font->maxascii)?font->ascii2glyph[y*16+x]:-1;
                      if(g>=0 && font->glyph[g].shape) {
                        if(lastx != x*xmax) {
                            swf_TextSetInfoRecord(t,0,0,0,x*xmax+1,0);
@@ -844,3 +975,40 @@ void swf_WriteFont(SWFFONT*font, char* filename)
 }
 
 
+void swf_SetEditText(TAG*tag, U16 flags, SRECT r, char*text, RGBA*color, 
+       int maxlength, U16 font, U16 height, EditTextLayout*layout, char*variable)
+{
+    swf_SetRect(tag,&r);
+    swf_ResetWriteBits(tag);
+
+    flags &= ~(ET_HASTEXT|ET_HASTEXTCOLOR|ET_HASMAXLENGTH|ET_HASFONT|ET_HASLAYOUT);
+    if(text) flags |= ET_HASTEXT;
+    if(color) flags |= ET_HASTEXTCOLOR;
+    if(maxlength) flags |= ET_HASMAXLENGTH;
+    if(font) flags |= ET_HASFONT;
+    if(layout) flags |= ET_HASLAYOUT;
+
+    swf_SetBits(tag, flags, 16);
+
+    if(flags & ET_HASFONT) {
+       swf_SetU16(tag, font); //font
+       swf_SetU16(tag, height); //fontheight
+    }
+    if(flags & ET_HASTEXTCOLOR) {
+       swf_SetRGBA(tag, color);
+    }
+    if(flags & ET_HASMAXLENGTH) {
+       swf_SetU16(tag, maxlength); //maxlength
+    }
+    if(flags & ET_HASLAYOUT) {
+       swf_SetU8(tag,layout->align); //align
+       swf_SetU16(tag,layout->leftmargin); //left margin
+       swf_SetU16(tag,layout->rightmargin); //right margin
+       swf_SetU16(tag,layout->indent); //indent
+       swf_SetU16(tag,layout->leading); //leading
+    }
+    swf_SetString(tag, variable);
+    if(flags & ET_HASTEXT)
+       swf_SetString(tag,text);
+}
+