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_size, int min, int max, char debug)
+#include <assert.h>
+
+static void find_best(float*_row, int width, int*_x1, int*_x2, int min_size, int from, int to, char debug)
{
+ assert(from>=0);
+ assert(to>=0);
int x1=-1, x2=-1;
float max1=-1e20,max2=-1e20;
int t;
row[t] = sum;
}
- for(t=0;t<=width;t++) {
+ for(t=from;t<=to;t++) {
if(row[t]>max1) {
max1 = row[t];
x1 = t;
}
double scale = min_size/1024.0;
- for(t=0;t<=width;t++) {
+ for(t=from;t<=to;t++) {
if(t==x1) {
row[t]=-1e20;
continue;
double d1 = r2-r1;
double d2 = d1+2;
double s = d2/d1;
- double ext1 = r1;
- double ext2 = width*scale-r2;
+ double ext1 = r1-from*scale;
+ double ext2 = to*scale-r2;
double add1 = ext1*s - ext1;
double add2 = ext2*s - ext2;
}
}
- for(t=0;t<=width;t++) {
+ for(t=from;t<=to;t++) {
if(row[t]>max2) {
max2 = row[t];
x2 = t;
free(row);
}
-static int find_min_distance(int min_size, int height)
+static void negate_y(SRECT* b)
{
- /* 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);
+ // negate y
+ int by1=b->ymin,by2=b->ymax;
+ b->ymin = -by2;
+ b->ymax = -by1;
}
-static ALIGNZONE detect_for_char(SWFFONT * f, int nr)
+static void draw_char(SWFFONT * f, int nr, float*row, float*column, 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 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);
SHAPE2*s = swf_ShapeToShape2(g->shape);
SHAPELINE*l = s->lines;
y = l->y;
l = l->next;
}
+}
+
+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;
- int t;
-
/* find two best x values */
int x1=-1,y1=-1,x2=-1,y2=-1;
- 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);
+ find_best(row, width, &x1, &x2, f->use->smallest_size,
+ char_bbox.xmin - font_bbox.xmin,
+ char_bbox.xmax - font_bbox.xmin,
+ 0);
+ find_best(column, height, &y1, &y2, f->use->smallest_size,
+ char_bbox.ymin - font_bbox.ymin,
+ char_bbox.ymax - font_bbox.ymin,
+ 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(y1>=0) a.y = floatToF16((y1+font_bbox.ymin) / 20480.0);
if(y2>=0) a.dy = floatToF16((y2-y1) / 20480.0);
return a;
}
return;
}
-
f->alignzones = (ALIGNZONE*)rfx_calloc(sizeof(ALIGNZONE)*f->numchars);
f->alignzone_flags = FONTALIGN_MEDIUM;
}
} else {
int t;
+ SRECT bounds = {0,0,0,0};
+
for(t=0;t<f->numchars;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 = rfx_calloc(sizeof(float)*(height+1));
+ float*row2 = rfx_calloc(sizeof(float)*(width+1));
+ float*column2 = rfx_calloc(sizeof(float)*(height+1));
+
+ for(t=0;t<f->numchars;t++) {
+ draw_char(f, t, row, column, bounds);
+ }
+ for(t=0;t<=width;t++) {row[t]/=f->numchars/2;}
+ for(t=0;t<=height;t++) {column[t]/=f->numchars/2;}
+
+ for(t=0;t<f->numchars;t++) {
+ memcpy(row2, row, sizeof(float)*(width+1));
+ memcpy(column2, column, sizeof(float)*(height+1));
+ //draw_char(f, t, row2, column2, bounds);
+
+ SRECT b = f->layout->bounds[t];
+ negate_y(&b);
+ f->alignzones[t] = detect_for_char(f, t, row2, column2, bounds, b);
+ }
+ }
}
void swf_FontSetAlignZones(TAG*t, SWFFONT *f)