X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=lib%2Fmodules%2Fswfalignzones.c;h=d58cea2197fb06033355911af56dcd4aefbb84d7;hb=e584fab17969f34332c92f7bf67ca2926668e197;hp=0c5f6637b3193eb5530c6d70a81562b97af8aac6;hpb=9b57fcd7feaf69fd54447174b19f5f377706bb15;p=swftools.git diff --git a/lib/modules/swfalignzones.c b/lib/modules/swfalignzones.c index 0c5f663..d58cea2 100644 --- a/lib/modules/swfalignzones.c +++ b/lib/modules/swfalignzones.c @@ -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 from, int to, int num, 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; @@ -61,48 +61,67 @@ static void find_best(float*_row, int width, int*_x1, int*_x2, int min_dist) row[t] = sum; } - for(t=0;t<=width;t++) { + for(t=from;t<=to;t++) { if(row[t]>max1) { max1 = row[t]; x1 = t; } } - // invalidate everything around the maximum - for(t=-min_dist+1;twidth) continue; - row[t+x1]=-1; - } - for(t=0;t<=width;t++) { - if(row[t]>max2) { - max2 = row[t]; - x2 = t; + + + if(num<=1) { + *_x1=x1; + } else { + double scale = min_size/1024.0; + for(t=from;t<=to;t++) { + if(t==x1) { + row[t]=-1e20; + continue; + } + double r1 = (t=1 || add2>=1) { + row[t]=-1e20; + } } + + for(t=from;t<=to;t++) { + if(row[t]>max2) { + max2 = row[t]; + x2 = t; + } + } + + if(x1>=0 && x2>=0 && x1>x2) {int x=x1;x1=x2;x2=x;} + + *_x1=x1; + *_x2=x2; } + - if(x1>0 && x2>0 && x1>x2) {int x=x1;x1=x2;x2=x;} - *_x1=x1; - *_x2=x2; free(row); } -static ALIGNZONE detect_for_char(SWFFONT * f, int nr) +static void negate_y(SRECT* b) { - SWFGLYPH*g = &f->glyph[nr]; - SRECT b = f->layout->bounds[nr]; - ALIGNZONE a = {0xffff,0xffff,0xffff,0xffff}; - // negate y - int by1=b.ymin,by2=b.ymax; - b.ymin = -by2; - b.ymax = -by1; + int by1=b->ymin,by2=b->ymax; + b->ymin = -by2; + b->ymax = -by1; +} - int width = b.xmax - b.xmin + 1; - int height = b.ymax - b.ymin + 1; - if(!width || !height) - return a; - - float*row = rfx_calloc(sizeof(float)*width); - float*column = rfx_calloc(sizeof(float)*height); +static void draw_char(SWFFONT * f, int nr, float*row, float*column, SRECT b) +{ + SWFGLYPH*g = &f->glyph[nr]; SHAPE2*s = swf_ShapeToShape2(g->shape); SHAPELINE*l = s->lines; @@ -129,20 +148,34 @@ static ALIGNZONE detect_for_char(SWFFONT * f, int nr) y = l->y; l = l->next; } +} - int t; +static ALIGNZONE detect_for_char(SWFFONT * f, int nr, float*row, float*column, SRECT font_bbox, SRECT char_bbox) +{ + ALIGNZONE a = {0xffff,0xffff,0xffff,0xffff}; + int width = font_bbox.xmax - font_bbox.xmin; + int height = font_bbox.ymax - font_bbox.ymin; + if(!width || !height) + return a; /* 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); - - 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); + + int nr_x = 1; + find_best(row, width, &x1, &x2, f->use->smallest_size, + char_bbox.xmin - font_bbox.xmin, + char_bbox.xmax - font_bbox.xmin, nr_x, + 0); + if(nr_x>0 && x1>=0) a.x = floatToF16((x1+font_bbox.xmin) / 20480.0); + if(nr_x>1 && x2>=0) a.dx = floatToF16((x2-x1) / 20480.0); + + find_best(column, height, &y1, &y2, f->use->smallest_size, + char_bbox.ymin - font_bbox.ymin, + char_bbox.ymax - font_bbox.ymin, 2, + 0); + if(y1>=0) a.y = floatToF16((y1+font_bbox.ymin) / 20480.0); if(y2>=0) a.dy = floatToF16((y2-y1) / 20480.0); + return a; } @@ -156,9 +189,8 @@ void swf_FontCreateAlignZones(SWFFONT * f) return; } - f->alignzones = (ALIGNZONE*)rfx_calloc(sizeof(ALIGNZONE)*f->numchars); - f->alignzone_flags = FONTALIGN_THIN; + f->alignzone_flags = FONTALIGN_MEDIUM; if(!f->layout) { int t; @@ -171,16 +203,35 @@ void swf_FontCreateAlignZones(SWFFONT * f) } } else { int t; + SRECT bounds = {0,0,0,0}; + for(t=0;tnumchars;t++) { - f->alignzones[t] = detect_for_char(f, t); + SRECT b = f->layout->bounds[t]; + negate_y(&b); + swf_ExpandRect2(&bounds, &b); } - } -/* - "-^_~\xad\xaf+`\xac\xb7\xf7" //chars for which to detect one y value - "#=:;\xb1" //chars for which to detect two y values - "\"\xa8" //chars for which to detect two x values -*/ + int width = bounds.xmax - bounds.xmin; + int height = bounds.ymax - bounds.ymin; + float*row = rfx_calloc(sizeof(float)*(width+1)); + float*column_global = rfx_calloc(sizeof(float)*(height+1)); + float*column = rfx_calloc(sizeof(float)*(height+1)); + + for(t=0;tnumchars;t++) { + draw_char(f, t, row, column_global, bounds); + } + for(t=0;t<=height;t++) {column_global[t]/=f->numchars/2;} + + for(t=0;tnumchars;t++) { + memcpy(column, column_global, sizeof(float)*(height+1)); + memset(row, 0, sizeof(float)*(width+1)); + draw_char(f, t, row, column, bounds); + + SRECT b = f->layout->bounds[t]; + negate_y(&b); + f->alignzones[t] = detect_for_char(f, t, row, column, bounds, b); + } + } } void swf_FontSetAlignZones(TAG*t, SWFFONT *f)