Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenlib/intern/freetypefont.c')
-rw-r--r--source/blender/blenlib/intern/freetypefont.c152
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;
}