fixed a couple of bugs in alignzone detector
authorMatthias Kramm <kramm@quiss.org>
Thu, 5 Nov 2009 04:49:43 +0000 (20:49 -0800)
committerMatthias Kramm <kramm@quiss.org>
Thu, 5 Nov 2009 04:49:43 +0000 (20:49 -0800)
lib/devices/swf.c
lib/modules/swfalignzones.c
lib/modules/swftext.c
lib/rfxswf.h

index 121d49c..3277938 100644 (file)
@@ -3117,6 +3117,6 @@ static void swf_drawchar(gfxdevice_t*dev, gfxfont_t*font, int glyph, gfxcolor_t*
     } else {
        i->chardata = charbuffer_append(i->chardata, i->swffont, glyph, x, y, i->current_font_size, *(RGBA*)color, &i->fontmatrix);
     }
-    swf_FontUseGlyph(i->swffont, glyph);
+    swf_FontUseGlyph(i->swffont, glyph, i->current_font_size);
     return;
 }
index 0c5f663..a102a9b 100644 (file)
@@ -34,13 +34,13 @@ static void draw_line_xy(float*row,float*column, float x1, float y1, float x2, f
     draw_line(column, y1, y2, x1, x2, area->ymin, area->ymax);
 }
 
-static void find_best(float*_row, int width, int*_x1, int*_x2, int min_dist)
+static void find_best(float*_row, int width, int*_x1, int*_x2, int min_size, int min, int max, char debug)
 {
     int x1=-1, x2=-1;
-    float max1=-1,max2=-1;
+    float max1=-1e20,max2=-1e20;
     int t;
     float*row = malloc(sizeof(float)*(width+1));
-    int filter_size = 100;
+    int filter_size = 20;
     float* filter = malloc(sizeof(float)*(filter_size*2+1));
     double var = filter_size/3;
     for(t=-filter_size;t<=filter_size;t++) {
@@ -48,7 +48,7 @@ static void find_best(float*_row, int width, int*_x1, int*_x2, int min_dist)
         float r = v*v/2;
        filter[filter_size+t] = exp(-r);
     }
-    filter[0]=1;filter_size=0;
+    //filter[0]=1;filter_size=0;
 
     for(t=0;t<=width;t++) {
        int s;
@@ -67,11 +67,29 @@ static void find_best(float*_row, int width, int*_x1, int*_x2, int min_dist)
            x1 = t;
        }
     }
-    // invalidate everything around the maximum
-    for(t=-min_dist+1;t<min_dist;t++) {
-       if(t+x1<0 || t+x1>width) continue;
-       row[t+x1]=-1;
+
+    double scale = min_size/1024.0;
+    for(t=0;t<=width;t++) {
+       if(t==x1) {
+           row[t]=-1e20;
+           continue;
+       }
+       double r1 = (t<x1?t:x1)*scale;
+       double r2 = (t<x1?x1:t)*scale;
+       double d1 = r2-r1;
+       double d2 = d1+2;
+       double s = d2/d1;
+       double ext1 = r1;
+       double ext2 = width*scale-r2;
+       double add1 = ext1*s - ext1;
+       double add2 = ext2*s - ext2;
+
+       /* don't allow the char to grow more than one pixel */
+       if(add1>=1 || add2>=1) {
+           row[t]=-1e20;
+       }
     }
+
     for(t=0;t<=width;t++) {
        if(row[t]>max2) {
            max2 = row[t];
@@ -79,12 +97,25 @@ static void find_best(float*_row, int width, int*_x1, int*_x2, int min_dist)
        }
     }
 
-    if(x1>0 && x2>0 && x1>x2) {int x=x1;x1=x2;x2=x;}
+    if(x1>=0 && x2>=0 && x1>x2) {int x=x1;x1=x2;x2=x;}
     *_x1=x1;
     *_x2=x2;
     free(row);
 }
 
+static int find_min_distance(int min_size, int height)
+{
+    /* find a minimum distance between two alignzones so
+       that when they both, due to pixel snapping, move 
+       into opposite directions, the subsequent character
+       scaling doesn't cause the upper/lower end of the char
+       to move outwards more than m pixels */
+    int m = 4;
+    double scale = min_size / 1024.0;
+    double max_move = (2 * 1.0 / scale)/m;
+    return (int)(height*max_move);
+}
+
 static ALIGNZONE detect_for_char(SWFFONT * f, int nr)
 {
     SWFGLYPH*g = &f->glyph[nr];
@@ -131,16 +162,15 @@ static ALIGNZONE detect_for_char(SWFFONT * f, int nr)
     }
 
     int t;
-
+    
     /* find two best x values */
     int x1=-1,y1=-1,x2=-1,y2=-1;
