FT_Outline_Embolden( FT_Outline* outline, FT_Pos strength ) { FT_Vector* points; FT_Vector v_prev, v_first, v_next, v_cur; FT_Angle rotate, angle_in, angle_out; FT_Int c, n, first; FT_Int orientation; if ( !outline ) return FT_Err_Invalid_Argument; strength /= 2; if ( strength == 0 ) return FT_Err_Ok; orientation = FT_Outline_Get_Orientation( outline ); if ( orientation == FT_ORIENTATION_NONE ) { if ( outline->n_contours ) return FT_Err_Invalid_Argument; else return FT_Err_Ok; } if ( orientation == FT_ORIENTATION_TRUETYPE ) rotate = -FT_ANGLE_PI2; else rotate = FT_ANGLE_PI2; points = outline->points; first = 0; for ( c = 0; c < outline->n_contours; c++ ) { int last = outline->contours[c]; v_first = points[first]; v_prev = points[last]; v_cur = v_first; for ( n = first; n <= last; n++ ) { FT_Vector in, out; FT_Angle angle_diff; FT_Pos d; FT_Fixed scale; if ( n < last ) v_next = points[n + 1]; else v_next = v_first; /* compute the in and out vectors */ in.x = v_cur.x - v_prev.x; in.y = v_cur.y - v_prev.y; out.x = v_next.x - v_cur.x; out.y = v_next.y - v_cur.y; angle_in = FT_Atan2( in.x, in.y ); angle_out = FT_Atan2( out.x, out.y ); angle_diff = FT_Angle_Diff( angle_in, angle_out ); scale = FT_Cos( angle_diff / 2 ); if ( scale < 0x4000L && scale > -0x4000L ) in.x = in.y = 0; else { d = FT_DivFix( strength, scale ); FT_Vector_From_Polar( &in, d, angle_in + angle_diff / 2 - rotate ); } outline->points[n].x = v_cur.x + strength + in.x; outline->points[n].y = v_cur.y + strength + in.y; v_prev = v_cur; v_cur = v_next; } first = last + 1; } return FT_Err_Ok; }
static void GK_Outline_Embolden(FT_Outline* outline,FT_Pos strength,int* x_left,int* x_right,int* y_bottom,int* y_top) { FT_Vector* points; FT_Vector v_prev, v_first, v_next, v_cur; FT_Angle rotate, angle_in, angle_out; FT_Int c, n, first = 0; FT_Int orientation; FT_Int min_x = 35565, max_x = -35565, min_y = 35565, max_y = -35565; FT_Int new_min_x = 35565, new_max_x = -35565, new_min_y = 35565, new_max_y = -35565; if (!outline) return; strength /= 2; if ( strength == 0 ) return; orientation = FT_Outline_Get_Orientation(outline); if (orientation == FT_ORIENTATION_NONE) return; #ifdef GLYPH_LOG if (glyph_log) { fprintf(glyph_log," Emboldening the outline by %ld:\n",strength); } #endif if (orientation == FT_ORIENTATION_TRUETYPE) rotate = -FT_ANGLE_PI2; else rotate = FT_ANGLE_PI2; points = outline->points; for ( c = 0; c < outline->n_contours; c++ ) { int last = outline->contours[c]; v_first = points[first]; v_prev = points[last]; v_cur = v_first; for ( n = first; n <= last; n++ ) { FT_Vector in, out; FT_Angle angle_diff; FT_Pos d; FT_Fixed scale; if ( n < last ) v_next = points[n + 1]; else v_next = v_first; /* compute the in and out vectors */ in.x = v_cur.x - v_prev.x; in.y = v_cur.y - v_prev.y; out.x = v_next.x - v_cur.x; out.y = v_next.y - v_cur.y; angle_in = FT_Atan2( in.x, in.y ); angle_out = FT_Atan2( out.x, out.y ); angle_diff = FT_Angle_Diff( angle_in, angle_out ); scale = FT_Cos( angle_diff / 2 ); if ( scale < 0x4000L && scale > -0x4000L ) in.x = in.y = 0; else { d = FT_DivFix( strength, scale ); FT_Vector_From_Polar( &in, d, angle_in + angle_diff / 2 - rotate ); } outline->points[n].x = v_cur.x + strength + in.x; outline->points[n].y = v_cur.y + strength + in.y; if (v_cur.x < min_x) min_x = v_cur.x; if (v_cur.x > max_x) max_x = v_cur.x; if (v_cur.y < min_y) min_y = v_cur.y; if (v_cur.y > max_y) max_y = v_cur.y; if (outline->points[n].x < new_min_x) new_min_x = outline->points[n].x; if (outline->points[n].x > new_max_x) new_max_x = outline->points[n].x; if (outline->points[n].y < new_min_y) new_min_y = outline->points[n].y; if (outline->points[n].y > new_max_y) new_max_y = outline->points[n].y; v_prev = v_cur; v_cur = v_next; } first = last + 1; } *x_left = min_x - new_min_x; *x_right = new_max_x - max_x; *y_top = new_max_y - max_y; *y_bottom = min_y - new_min_y; #ifdef GLYPH_LOG if (glyph_log) { fprintf(glyph_log," (%d..%d x %d..%d) -> (%d..%d x %d..%d)\n", min_x,max_x,min_y,max_y,new_min_x,new_max_x,new_min_y,new_max_y); } #endif }