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.c776
1 files changed, 384 insertions, 392 deletions
diff --git a/source/blender/blenlib/intern/freetypefont.c b/source/blender/blenlib/intern/freetypefont.c
index 36051e3e7f0..a8b8f01fa22 100644
--- a/source/blender/blenlib/intern/freetypefont.c
+++ b/source/blender/blenlib/intern/freetypefont.c
@@ -50,371 +50,363 @@
static FT_Library library;
static FT_Error err;
-
static VChar *freetypechar_to_vchar(FT_Face face, FT_ULong charcode, VFontData *vfd)
{
- const float scale = vfd->scale;
- const float eps = 0.0001f;
- const float eps_sq = eps * eps;
- /* Blender */
- struct Nurb *nu;
- struct VChar *che;
- struct BezTriple *bezt;
-
- /* Freetype2 */
- FT_GlyphSlot glyph;
- FT_UInt glyph_index;
- FT_Outline ftoutline;
- float dx, dy;
- int j, k, l, l_first = 0;
-
- /*
- * Generate the character 3D data
- *
- * Get the FT Glyph index and load the Glyph */
- glyph_index = FT_Get_Char_Index(face, charcode);
- err = FT_Load_Glyph(face, glyph_index, FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP);
-
- /* If loading succeeded, convert the FT glyph to the internal format */
- if (!err) {
- /* 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 */
- che = (VChar *) MEM_callocN(sizeof(struct VChar), "objfnt_char");
-
- /* Take some data for modifying purposes */
- glyph = face->glyph;
- ftoutline = glyph->outline;
-
- /* Set the width and character code */
- che->index = charcode;
- che->width = glyph->advance.x * scale;
-
- BLI_ghash_insert(vfd->characters, POINTER_FROM_UINT(che->index), che);
-
- /* Start converting the FT data */
- onpoints = (int *)MEM_callocN((ftoutline.n_contours) * sizeof(int), "onpoints");
-
- /* get number of on-curve points for beziertriples (including conic virtual on-points) */
- 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]++;
- }
-
- {
- 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]++;
- }
- }
- }
- }
-
- /* contour loop, bezier & conic styles merged */
- 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");
- BLI_addtail(&che->nurbsbase, nu);
-
- nu->type = CU_BEZIER;
- nu->pntsu = onpoints[j];
- nu->resolu = 8;
- nu->flag = CU_2D;
- nu->flagu = CU_NURB_CYCLIC;
- nu->bezt = bezt;
-
- /* individual curve loop, start-end */
- 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 */
- {
- 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;
- bezt->vec[0][1] = (dy + (2 * ftoutline.points[l].y) * scale) / 3.0f;
-
- /* midpoint (virtual on-curve point) */
- bezt->vec[1][0] = dx;
- bezt->vec[1][1] = dy;
-
- /* right handle */
- 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;
- bezt++;
- }
- }
-
- /* 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 (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 {
- 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) */
- bezt->vec[1][0] = ftoutline.points[l].x * scale;
- bezt->vec[1][1] = ftoutline.points[l].y * scale;
-
- /* right handle */
- 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 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...
- * - check if one of them is a vector handle.
- * - dist_squared_to_line_v2, check if the three beztriple points are on one line
- * - len_squared_v2v2, see if there's a distance between the three points
- * - len_squared_v2v2 again, to check the angle between the handles
- */
- if ((bezt->h1 != HD_VECT && bezt->h2 != HD_VECT) &&
- (dist_squared_to_line_v2(bezt->vec[0], bezt->vec[1], bezt->vec[2]) < (0.001f * 0.001f)) &&
- (len_squared_v2v2(bezt->vec[0], bezt->vec[1]) > eps_sq) &&
- (len_squared_v2v2(bezt->vec[1], bezt->vec[2]) > eps_sq) &&
- (len_squared_v2v2(bezt->vec[0], bezt->vec[2]) > eps_sq) &&
- (len_squared_v2v2(bezt->vec[0], bezt->vec[2]) >
- max_ff(len_squared_v2v2(bezt->vec[0], bezt->vec[1]),
- len_squared_v2v2(bezt->vec[1], bezt->vec[2]))))
- {
- bezt->h1 = bezt->h2 = HD_ALIGN;
- }
- bezt->radius = 1.0f;
- bezt++;
- }
- }
- }
-
- MEM_freeN(onpoints);
-
- return che;
- }
-
- return NULL;
+ const float scale = vfd->scale;
+ const float eps = 0.0001f;
+ const float eps_sq = eps * eps;
+ /* Blender */
+ struct Nurb *nu;
+ struct VChar *che;
+ struct BezTriple *bezt;
+
+ /* Freetype2 */
+ FT_GlyphSlot glyph;
+ FT_UInt glyph_index;
+ FT_Outline ftoutline;
+ float dx, dy;
+ int j, k, l, l_first = 0;
+
+ /*
+ * Generate the character 3D data
+ *
+ * Get the FT Glyph index and load the Glyph */
+ glyph_index = FT_Get_Char_Index(face, charcode);
+ err = FT_Load_Glyph(face, glyph_index, FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP);
+
+ /* If loading succeeded, convert the FT glyph to the internal format */
+ if (!err) {
+ /* 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 */
+ che = (VChar *)MEM_callocN(sizeof(struct VChar), "objfnt_char");
+
+ /* Take some data for modifying purposes */
+ glyph = face->glyph;
+ ftoutline = glyph->outline;
+
+ /* Set the width and character code */
+ che->index = charcode;
+ che->width = glyph->advance.x * scale;
+
+ BLI_ghash_insert(vfd->characters, POINTER_FROM_UINT(che->index), che);
+
+ /* Start converting the FT data */
+ onpoints = (int *)MEM_callocN((ftoutline.n_contours) * sizeof(int), "onpoints");
+
+ /* get number of on-curve points for beziertriples (including conic virtual on-points) */
+ 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]++;
+ }
+
+ {
+ 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]++;
+ }
+ }
+ }
+ }
+
+ /* contour loop, bezier & conic styles merged */
+ 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");
+ BLI_addtail(&che->nurbsbase, nu);
+
+ nu->type = CU_BEZIER;
+ nu->pntsu = onpoints[j];
+ nu->resolu = 8;
+ nu->flag = CU_2D;
+ nu->flagu = CU_NURB_CYCLIC;
+ nu->bezt = bezt;
+
+ /* individual curve loop, start-end */
+ 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 */
+ {
+ 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;
+ bezt->vec[0][1] = (dy + (2 * ftoutline.points[l].y) * scale) / 3.0f;
+
+ /* midpoint (virtual on-curve point) */
+ bezt->vec[1][0] = dx;
+ bezt->vec[1][1] = dy;
+
+ /* right handle */
+ 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;
+ bezt++;
+ }
+ }
+
+ /* 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 (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 {
+ 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) */
+ bezt->vec[1][0] = ftoutline.points[l].x * scale;
+ bezt->vec[1][1] = ftoutline.points[l].y * scale;
+
+ /* right handle */
+ 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 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...
+ * - check if one of them is a vector handle.
+ * - dist_squared_to_line_v2, check if the three beztriple points are on one line
+ * - len_squared_v2v2, see if there's a distance between the three points
+ * - len_squared_v2v2 again, to check the angle between the handles
+ */
+ if ((bezt->h1 != HD_VECT && bezt->h2 != HD_VECT) &&
+ (dist_squared_to_line_v2(bezt->vec[0], bezt->vec[1], bezt->vec[2]) <
+ (0.001f * 0.001f)) &&
+ (len_squared_v2v2(bezt->vec[0], bezt->vec[1]) > eps_sq) &&
+ (len_squared_v2v2(bezt->vec[1], bezt->vec[2]) > eps_sq) &&
+ (len_squared_v2v2(bezt->vec[0], bezt->vec[2]) > eps_sq) &&
+ (len_squared_v2v2(bezt->vec[0], bezt->vec[2]) >
+ max_ff(len_squared_v2v2(bezt->vec[0], bezt->vec[1]),
+ len_squared_v2v2(bezt->vec[1], bezt->vec[2])))) {
+ bezt->h1 = bezt->h2 = HD_ALIGN;
+ }
+ bezt->radius = 1.0f;
+ bezt++;
+ }
+ }
+ }
+
+ MEM_freeN(onpoints);
+
+ return che;
+ }
+
+ return NULL;
}
static VChar *objchr_to_ftvfontdata(VFont *vfont, FT_ULong charcode)
{
- VChar *che;
-
- /* Freetype2 */
- FT_Face face;
-
- /* Load the font to memory */
- if (vfont->temp_pf) {
- err = FT_New_Memory_Face(library,
- vfont->temp_pf->data,
- vfont->temp_pf->size,
- 0,
- &face);
- if (err) {
- return NULL;
- }
- }
- else {
- err = true;
- return NULL;
- }
-
- /* Read the char */
- che = freetypechar_to_vchar(face, charcode, vfont->data);
-
- /* And everything went ok */
- return che;
+ VChar *che;
+
+ /* Freetype2 */
+ FT_Face face;
+
+ /* Load the font to memory */
+ if (vfont->temp_pf) {
+ err = FT_New_Memory_Face(library, vfont->temp_pf->data, vfont->temp_pf->size, 0, &face);
+ if (err) {
+ return NULL;
+ }
+ }
+ else {
+ err = true;
+ return NULL;
+ }
+
+ /* Read the char */
+ che = freetypechar_to_vchar(face, charcode, vfont->data);
+
+ /* And everything went ok */
+ return che;
}
-
static VFontData *objfnt_to_ftvfontdata(PackedFile *pf)
{
- /* Variables */
- FT_Face face;
- const FT_ULong charcode_reserve = 256;
- FT_ULong charcode = 0, lcode;
- FT_UInt glyph_index;
- const char *fontname;
- VFontData *vfd;
-
- /* load the freetype font */
- err = FT_New_Memory_Face(library,
- pf->data,
- pf->size,
- 0,
- &face);
-
- if (err) {
- return NULL;
- }
-
- /* allocate blender font */
- vfd = MEM_callocN(sizeof(*vfd), "FTVFontData");
-
- /* get the name */
- fontname = FT_Get_Postscript_Name(face);
- BLI_strncpy(vfd->name, (fontname == NULL) ? "" : fontname, sizeof(vfd->name));
-
- /* Extract the first 256 character from TTF */
- lcode = charcode = FT_Get_First_Char(face, &glyph_index);
-
- /* No charmap found from the ttf so we need to figure it out */
- if (glyph_index == 0) {
- FT_CharMap found = NULL;
- FT_CharMap charmap;
- int n;
-
- for (n = 0; n < face->num_charmaps; n++) {
- charmap = face->charmaps[n];
- if (charmap->encoding == FT_ENCODING_APPLE_ROMAN) {
- found = charmap;
- break;
- }
- }
-
- err = FT_Set_Charmap(face, found);
-
- if (err) {
- return NULL;
- }
-
- lcode = charcode = FT_Get_First_Char(face, &glyph_index);
- }
-
- /* Blender default BFont is not "complete". */
- const bool complete_font = (face->ascender != 0) && (face->descender != 0) &&
- (face->ascender != face->descender);
-
- if (complete_font) {
- /* We can get descender as well, but we simple store descender in relation to the ascender.
- * Also note that descender is stored as a negative number. */
- vfd->ascender = (float)face->ascender / (face->ascender - face->descender);
- }
- else {
- vfd->ascender = 0.8f;
- vfd->em_height = 1.0f;
- }
-
- /* Adjust font size */
- if (face->bbox.yMax != face->bbox.yMin) {
- vfd->scale = (float)(1.0 / (double)(face->bbox.yMax - face->bbox.yMin));
-
- if (complete_font) {
- vfd->em_height = (float)(face->ascender - face->descender) / (face->bbox.yMax - face->bbox.yMin);
- }
- }
- else {
- vfd->scale = 1.0f / 1000.0f;
- }
-
- /* Load characters */
- vfd->characters = BLI_ghash_int_new_ex(__func__, charcode_reserve);
-
- while (charcode < charcode_reserve) {
- /* Generate the font data */
- freetypechar_to_vchar(face, charcode, vfd);
-
- /* Next glyph */
- charcode = FT_Get_Next_Char(face, charcode, &glyph_index);
-
- /* Check that we won't start infinite loop */
- if (charcode <= lcode) {
- break;
- }
- lcode = charcode;
- }
-
- return vfd;
+ /* Variables */
+ FT_Face face;
+ const FT_ULong charcode_reserve = 256;
+ FT_ULong charcode = 0, lcode;
+ FT_UInt glyph_index;
+ const char *fontname;
+ VFontData *vfd;
+
+ /* load the freetype font */
+ err = FT_New_Memory_Face(library, pf->data, pf->size, 0, &face);
+
+ if (err) {
+ return NULL;
+ }
+
+ /* allocate blender font */
+ vfd = MEM_callocN(sizeof(*vfd), "FTVFontData");
+
+ /* get the name */
+ fontname = FT_Get_Postscript_Name(face);
+ BLI_strncpy(vfd->name, (fontname == NULL) ? "" : fontname, sizeof(vfd->name));
+
+ /* Extract the first 256 character from TTF */
+ lcode = charcode = FT_Get_First_Char(face, &glyph_index);
+
+ /* No charmap found from the ttf so we need to figure it out */
+ if (glyph_index == 0) {
+ FT_CharMap found = NULL;
+ FT_CharMap charmap;
+ int n;
+
+ for (n = 0; n < face->num_charmaps; n++) {
+ charmap = face->charmaps[n];
+ if (charmap->encoding == FT_ENCODING_APPLE_ROMAN) {
+ found = charmap;
+ break;
+ }
+ }
+
+ err = FT_Set_Charmap(face, found);
+
+ if (err) {
+ return NULL;
+ }
+
+ lcode = charcode = FT_Get_First_Char(face, &glyph_index);
+ }
+
+ /* Blender default BFont is not "complete". */
+ const bool complete_font = (face->ascender != 0) && (face->descender != 0) &&
+ (face->ascender != face->descender);
+
+ if (complete_font) {
+ /* We can get descender as well, but we simple store descender in relation to the ascender.
+ * Also note that descender is stored as a negative number. */
+ vfd->ascender = (float)face->ascender / (face->ascender - face->descender);
+ }
+ else {
+ vfd->ascender = 0.8f;
+ vfd->em_height = 1.0f;
+ }
+
+ /* Adjust font size */
+ if (face->bbox.yMax != face->bbox.yMin) {
+ vfd->scale = (float)(1.0 / (double)(face->bbox.yMax - face->bbox.yMin));
+
+ if (complete_font) {
+ vfd->em_height = (float)(face->ascender - face->descender) /
+ (face->bbox.yMax - face->bbox.yMin);
+ }
+ }
+ else {
+ vfd->scale = 1.0f / 1000.0f;
+ }
+
+ /* Load characters */
+ vfd->characters = BLI_ghash_int_new_ex(__func__, charcode_reserve);
+
+ while (charcode < charcode_reserve) {
+ /* Generate the font data */
+ freetypechar_to_vchar(face, charcode, vfd);
+
+ /* Next glyph */
+ charcode = FT_Get_Next_Char(face, charcode, &glyph_index);
+
+ /* Check that we won't start infinite loop */
+ if (charcode <= lcode) {
+ break;
+ }
+ lcode = charcode;
+ }
+
+ return vfd;
}
-
static int check_freetypefont(PackedFile *pf)
{
- FT_Face face;
- FT_GlyphSlot glyph;
- FT_UInt glyph_index;
- int success = 0;
-
- err = FT_New_Memory_Face(library,
- pf->data,
- pf->size,
- 0,
- &face);
- if (err) {
- success = 0;
- //XXX error("This is not a valid font");
- }
- else {
- glyph_index = FT_Get_Char_Index(face, 'A');
- err = FT_Load_Glyph(face, glyph_index, FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP);
- if (err) {
- success = 0;
- }
- else {
- glyph = face->glyph;
- if (glyph->format == ft_glyph_format_outline) {
- success = 1;
- }
- else {
- //XXX error("Selected Font has no outline data");
- success = 0;
- }
- }
- }
-
- return success;
+ FT_Face face;
+ FT_GlyphSlot glyph;
+ FT_UInt glyph_index;
+ int success = 0;
+
+ err = FT_New_Memory_Face(library, pf->data, pf->size, 0, &face);
+ if (err) {
+ success = 0;
+ //XXX error("This is not a valid font");
+ }
+ else {
+ glyph_index = FT_Get_Char_Index(face, 'A');
+ err = FT_Load_Glyph(face, glyph_index, FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP);
+ if (err) {
+ success = 0;
+ }
+ else {
+ glyph = face->glyph;
+ if (glyph->format == ft_glyph_format_outline) {
+ success = 1;
+ }
+ else {
+ //XXX error("Selected Font has no outline data");
+ success = 0;
+ }
+ }
+ }
+
+ return success;
}
/**
@@ -427,66 +419,67 @@ static int check_freetypefont(PackedFile *pf)
*/
VFontData *BLI_vfontdata_from_freetypefont(PackedFile *pf)
{
- VFontData *vfd = NULL;
- int success = 0;
+ VFontData *vfd = NULL;
+ int success = 0;
- /* init Freetype */
- err = FT_Init_FreeType(&library);
- if (err) {
- /* XXX error("Failed to load the Freetype font library"); */
- return NULL;
- }
+ /* init Freetype */
+ err = FT_Init_FreeType(&library);
+ if (err) {
+ /* XXX error("Failed to load the Freetype font library"); */
+ return NULL;
+ }
- success = check_freetypefont(pf);
+ success = check_freetypefont(pf);
- if (success) {
- vfd = objfnt_to_ftvfontdata(pf);
- }
+ if (success) {
+ vfd = objfnt_to_ftvfontdata(pf);
+ }
- /* free Freetype */
- FT_Done_FreeType(library);
+ /* free Freetype */
+ FT_Done_FreeType(library);
- return vfd;
+ return vfd;
}
static void *vfontdata_copy_characters_value_cb(const void *src)
{
- return BLI_vfontchar_copy(src, 0);
+ return BLI_vfontchar_copy(src, 0);
}
VFontData *BLI_vfontdata_copy(const VFontData *vfont_src, const int UNUSED(flag))
{
- VFontData *vfont_dst = MEM_dupallocN(vfont_src);
+ VFontData *vfont_dst = MEM_dupallocN(vfont_src);
- if (vfont_src->characters != NULL) {
- vfont_dst->characters = BLI_ghash_copy(vfont_src->characters, NULL, vfontdata_copy_characters_value_cb);
- }
+ if (vfont_src->characters != NULL) {
+ vfont_dst->characters = BLI_ghash_copy(
+ vfont_src->characters, NULL, vfontdata_copy_characters_value_cb);
+ }
- return vfont_dst;
+ return vfont_dst;
}
VChar *BLI_vfontchar_from_freetypefont(VFont *vfont, unsigned long character)
{
- VChar *che = NULL;
+ VChar *che = NULL;
- if (!vfont) {
- return NULL;
- }
+ if (!vfont) {
+ return NULL;
+ }
- /* Init Freetype */
- err = FT_Init_FreeType(&library);
- if (err) {
- /* XXX error("Failed to load the Freetype font library"); */
- return NULL;
- }
+ /* Init Freetype */
+ err = FT_Init_FreeType(&library);
+ if (err) {
+ /* XXX error("Failed to load the Freetype font library"); */
+ return NULL;
+ }
- /* Load the character */
- che = objchr_to_ftvfontdata(vfont, character);
+ /* Load the character */
+ che = objchr_to_ftvfontdata(vfont, character);
- /* Free Freetype */
- FT_Done_FreeType(library);
+ /* Free Freetype */
+ FT_Done_FreeType(library);
- return che;
+ return che;
}
/* Yeah, this is very bad... But why is this in BLI in the first place, since it uses Nurb data?
@@ -496,15 +489,14 @@ VChar *BLI_vfontchar_from_freetypefont(VFont *vfont, unsigned long character)
VChar *BLI_vfontchar_copy(const VChar *vchar_src, const int UNUSED(flag))
{
- VChar *vchar_dst = MEM_dupallocN(vchar_src);
+ VChar *vchar_dst = MEM_dupallocN(vchar_src);
- BLI_listbase_clear(&vchar_dst->nurbsbase);
- BKE_nurbList_duplicate(&vchar_dst->nurbsbase, &vchar_src->nurbsbase);
+ BLI_listbase_clear(&vchar_dst->nurbsbase);
+ BKE_nurbList_duplicate(&vchar_dst->nurbsbase, &vchar_src->nurbsbase);
- return vchar_dst;
+ return vchar_dst;
}
-
/*
* from: http://www.freetype.org/freetype2/docs/glyphs/glyphs-6.html#section-1
*