-    //int min_dist = 4000;
-    int min_dist = 1;
-    find_best(row,width,&x1,&x2,min_dist);
-    find_best(column,height,&y1,&y2,min_dist);
+    find_best(row,width,&x1,&x2,f->use->smallest_size,b.xmin,b.xmax,0);
+    char debug = f->glyph2ascii[nr]=='o' && f->id==7;
+    find_best(column,height,&y1,&y2,f->use->smallest_size,b.ymin,b.ymax,debug);
 
-    if(x1>=0) a.x  = floatToF16((x1+b.xmin) / 20480.0);
-    if(x2>=0) a.dx = floatToF16((x2-x1) / 20480.0);
+    //if(x1>=0) a.x  = floatToF16((x1+b.xmin) / 20480.0);
+    //if(x2>=0) a.dx = floatToF16((x2-x1) / 20480.0);
     if(y1>=0) a.y  = floatToF16((y1+b.ymin) / 20480.0);
     if(y2>=0) a.dy = floatToF16((y2-y1) / 20480.0);
     return a;
@@ -158,7 +188,7 @@ void swf_FontCreateAlignZones(SWFFONT * f)
 
     
     f->alignzones = (ALIGNZONE*)rfx_calloc(sizeof(ALIGNZONE)*f->numchars);
-    f->alignzone_flags = FONTALIGN_THIN;
+    f->alignzone_flags = FONTALIGN_MEDIUM;
 
     if(!f->layout) {
        int t;
index b5d74f0..194ec72 100644 (file)
@@ -853,6 +853,7 @@ int swf_FontInitUsage(SWFFONT * f)
     }
     f->use = (FONTUSAGE*)rfx_alloc(sizeof(FONTUSAGE));
     f->use->is_reduced = 0;
+    f->use->smallest_size = 0xffff;
     f->use->used_glyphs = 0;
     f->use->chars = (int*)rfx_calloc(sizeof(f->use->chars[0]) * f->numchars);
     f->use->glyphs_specified = 0;
@@ -873,13 +874,13 @@ int swf_FontUse(SWFFONT * f, U8 * s)
        return -1;
     while (*s) {
        if(*s < f->maxascii && f->ascii2glyph[*s]>=0)
-           swf_FontUseGlyph(f, f->ascii2glyph[*s]);
+           swf_FontUseGlyph(f, f->ascii2glyph[*s], /*FIXME*/0xffff);
        s++;
     }
     return 0;
 }
 
-int swf_FontUseUTF8(SWFFONT * f, U8 * s)
+int swf_FontUseUTF8(SWFFONT * f, U8 * s, U16 size)
 {
     if( (!s))
        return -1;
@@ -888,7 +889,7 @@ int swf_FontUseUTF8(SWFFONT * f, U8 * s)
     {
        ascii = readUTF8char(&s);
        if(ascii < f->maxascii && f->ascii2glyph[ascii]>=0)
-           swf_FontUseGlyph(f, f->ascii2glyph[ascii]);
+           swf_FontUseGlyph(f, f->ascii2glyph[ascii], size);
     }
     return 0;
 }
@@ -905,7 +906,7 @@ int swf_FontUseAll(SWFFONT* f)
     return 0;
 }
 
-int swf_FontUseGlyph(SWFFONT * f, int glyph)
+int swf_FontUseGlyph(SWFFONT * f, int glyph, U16 size)
 {
     if (!f->use)
        swf_FontInitUsage(f);
@@ -914,6 +915,8 @@ int swf_FontUseGlyph(SWFFONT * f, int glyph)
     if(!f->use->chars[glyph])
        f->use->used_glyphs++;
     f->use->chars[glyph] = 1;
+    if(size && size < f->use->smallest_size)
+       f->use->smallest_size = size;
     return 0;
 }
 
index 8c102c9..0baf61e 100644 (file)
@@ -535,6 +535,7 @@ typedef struct _FONTUSAGE
   char is_reduced;
   int used_glyphs;
   int glyphs_specified;
+  U16 smallest_size;
 } FONTUSAGE;
 
 #define FONT_STYLE_BOLD 1
@@ -629,9 +630,9 @@ int swf_FontReduce(SWFFONT * f);
 int swf_FontReduce_swfc(SWFFONT * f);
 
 int swf_FontInitUsage(SWFFONT * f);
-int swf_FontUseGlyph(SWFFONT * f, int glyph);
+int swf_FontUseGlyph(SWFFONT * f, int glyph, U16 size);
 int swf_FontUseAll(SWFFONT* f);
-int swf_FontUseUTF8(SWFFONT * f, U8 * s);
+int swf_FontUseUTF8(SWFFONT * f, U8 * s, U16 size);
 int swf_FontUse(SWFFONT* f,U8 * s);
 
 int swf_FontSetDefine(TAG * t,SWFFONT * f);