diff options
Diffstat (limited to 'source/blender/blenlib/intern/freetypefont.c')
-rw-r--r-- | source/blender/blenlib/intern/freetypefont.c | 152 |
1 files changed, 60 insertions, 92 deletions
diff --git a/source/blender/blenlib/intern/freetypefont.c b/source/blender/blenlib/intern/freetypefont.c index 79f009e8aa3..b3392e28223 100644 --- a/source/blender/blenlib/intern/freetypefont.c +++ b/source/blender/blenlib/intern/freetypefont.c @@ -73,7 +73,7 @@ static VChar *freetypechar_to_vchar(FT_Face face, FT_ULong charcode, VFontData * FT_UInt glyph_index; FT_Outline ftoutline; float dx, dy; - int j, k, l, m = 0; + int j, k, l, l_first = 0; /* * Generate the character 3D data @@ -84,7 +84,8 @@ static VChar *freetypechar_to_vchar(FT_Face face, FT_ULong charcode, VFontData * /* If loading succeeded, convert the FT glyph to the internal format */ if (!err) { - int *npoints; + /* initialize as -1 to add 1 on first loop each time */ + int contour_prev; int *onpoints; /* First we create entry for the new character to the character list */ @@ -101,28 +102,24 @@ static VChar *freetypechar_to_vchar(FT_Face face, FT_ULong charcode, VFontData * BLI_ghash_insert(vfd->characters, SET_UINT_IN_POINTER(che->index), che); /* Start converting the FT data */ - npoints = (int *)MEM_mallocN((ftoutline.n_contours) * sizeof(int), "endpoints"); onpoints = (int *)MEM_callocN((ftoutline.n_contours) * sizeof(int), "onpoints"); - /* calculate total points of each contour */ - for (j = 0; j < ftoutline.n_contours; j++) { - if (j == 0) - npoints[j] = ftoutline.contours[j] + 1; - else - npoints[j] = ftoutline.contours[j] - ftoutline.contours[j - 1]; - } - /* get number of on-curve points for beziertriples (including conic virtual on-points) */ - for (j = 0; j < ftoutline.n_contours; j++) { - for (k = 0; k < npoints[j]; k++) { + for (j = 0, contour_prev = -1; j < ftoutline.n_contours; j++) { + const int n = ftoutline.contours[j] - contour_prev; + contour_prev = ftoutline.contours[j]; + + for (k = 0; k < n; k++) { l = (j > 0) ? (k + ftoutline.contours[j - 1] + 1) : k; + if (k == 0) l_first = l; if (ftoutline.tags[l] == FT_Curve_Tag_On) onpoints[j]++; - if (k < npoints[j] - 1) { - if (ftoutline.tags[l] == FT_Curve_Tag_Conic && - ftoutline.tags[l + 1] == FT_Curve_Tag_Conic) + { + const int l_next = (k < n - 1) ? (l + 1) : l_first; + if (ftoutline.tags[l] == FT_Curve_Tag_Conic && + ftoutline.tags[l_next] == FT_Curve_Tag_Conic) { onpoints[j]++; } @@ -131,7 +128,10 @@ static VChar *freetypechar_to_vchar(FT_Face face, FT_ULong charcode, VFontData * } /* contour loop, bezier & conic styles merged */ - for (j = 0; j < ftoutline.n_contours; j++) { + for (j = 0, contour_prev = -1; j < ftoutline.n_contours; j++) { + const int n = ftoutline.contours[j] - contour_prev; + contour_prev = ftoutline.contours[j]; + /* add new curve */ nu = (Nurb *)MEM_callocN(sizeof(struct Nurb), "objfnt_nurb"); bezt = (BezTriple *)MEM_callocN((onpoints[j]) * sizeof(BezTriple), "objfnt_bezt"); @@ -145,15 +145,18 @@ static VChar *freetypechar_to_vchar(FT_Face face, FT_ULong charcode, VFontData * nu->bezt = bezt; /* individual curve loop, start-end */ - for (k = 0; k < npoints[j]; k++) { - if (j > 0) l = k + ftoutline.contours[j - 1] + 1; else l = k; - if (k == 0) m = l; + for (k = 0; k < n; k++) { + l = (j > 0) ? (k + ftoutline.contours[j - 1] + 1) : k; + if (k == 0) l_first = l; /* virtual conic on-curve points */ - if (k < npoints[j] - 1) { - if (ftoutline.tags[l] == FT_Curve_Tag_Conic && ftoutline.tags[l + 1] == FT_Curve_Tag_Conic) { - dx = (ftoutline.points[l].x + ftoutline.points[l + 1].x) * scale / 2.0f; - dy = (ftoutline.points[l].y + ftoutline.points[l + 1].y) * scale / 2.0f; + { + const int l_next = (k < n - 1) ? (l + 1) : l_first; + if (ftoutline.tags[l] == FT_Curve_Tag_Conic && + ftoutline.tags[l_next] == FT_Curve_Tag_Conic) + { + dx = (ftoutline.points[l].x + ftoutline.points[l_next].x) * scale / 2.0f; + dy = (ftoutline.points[l].y + ftoutline.points[l_next].y) * scale / 2.0f; /* left handle */ bezt->vec[0][0] = (dx + (2 * ftoutline.points[l].x) * scale) / 3.0f; @@ -164,8 +167,8 @@ static VChar *freetypechar_to_vchar(FT_Face face, FT_ULong charcode, VFontData * bezt->vec[1][1] = dy; /* right handle */ - bezt->vec[2][0] = (dx + (2 * ftoutline.points[l + 1].x) * scale) / 3.0f; - bezt->vec[2][1] = (dy + (2 * ftoutline.points[l + 1].y) * scale) / 3.0f; + bezt->vec[2][0] = (dx + (2 * ftoutline.points[l_next].x) * scale) / 3.0f; + bezt->vec[2][1] = (dy + (2 * ftoutline.points[l_next].y) * scale) / 3.0f; bezt->h1 = bezt->h2 = HD_ALIGN; bezt->radius = 1.0f; @@ -175,40 +178,24 @@ static VChar *freetypechar_to_vchar(FT_Face face, FT_ULong charcode, VFontData * /* on-curve points */ if (ftoutline.tags[l] == FT_Curve_Tag_On) { + const int l_prev = (k > 0) ? (l - 1) : ftoutline.contours[j]; + const int l_next = (k < n - 1) ? (l + 1) : l_first; + /* left handle */ - if (k > 0) { - if (ftoutline.tags[l - 1] == FT_Curve_Tag_Cubic) { - bezt->vec[0][0] = ftoutline.points[l - 1].x * scale; - bezt->vec[0][1] = ftoutline.points[l - 1].y * scale; - bezt->h1 = HD_FREE; - } - else if (ftoutline.tags[l - 1] == FT_Curve_Tag_Conic) { - bezt->vec[0][0] = (ftoutline.points[l].x + (2 * ftoutline.points[l - 1].x)) * scale / 3.0f; - bezt->vec[0][1] = (ftoutline.points[l].y + (2 * ftoutline.points[l - 1].y)) * scale / 3.0f; - bezt->h1 = HD_FREE; - } - else { - bezt->vec[0][0] = ftoutline.points[l].x * scale - (ftoutline.points[l].x - ftoutline.points[l - 1].x) * scale / 3.0f; - bezt->vec[0][1] = ftoutline.points[l].y * scale - (ftoutline.points[l].y - ftoutline.points[l - 1].y) * scale / 3.0f; - bezt->h1 = HD_VECT; - } + if (ftoutline.tags[l_prev] == FT_Curve_Tag_Cubic) { + bezt->vec[0][0] = ftoutline.points[l_prev].x * scale; + bezt->vec[0][1] = ftoutline.points[l_prev].y * scale; + bezt->h1 = HD_FREE; + } + else if (ftoutline.tags[l_prev] == FT_Curve_Tag_Conic) { + bezt->vec[0][0] = (ftoutline.points[l].x + (2 * ftoutline.points[l_prev].x)) * scale / 3.0f; + bezt->vec[0][1] = (ftoutline.points[l].y + (2 * ftoutline.points[l_prev].y)) * scale / 3.0f; + bezt->h1 = HD_FREE; } - else { /* first point on curve */ - if (ftoutline.tags[ftoutline.contours[j]] == FT_Curve_Tag_Cubic) { - bezt->vec[0][0] = ftoutline.points[ftoutline.contours[j]].x * scale; - bezt->vec[0][1] = ftoutline.points[ftoutline.contours[j]].y * scale; - bezt->h1 = HD_FREE; - } - else if (ftoutline.tags[ftoutline.contours[j]] == FT_Curve_Tag_Conic) { - bezt->vec[0][0] = (ftoutline.points[l].x + (2 * ftoutline.points[ftoutline.contours[j]].x)) * scale / 3.0f; - bezt->vec[0][1] = (ftoutline.points[l].y + (2 * ftoutline.points[ftoutline.contours[j]].y)) * scale / 3.0f; - bezt->h1 = HD_FREE; - } - else { - bezt->vec[0][0] = ftoutline.points[l].x * scale - (ftoutline.points[l].x - ftoutline.points[ftoutline.contours[j]].x) * scale / 3.0f; - bezt->vec[0][1] = ftoutline.points[l].y * scale - (ftoutline.points[l].y - ftoutline.points[ftoutline.contours[j]].y) * scale / 3.0f; - bezt->h1 = HD_VECT; - } + else { + bezt->vec[0][0] = ftoutline.points[l].x * scale - (ftoutline.points[l].x - ftoutline.points[l_prev].x) * scale / 3.0f; + bezt->vec[0][1] = ftoutline.points[l].y * scale - (ftoutline.points[l].y - ftoutline.points[l_prev].y) * scale / 3.0f; + bezt->h1 = HD_VECT; } /* midpoint (on-curve point) */ @@ -216,39 +203,20 @@ static VChar *freetypechar_to_vchar(FT_Face face, FT_ULong charcode, VFontData * bezt->vec[1][1] = ftoutline.points[l].y * scale; /* right handle */ - if (k < (npoints[j] - 1)) { - if (ftoutline.tags[l + 1] == FT_Curve_Tag_Cubic) { - bezt->vec[2][0] = ftoutline.points[l + 1].x * scale; - bezt->vec[2][1] = ftoutline.points[l + 1].y * scale; - bezt->h2 = HD_FREE; - } - else if (ftoutline.tags[l + 1] == FT_Curve_Tag_Conic) { - bezt->vec[2][0] = (ftoutline.points[l].x + (2 * ftoutline.points[l + 1].x)) * scale / 3.0f; - bezt->vec[2][1] = (ftoutline.points[l].y + (2 * ftoutline.points[l + 1].y)) * scale / 3.0f; - bezt->h2 = HD_FREE; - } - else { - bezt->vec[2][0] = ftoutline.points[l].x * scale - (ftoutline.points[l].x - ftoutline.points[l + 1].x) * scale / 3.0f; - bezt->vec[2][1] = ftoutline.points[l].y * scale - (ftoutline.points[l].y - ftoutline.points[l + 1].y) * scale / 3.0f; - bezt->h2 = HD_VECT; - } + if (ftoutline.tags[l_next] == FT_Curve_Tag_Cubic) { + bezt->vec[2][0] = ftoutline.points[l_next].x * scale; + bezt->vec[2][1] = ftoutline.points[l_next].y * scale; + bezt->h2 = HD_FREE; } - else { /* last point on curve */ - if (ftoutline.tags[m] == FT_Curve_Tag_Cubic) { - bezt->vec[2][0] = ftoutline.points[m].x * scale; - bezt->vec[2][1] = ftoutline.points[m].y * scale; - bezt->h2 = HD_FREE; - } - else if (ftoutline.tags[m] == FT_Curve_Tag_Conic) { - bezt->vec[2][0] = (ftoutline.points[l].x + (2 * ftoutline.points[m].x)) * scale / 3.0f; - bezt->vec[2][1] = (ftoutline.points[l].y + (2 * ftoutline.points[m].y)) * scale / 3.0f; - bezt->h2 = HD_FREE; - } - else { - bezt->vec[2][0] = ftoutline.points[l].x * scale - (ftoutline.points[l].x - ftoutline.points[m].x) * scale / 3.0f; - bezt->vec[2][1] = ftoutline.points[l].y * scale - (ftoutline.points[l].y - ftoutline.points[m].y) * scale / 3.0f; - bezt->h2 = HD_VECT; - } + else if (ftoutline.tags[l_next] == FT_Curve_Tag_Conic) { + bezt->vec[2][0] = (ftoutline.points[l].x + (2 * ftoutline.points[l_next].x)) * scale / 3.0f; + bezt->vec[2][1] = (ftoutline.points[l].y + (2 * ftoutline.points[l_next].y)) * scale / 3.0f; + bezt->h2 = HD_FREE; + } + else { + bezt->vec[2][0] = ftoutline.points[l].x * scale - (ftoutline.points[l].x - ftoutline.points[l_next].x) * scale / 3.0f; + bezt->vec[2][1] = ftoutline.points[l].y * scale - (ftoutline.points[l].y - ftoutline.points[l_next].y) * scale / 3.0f; + bezt->h2 = HD_VECT; } /* get the handles that are aligned, tricky... @@ -273,8 +241,8 @@ static VChar *freetypechar_to_vchar(FT_Face face, FT_ULong charcode, VFontData * } } } - if (npoints) MEM_freeN(npoints); - if (onpoints) MEM_freeN(onpoints); + + MEM_freeN(onpoints); return che; } |