/* matching fnction in rna_ID.c */ static int rna_VectorFont_filepath_editable(PointerRNA *ptr) { VFont *vfont = ptr->id.data; if (BKE_vfont_is_builtin(vfont)) { return 0; } return PROP_EDITABLE; }
/* matching fnction in rna_ID.c */ static int rna_VectorFont_filepath_editable(PointerRNA *ptr) { VFont *vfont = ptr->id.data; if (BKE_vfont_is_builtin(vfont)) { return false; } return true; }
static int rna_ID_name_editable(PointerRNA *ptr) { ID *id = (ID *)ptr->data; if (GS(id->name) == ID_VF) { VFont *vfont = (VFont *)id; if (BKE_vfont_is_builtin(vfont)) return false; } return PROP_EDITABLE; }
VFont *BKE_vfont_builtin_get(void) { VFont *vfont; for (vfont = G.main->vfont.first; vfont; vfont = vfont->id.next) { if (BKE_vfont_is_builtin(vfont)) { return vfont; } } return BKE_vfont_load(G.main, FO_BUILTIN_NAME); }
static VFontData *vfont_get_data(Main *bmain, VFont *vfont) { if (vfont == NULL) { return NULL; } /* And then set the data */ if (!vfont->data) { PackedFile *pf; if (BKE_vfont_is_builtin(vfont)) { pf = get_builtin_packedfile(); } else { if (vfont->packedfile) { pf = vfont->packedfile; /* We need to copy a tmp font to memory unless it is already there */ if (vfont->temp_pf == NULL) { vfont->temp_pf = dupPackedFile(pf); } } else { pf = newPackedFile(NULL, vfont->name, ID_BLEND_PATH(bmain, &vfont->id)); if (vfont->temp_pf == NULL) { vfont->temp_pf = newPackedFile(NULL, vfont->name, ID_BLEND_PATH(bmain, &vfont->id)); } } if (!pf) { printf("Font file doesn't exist: %s\n", vfont->name); /* DON'T DO THIS * missing file shouldn't modifty path! - campbell */ #if 0 strcpy(vfont->name, FO_BUILTIN_NAME); #endif pf = get_builtin_packedfile(); } } if (pf) { vfont->data = BLI_vfontdata_from_freetypefont(pf); if (pf != vfont->packedfile) { freePackedFile(pf); } } } return vfont->data; }
int GetFontId(VFont *vfont) { PackedFile *packedfile=NULL; int fontid = -1; if (vfont->packedfile) { packedfile= vfont->packedfile; fontid= BLF_load_mem(vfont->name, (unsigned char*)packedfile->data, packedfile->size); if (fontid == -1) { printf("ERROR: packed font \"%s\" could not be loaded.\n", vfont->name); fontid = BLF_load("default"); } return fontid; } /* once we have packed working we can load the builtin font */ const char *filepath = vfont->name; if (BKE_vfont_is_builtin(vfont)) { fontid = BLF_load("default"); /* XXX the following code is supposed to work (after you add get_builtin_packedfile to BKE_font.h ) * unfortunately it's crashing on blf_glyph.c:173 because gc->max_glyph_width is 0 */ // packedfile=get_builtin_packedfile(); // fontid= BLF_load_mem(font->name, (unsigned char*)packedfile->data, packedfile->size); // return fontid; return BLF_load("default"); } /* convert from absolute to relative */ char expanded[256]; // font names can be bigger than FILE_MAX (240) BLI_strncpy(expanded, filepath, 256); BLI_path_abs(expanded, G.main->name); fontid = BLF_load(expanded); /* fallback */ if (fontid == -1) fontid = BLF_load("default"); return fontid; }
/* no libraries for now */ void packAll(Main *bmain, ReportList *reports, bool verbose) { Image *ima; VFont *vfont; bSound *sound; int tot = 0; for (ima = bmain->image.first; ima; ima = ima->id.next) { if (BKE_image_has_packedfile(ima) == false && ima->id.lib == NULL) { if (ima->source == IMA_SRC_FILE) { BKE_image_packfiles(reports, ima, ID_BLEND_PATH(bmain, &ima->id)); tot ++; } else if (BKE_image_is_animated(ima) && verbose) { BKE_reportf(reports, RPT_WARNING, "Image '%s' skipped, movies and image sequences not supported", ima->id.name + 2); } } } for (vfont = bmain->vfont.first; vfont; vfont = vfont->id.next) { if (vfont->packedfile == NULL && vfont->id.lib == NULL && BKE_vfont_is_builtin(vfont) == false) { vfont->packedfile = newPackedFile(reports, vfont->name, bmain->name); tot ++; } } for (sound = bmain->sound.first; sound; sound = sound->id.next) { if (sound->packedfile == NULL && sound->id.lib == NULL) { sound->packedfile = newPackedFile(reports, sound->name, bmain->name); tot++; } } if (tot > 0) BKE_reportf(reports, RPT_INFO, "Packed %d files", tot); else if (verbose) BKE_report(reports, RPT_INFO, "No new files have been packed"); }
struct CharTrans *BKE_vfont_to_curve(Main *bmain, Scene *scene, Object *ob, int mode) { VFont *vfont, *oldvfont; VFontData *vfd = NULL; Curve *cu; CharInfo *info = NULL, *custrinfo; TextBox *tb; VChar *che; struct CharTrans *chartransdata = NULL, *ct; float *f, xof, yof, xtrax, linedist, *linedata, *linedata2, *linedata3, *linedata4; float twidth, maxlen = 0; int i, slen, j; int curbox; int selstart, selend; int utf8len; short cnr = 0, lnr = 0, wsnr = 0; wchar_t *mem, *tmp, ascii; /* remark: do calculations including the trailing '\0' of a string * because the cursor can be at that location */ if (ob->type != OB_FONT) return NULL; /* Set font data */ cu = (Curve *) ob->data; vfont = cu->vfont; if (cu->str == NULL) return NULL; if (vfont == NULL) return NULL; /* Create unicode string */ utf8len = BLI_strlen_utf8(cu->str); mem = MEM_callocN(((utf8len + 1) * sizeof(wchar_t)), "convertedmem"); BLI_strncpy_wchar_from_utf8(mem, cu->str, utf8len + 1); /* Count the wchar_t string length */ slen = wcslen(mem); if (cu->ulheight == 0.0f) cu->ulheight = 0.05f; if (cu->strinfo == NULL) /* old file */ cu->strinfo = MEM_callocN((slen + 4) * sizeof(CharInfo), "strinfo compat"); custrinfo = cu->strinfo; if (cu->editfont) custrinfo = cu->editfont->textbufinfo; if (cu->tb == NULL) cu->tb = MEM_callocN(MAXTEXTBOX * sizeof(TextBox), "TextBox compat"); vfd = vfont_get_data(bmain, vfont); /* The VFont Data can not be found */ if (!vfd) { if (mem) MEM_freeN(mem); return NULL; } /* calc offset and rotation of each char */ ct = chartransdata = (struct CharTrans *)MEM_callocN((slen + 1) * sizeof(struct CharTrans), "buildtext"); /* We assume the worst case: 1 character per line (is freed at end anyway) */ linedata = MEM_mallocN(sizeof(float) * (slen * 2 + 1), "buildtext2"); linedata2 = MEM_mallocN(sizeof(float) * (slen * 2 + 1), "buildtext3"); linedata3 = MEM_callocN(sizeof(float) * (slen * 2 + 1), "buildtext4"); linedata4 = MEM_callocN(sizeof(float) * (slen * 2 + 1), "buildtext5"); linedist = cu->linedist; xof = cu->xof + (cu->tb[0].x / cu->fsize); yof = cu->yof + (cu->tb[0].y / cu->fsize); xtrax = 0.5f * cu->spacing - 0.5f; oldvfont = NULL; for (i = 0; i < slen; i++) custrinfo[i].flag &= ~(CU_CHINFO_WRAP | CU_CHINFO_SMALLCAPS_CHECK); if (cu->selboxes) MEM_freeN(cu->selboxes); cu->selboxes = NULL; if (BKE_vfont_select_get(ob, &selstart, &selend)) cu->selboxes = MEM_callocN((selend - selstart + 1) * sizeof(SelBox), "font selboxes"); tb = &(cu->tb[0]); curbox = 0; for (i = 0; i <= slen; i++) { makebreak: /* Characters in the list */ info = &(custrinfo[i]); ascii = mem[i]; if (info->flag & CU_CHINFO_SMALLCAPS) { ascii = towupper(ascii); if (mem[i] != ascii) { mem[i] = ascii; info->flag |= CU_CHINFO_SMALLCAPS_CHECK; } } vfont = which_vfont(cu, info); if (vfont == NULL) break; che = find_vfont_char(vfd, ascii); /* * The character wasn't in the current curve base so load it * But if the font is built-in then do not try loading since * whole font is in the memory already */ if (che == NULL && BKE_vfont_is_builtin(vfont) == FALSE) { BLI_vfontchar_from_freetypefont(vfont, ascii); } /* Try getting the character again from the list */ che = find_vfont_char(vfd, ascii); /* No VFont found */ if (vfont == NULL) { if (mem) MEM_freeN(mem); MEM_freeN(chartransdata); return NULL; } if (vfont != oldvfont) { vfd = vfont_get_data(bmain, vfont); oldvfont = vfont; } /* VFont Data for VFont couldn't be found */ if (!vfd) { if (mem) MEM_freeN(mem); MEM_freeN(chartransdata); return NULL; } twidth = char_width(cu, che, info); /* Calculate positions */ if ((tb->w != 0.0f) && (ct->dobreak == 0) && (((xof - (tb->x / cu->fsize) + twidth) * cu->fsize) > tb->w + cu->xof * cu->fsize)) { // fprintf(stderr, "linewidth exceeded: %c%c%c...\n", mem[i], mem[i+1], mem[i+2]); for (j = i; j && (mem[j] != '\n') && (mem[j] != '\r') && (chartransdata[j].dobreak == 0); j--) { if (mem[j] == ' ' || mem[j] == '-') { ct -= (i - (j - 1)); cnr -= (i - (j - 1)); if (mem[j] == ' ') wsnr--; if (mem[j] == '-') wsnr++; i = j - 1; xof = ct->xof; ct[1].dobreak = 1; custrinfo[i + 1].flag |= CU_CHINFO_WRAP; goto makebreak; } if (chartransdata[j].dobreak) { // fprintf(stderr, "word too long: %c%c%c...\n", mem[j], mem[j+1], mem[j+2]); ct->dobreak = 1; custrinfo[i + 1].flag |= CU_CHINFO_WRAP; ct -= 1; cnr -= 1; i--; xof = ct->xof; goto makebreak; } } } if (ascii == '\n' || ascii == '\r' || ascii == 0 || ct->dobreak) { ct->xof = xof; ct->yof = yof; ct->linenr = lnr; ct->charnr = cnr; yof -= linedist; maxlen = max_ff(maxlen, (xof - tb->x / cu->fsize)); linedata[lnr] = xof - tb->x / cu->fsize; linedata2[lnr] = cnr; linedata3[lnr] = tb->w / cu->fsize; linedata4[lnr] = wsnr; if ((tb->h != 0.0f) && ((-(yof - (tb->y / cu->fsize))) > ((tb->h / cu->fsize) - (linedist * cu->fsize)) - cu->yof) && (cu->totbox > (curbox + 1)) ) { maxlen = 0; tb++; curbox++; yof = cu->yof + tb->y / cu->fsize; } /* XXX, has been unused for years, need to check if this is useful, r4613 r5282 - campbell */ #if 0 if (ascii == '\n' || ascii == '\r') xof = cu->xof; else xof = cu->xof + (tb->x / cu->fsize); #else xof = cu->xof + (tb->x / cu->fsize); #endif lnr++; cnr = 0; wsnr = 0; } else if (ascii == 9) { /* TAB */ float tabfac; ct->xof = xof; ct->yof = yof; ct->linenr = lnr; ct->charnr = cnr++; tabfac = (xof - cu->xof + 0.01f); tabfac = 2.0f * ceilf(tabfac / 2.0f); xof = cu->xof + tabfac; } else { SelBox *sb = NULL; float wsfac; ct->xof = xof; ct->yof = yof; ct->linenr = lnr; ct->charnr = cnr++; if (cu->selboxes && (i >= selstart) && (i <= selend)) { sb = &(cu->selboxes[i - selstart]); sb->y = yof * cu->fsize - linedist * cu->fsize * 0.1f; sb->h = linedist * cu->fsize; sb->w = xof * cu->fsize; } if (ascii == 32) { wsfac = cu->wordspace; wsnr++; } else { wsfac = 1.0f; } /* Set the width of the character */ twidth = char_width(cu, che, info); xof += (twidth * wsfac * (1.0f + (info->kern / 40.0f)) ) + xtrax; if (sb) { sb->w = (xof * cu->fsize) - sb->w; } } ct++; } cu->lines = 1; ct = chartransdata; tmp = mem; for (i = 0; i <= slen; i++, tmp++, ct++) { ascii = *tmp; if (ascii == '\n' || ascii == '\r' || ct->dobreak) cu->lines++; } /* linedata is now: width of line * linedata2 is now: number of characters * linedata3 is now: maxlen of that line * linedata4 is now: number of whitespaces of line */ if (cu->spacemode != CU_LEFT) { ct = chartransdata; if (cu->spacemode == CU_RIGHT) { for (i = 0; i < lnr; i++) linedata[i] = linedata3[i] - linedata[i]; for (i = 0; i <= slen; i++) { ct->xof += linedata[ct->linenr]; ct++; } } else if (cu->spacemode == CU_MIDDLE) { for (i = 0; i < lnr; i++) linedata[i] = (linedata3[i] - linedata[i]) / 2; for (i = 0; i <= slen; i++) { ct->xof += linedata[ct->linenr]; ct++; } } else if ((cu->spacemode == CU_FLUSH) && (cu->tb[0].w != 0.0f)) { for (i = 0; i < lnr; i++) if (linedata2[i] > 1) linedata[i] = (linedata3[i] - linedata[i]) / (linedata2[i] - 1); for (i = 0; i <= slen; i++) { for (j = i; (!ELEM3(mem[j], '\0', '\n', '\r')) && (chartransdata[j].dobreak == 0) && (j < slen); j++) { /* do nothing */ } // if ((mem[j] != '\r') && (mem[j] != '\n') && (mem[j])) { ct->xof += ct->charnr * linedata[ct->linenr]; // } ct++; } } else if ((cu->spacemode == CU_JUSTIFY) && (cu->tb[0].w != 0.0f)) { float curofs = 0.0f; for (i = 0; i <= slen; i++) { for (j = i; (mem[j]) && (mem[j] != '\n') && (mem[j] != '\r') && (chartransdata[j].dobreak == 0) && (j < slen); j++) { /* pass */ } if ((mem[j] != '\r') && (mem[j] != '\n') && ((chartransdata[j].dobreak != 0))) { if (mem[i] == ' ') curofs += (linedata3[ct->linenr] - linedata[ct->linenr]) / linedata4[ct->linenr]; ct->xof += curofs; } if (mem[i] == '\n' || mem[i] == '\r' || chartransdata[i].dobreak) curofs = 0; ct++; } } } /* TEXT ON CURVE */ /* Note: Only OB_CURVE objects could have a path */ if (cu->textoncurve && cu->textoncurve->type == OB_CURVE) { Curve *cucu = cu->textoncurve->data; int oldflag = cucu->flag; cucu->flag |= (CU_PATH + CU_FOLLOW); if (cucu->path == NULL) BKE_displist_make_curveTypes(scene, cu->textoncurve, 0); if (cucu->path) { float distfac, imat[4][4], imat3[3][3], cmat[3][3]; float minx, maxx, miny, maxy; float timeofs, sizefac; invert_m4_m4(imat, ob->obmat); copy_m3_m4(imat3, imat); copy_m3_m4(cmat, cu->textoncurve->obmat); mul_m3_m3m3(cmat, cmat, imat3); sizefac = normalize_v3(cmat[0]) / cu->fsize; minx = miny = 1.0e20f; maxx = maxy = -1.0e20f; ct = chartransdata; for (i = 0; i <= slen; i++, ct++) { if (minx > ct->xof) minx = ct->xof; if (maxx < ct->xof) maxx = ct->xof; if (miny > ct->yof) miny = ct->yof; if (maxy < ct->yof) maxy = ct->yof; } /* we put the x-coordinaat exact at the curve, the y is rotated */ /* length correction */ distfac = sizefac * cucu->path->totdist / (maxx - minx); timeofs = 0.0f; if (distfac > 1.0f) { /* path longer than text: spacemode involves */ distfac = 1.0f / distfac; if (cu->spacemode == CU_RIGHT) { timeofs = 1.0f - distfac; } else if (cu->spacemode == CU_MIDDLE) { timeofs = (1.0f - distfac) / 2.0f; } else if (cu->spacemode == CU_FLUSH) { distfac = 1.0f; } } else { distfac = 1.0; } distfac /= (maxx - minx); timeofs += distfac * cu->xof; /* not cyclic */ ct = chartransdata; for (i = 0; i <= slen; i++, ct++) { float ctime, dtime, vec[4], tvec[4], rotvec[3]; float si, co; /* rotate around center character */ ascii = mem[i]; che = find_vfont_char(vfd, ascii); twidth = char_width(cu, che, info); dtime = distfac * 0.5f * twidth; ctime = timeofs + distfac * (ct->xof - minx); CLAMP(ctime, 0.0f, 1.0f); /* calc the right loc AND the right rot separately */ /* vec, tvec need 4 items */ where_on_path(cu->textoncurve, ctime, vec, tvec, NULL, NULL, NULL); where_on_path(cu->textoncurve, ctime + dtime, tvec, rotvec, NULL, NULL, NULL); mul_v3_fl(vec, sizefac); ct->rot = (float)M_PI - atan2f(rotvec[1], rotvec[0]); si = sinf(ct->rot); co = cosf(ct->rot); yof = ct->yof; ct->xof = vec[0] + si * yof; ct->yof = vec[1] + co * yof; } cucu->flag = oldflag; } } if (cu->selboxes) { ct = chartransdata; for (i = 0; i <= selend; i++, ct++) { if (i >= selstart) { cu->selboxes[i - selstart].x = ct->xof * cu->fsize; cu->selboxes[i - selstart].y = ct->yof * cu->fsize; } } } if (mode == FO_CURSUP || mode == FO_CURSDOWN || mode == FO_PAGEUP || mode == FO_PAGEDOWN) { /* 2: curs up * 3: curs down */ ct = chartransdata + cu->pos; if ((mode == FO_CURSUP || mode == FO_PAGEUP) && ct->linenr == 0) { /* pass */ } else if ((mode == FO_CURSDOWN || mode == FO_PAGEDOWN) && ct->linenr == lnr) { /* pass */ } else { switch (mode) { case FO_CURSUP: lnr = ct->linenr - 1; break; case FO_CURSDOWN: lnr = ct->linenr + 1; break; case FO_PAGEUP: lnr = ct->linenr - 10; break; case FO_PAGEDOWN: lnr = ct->linenr + 10; break; } cnr = ct->charnr; /* seek for char with lnr en cnr */ cu->pos = 0; ct = chartransdata; for (i = 0; i < slen; i++) { if (ct->linenr == lnr) { if ((ct->charnr == cnr) || ((ct + 1)->charnr == 0)) { break; } } else if (ct->linenr > lnr) { break; } cu->pos++; ct++; } } } /* cursor first */ if (cu->editfont) { float si, co; ct = chartransdata + cu->pos; si = sinf(ct->rot); co = cosf(ct->rot); f = cu->editfont->textcurs[0]; f[0] = cu->fsize * (-0.1f * co + ct->xof); f[1] = cu->fsize * ( 0.1f * si + ct->yof); f[2] = cu->fsize * ( 0.1f * co + ct->xof); f[3] = cu->fsize * (-0.1f * si + ct->yof); f[4] = cu->fsize * ( 0.1f * co + 0.8f * si + ct->xof); f[5] = cu->fsize * (-0.1f * si + 0.8f * co + ct->yof); f[6] = cu->fsize * (-0.1f * co + 0.8f * si + ct->xof); f[7] = cu->fsize * ( 0.1f * si + 0.8f * co + ct->yof); } MEM_freeN(linedata); MEM_freeN(linedata2); MEM_freeN(linedata3); MEM_freeN(linedata4); if (mode == FO_SELCHANGE) { MEM_freeN(chartransdata); MEM_freeN(mem); return NULL; } if (mode == FO_EDIT) { /* make nurbdata */ BKE_nurbList_free(&cu->nurb); ct = chartransdata; if (cu->sepchar == 0) { for (i = 0; i < slen; i++) { unsigned long cha = (uintptr_t) mem[i]; info = &(custrinfo[i]); if (info->mat_nr > (ob->totcol)) { /* printf("Error: Illegal material index (%d) in text object, setting to 0\n", info->mat_nr); */ info->mat_nr = 0; } /* We do not want to see any character for \n or \r */ if (cha != '\n' && cha != '\r') buildchar(bmain, cu, cha, info, ct->xof, ct->yof, ct->rot, i); if ((info->flag & CU_CHINFO_UNDERLINE) && (cu->textoncurve == NULL) && (cha != '\n') && (cha != '\r')) { float ulwidth, uloverlap = 0.0f; if ((i < (slen - 1)) && (mem[i + 1] != '\n') && (mem[i + 1] != '\r') && ((mem[i + 1] != ' ') || (custrinfo[i + 1].flag & CU_CHINFO_UNDERLINE)) && ((custrinfo[i + 1].flag & CU_CHINFO_WRAP) == 0)) { uloverlap = xtrax + 0.1f; } /* Find the character, the characters has to be in the memory already * since character checking has been done earlier already. */ che = find_vfont_char(vfd, cha); twidth = char_width(cu, che, info); ulwidth = cu->fsize * ((twidth * (1.0f + (info->kern / 40.0f))) + uloverlap); build_underline(cu, ct->xof * cu->fsize, ct->yof * cu->fsize + (cu->ulpos - 0.05f) * cu->fsize, ct->xof * cu->fsize + ulwidth, ct->yof * cu->fsize + (cu->ulpos - 0.05f) * cu->fsize - cu->ulheight * cu->fsize, i, info->mat_nr); } ct++; } } else { int outta = 0; for (i = 0; (i < slen) && (outta == 0); i++) { ascii = mem[i]; info = &(custrinfo[i]); if (cu->sepchar == (i + 1)) { float vecyo[3]; vecyo[0] = ct->xof; vecyo[1] = ct->yof; vecyo[2] = 0.0f; mem[0] = ascii; mem[1] = 0; custrinfo[0] = *info; cu->pos = 1; cu->len = 1; mul_v3_m4v3(ob->loc, ob->obmat, vecyo); outta = 1; cu->sepchar = 0; } ct++; } } } if (mode == FO_DUPLI) { MEM_freeN(mem); return chartransdata; } if (mem) MEM_freeN(mem); MEM_freeN(chartransdata); return NULL; }
static VFontData *vfont_get_data(Main *bmain, VFont *vfont) { if (vfont == NULL) { return NULL; } /* And then set the data */ if (!vfont->data) { PackedFile *pf; BLI_mutex_lock(&vfont_mutex); if (vfont->data) { /* Check data again, since it might have been already * initialized from other thread (previous check is * not accurate or threading, just prevents unneeded * lock if all the data is here for sure). */ BLI_mutex_unlock(&vfont_mutex); return vfont->data; } if (BKE_vfont_is_builtin(vfont)) { pf = get_builtin_packedfile(); } else { if (vfont->packedfile) { pf = vfont->packedfile; /* We need to copy a tmp font to memory unless it is already there */ if (vfont->temp_pf == NULL) { vfont->temp_pf = dupPackedFile(pf); } } else { pf = newPackedFile(NULL, vfont->name, ID_BLEND_PATH(bmain, &vfont->id)); if (vfont->temp_pf == NULL) { vfont->temp_pf = newPackedFile(NULL, vfont->name, ID_BLEND_PATH(bmain, &vfont->id)); } } if (!pf) { printf("Font file doesn't exist: %s\n", vfont->name); /* DON'T DO THIS * missing file shouldn't modifty path! - campbell */ #if 0 strcpy(vfont->name, FO_BUILTIN_NAME); #endif pf = get_builtin_packedfile(); } } if (pf) { vfont->data = BLI_vfontdata_from_freetypefont(pf); if (pf != vfont->packedfile) { freePackedFile(pf); } } BLI_mutex_unlock(&vfont_mutex); } return vfont->data; }