From 5b751c95f4e58c5f56b1af61c835b4537f19f43c Mon Sep 17 00:00:00 2001 From: Harley Acheson Date: Wed, 25 Aug 2021 13:30:00 -0700 Subject: BLF: Remove ASCII-only Code Paths Remove redundant code for drawing text strings that contain only ASCII. See D12293 for much more detail. Differential Revision: https://developer.blender.org/D12293 Reviewed by Campbell Barton --- source/blender/blenfont/BLF_api.h | 5 --- source/blender/blenfont/intern/blf.c | 28 ------------ source/blender/blenfont/intern/blf_default.c | 11 ----- source/blender/blenfont/intern/blf_font.c | 50 ---------------------- .../blender/draw/engines/overlay/overlay_edit_uv.c | 10 +---- .../draw/engines/overlay/overlay_motion_path.c | 2 +- .../blender/draw/intern/draw_manager_profiling.c | 12 +++--- source/blender/draw/intern/draw_manager_text.c | 10 ++--- source/blender/draw/intern/draw_manager_text.h | 2 +- source/blender/editors/interface/view2d_draw.c | 4 +- source/blender/editors/space_image/image_draw.c | 30 ++++++------- source/blender/editors/space_view3d/view3d_draw.c | 10 +---- .../space_view3d/view3d_gizmo_navigate_type.c | 2 +- source/blender/editors/transform/transform.c | 4 -- source/blender/editors/transform/transform_ops.c | 3 +- 15 files changed, 36 insertions(+), 147 deletions(-) (limited to 'source') diff --git a/source/blender/blenfont/BLF_api.h b/source/blender/blenfont/BLF_api.h index 4de7e704a7e..78252bdb08b 100644 --- a/source/blender/blenfont/BLF_api.h +++ b/source/blender/blenfont/BLF_api.h @@ -101,9 +101,6 @@ void BLF_batch_draw_end(void); void BLF_draw_ex(int fontid, const char *str, size_t str_len, struct ResultBLF *r_info) ATTR_NONNULL(2); void BLF_draw(int fontid, const char *str, size_t str_len) ATTR_NONNULL(2); -void BLF_draw_ascii_ex(int fontid, const char *str, size_t str_len, struct ResultBLF *r_info) - ATTR_NONNULL(2); -void BLF_draw_ascii(int fontid, const char *str, size_t str_len) ATTR_NONNULL(2); int BLF_draw_mono(int fontid, const char *str, size_t str_len, int cwidth) ATTR_NONNULL(2); typedef bool (*BLF_GlyphBoundsFn)(const char *str, @@ -257,8 +254,6 @@ void BLF_default_set(int fontid); int BLF_default(void); /* get default font ID so we can pass it to other functions */ /* Draw the string using the default font, size and dpi. */ void BLF_draw_default(float x, float y, float z, const char *str, size_t str_len) ATTR_NONNULL(); -void BLF_draw_default_ascii(float x, float y, float z, const char *str, size_t str_len) - ATTR_NONNULL(); /* Set size and DPI, and return default font ID. */ int BLF_set_default(void); diff --git a/source/blender/blenfont/intern/blf.c b/source/blender/blenfont/intern/blf.c index 86d67c80fd4..34ddb6f22d2 100644 --- a/source/blender/blenfont/intern/blf.c +++ b/source/blender/blenfont/intern/blf.c @@ -550,34 +550,6 @@ void BLF_draw(int fontid, const char *str, const size_t str_len) BLF_draw_ex(fontid, str, str_len, NULL); } -void BLF_draw_ascii_ex(int fontid, const char *str, const size_t str_len, struct ResultBLF *r_info) -{ - FontBLF *font = blf_get(fontid); - - BLF_RESULT_CHECK_INIT(r_info); - - if (font) { - blf_draw_gl__start(font); - if (font->flags & BLF_WORD_WRAP) { - /* Use non-ASCII draw function for word-wrap. */ - blf_font_draw__wrap(font, str, str_len, r_info); - } - else { - blf_font_draw_ascii(font, str, str_len, r_info); - } - blf_draw_gl__end(font); - } -} - -void BLF_draw_ascii(int fontid, const char *str, const size_t str_len) -{ - if (str_len == 0 || str[0] == '\0') { - return; - } - - BLF_draw_ascii_ex(fontid, str, str_len, NULL); -} - int BLF_draw_mono(int fontid, const char *str, const size_t str_len, int cwidth) { if (str_len == 0 || str[0] == '\0') { diff --git a/source/blender/blenfont/intern/blf_default.c b/source/blender/blenfont/intern/blf_default.c index 1b458e8aaef..2bac0bf8904 100644 --- a/source/blender/blenfont/intern/blf_default.c +++ b/source/blender/blenfont/intern/blf_default.c @@ -77,14 +77,3 @@ void BLF_draw_default(float x, float y, float z, const char *str, const size_t s BLF_position(global_font_default, x, y, z); BLF_draw(global_font_default, str, str_len); } - -/* same as above but call 'BLF_draw_ascii' */ -void BLF_draw_default_ascii(float x, float y, float z, const char *str, const size_t str_len) -{ - ASSERT_DEFAULT_SET; - - const uiStyle *style = UI_style_get(); - BLF_size(global_font_default, style->widgetlabel.points, global_font_dpi); - BLF_position(global_font_default, x, y, z); - BLF_draw_ascii(global_font_default, str, str_len); /* XXX, use real length */ -} diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c index 426008c9395..dbcd1d6016d 100644 --- a/source/blender/blenfont/intern/blf_font.c +++ b/source/blender/blenfont/intern/blf_font.c @@ -412,56 +412,6 @@ void blf_font_draw(FontBLF *font, const char *str, const size_t str_len, struct blf_glyph_cache_release(font); } -/* faster version of blf_font_draw, ascii only for view dimensions */ -static void blf_font_draw_ascii_ex( - FontBLF *font, const char *str, size_t str_len, struct ResultBLF *r_info, int pen_y) -{ - unsigned int c, c_prev = BLI_UTF8_ERR; - GlyphBLF *g, *g_prev = NULL; - int pen_x = 0; - - GlyphCacheBLF *gc = blf_glyph_cache_acquire(font); - - blf_batch_draw_begin(font); - - while ((c = *(str++)) && str_len--) { - BLI_assert(c < GLYPH_ASCII_TABLE_SIZE); - g = gc->glyph_ascii_table[c]; - if (UNLIKELY(g == NULL)) { - g = blf_glyph_add(font, gc, FT_Get_Char_Index((font)->face, c), c); - gc->glyph_ascii_table[c] = g; - if (UNLIKELY(g == NULL)) { - continue; - } - } - blf_kerning_step_fast(font, g_prev, g, c_prev, c, &pen_x); - - /* do not return this loop if clipped, we want every character tested */ - blf_glyph_render(font, gc, g, (float)pen_x, (float)pen_y); - - pen_x += g->advance_i; - g_prev = g; - c_prev = c; - } - - blf_batch_draw_end(); - - if (r_info) { - r_info->lines = 1; - r_info->width = pen_x; - } - - blf_glyph_cache_release(font); -} - -void blf_font_draw_ascii(FontBLF *font, - const char *str, - const size_t str_len, - struct ResultBLF *r_info) -{ - blf_font_draw_ascii_ex(font, str, str_len, r_info, 0); -} - /* use fixed column width, but an utf8 character may occupy multiple columns */ int blf_font_draw_mono(FontBLF *font, const char *str, const size_t str_len, int cwidth) { diff --git a/source/blender/draw/engines/overlay/overlay_edit_uv.c b/source/blender/draw/engines/overlay/overlay_edit_uv.c index c2b130163e8..985f8a6785c 100644 --- a/source/blender/draw/engines/overlay/overlay_edit_uv.c +++ b/source/blender/draw/engines/overlay/overlay_edit_uv.c @@ -333,14 +333,8 @@ void OVERLAY_edit_uv_cache_init(OVERLAY_Data *vedata) BLI_snprintf(text, 5, "%d", tile->tile_number); float tile_location[3] = { ((tile->tile_number - 1001) % 10), ((tile->tile_number - 1001) / 10), 0.0f}; - DRW_text_cache_add(dt, - tile_location, - text, - strlen(text), - 10, - 10, - DRW_TEXT_CACHE_GLOBALSPACE | DRW_TEXT_CACHE_ASCII, - color); + DRW_text_cache_add( + dt, tile_location, text, strlen(text), 10, 10, DRW_TEXT_CACHE_GLOBALSPACE, color); } } diff --git a/source/blender/draw/engines/overlay/overlay_motion_path.c b/source/blender/draw/engines/overlay/overlay_motion_path.c index e19d99dc597..1b7611e9620 100644 --- a/source/blender/draw/engines/overlay/overlay_motion_path.c +++ b/source/blender/draw/engines/overlay/overlay_motion_path.c @@ -130,7 +130,7 @@ static void motion_path_cache(OVERLAY_Data *vedata, OVERLAY_PrivateData *pd = vedata->stl->pd; const DRWContextState *draw_ctx = DRW_context_state_get(); struct DRWTextStore *dt = DRW_text_cache_ensure(); - int txt_flag = DRW_TEXT_CACHE_GLOBALSPACE | DRW_TEXT_CACHE_ASCII; + int txt_flag = DRW_TEXT_CACHE_GLOBALSPACE; int cfra = (int)DEG_get_ctime(draw_ctx->depsgraph); bool selected = (pchan) ? (pchan->bone->flag & BONE_SELECTED) : (ob->base_flag & BASE_SELECTED); bool show_keyframes = (avs->path_viewflag & MOTIONPATH_VIEW_KFRAS) != 0; diff --git a/source/blender/draw/intern/draw_manager_profiling.c b/source/blender/draw/intern/draw_manager_profiling.c index 783ec1b1d7d..d9ba2cbf932 100644 --- a/source/blender/draw/intern/draw_manager_profiling.c +++ b/source/blender/draw/intern/draw_manager_profiling.c @@ -209,16 +209,16 @@ void DRW_stats_reset(void) static void draw_stat_5row(const rcti *rect, int u, int v, const char *txt, const int size) { - BLF_draw_default_ascii(rect->xmin + (1 + u * 5) * U.widget_unit, - rect->ymax - (3 + v) * U.widget_unit, - 0.0f, - txt, - size); + BLF_draw_default(rect->xmin + (1 + u * 5) * U.widget_unit, + rect->ymax - (3 + v) * U.widget_unit, + 0.0f, + txt, + size); } static void draw_stat(const rcti *rect, int u, int v, const char *txt, const int size) { - BLF_draw_default_ascii( + BLF_draw_default( rect->xmin + (1 + u) * U.widget_unit, rect->ymax - (3 + v) * U.widget_unit, 0.0f, txt, size); } diff --git a/source/blender/draw/intern/draw_manager_text.c b/source/blender/draw/intern/draw_manager_text.c index 265fdba66fd..cfaa22ba7c6 100644 --- a/source/blender/draw/intern/draw_manager_text.c +++ b/source/blender/draw/intern/draw_manager_text.c @@ -152,11 +152,9 @@ static void drw_text_cache_draw_ex(DRWTextStore *dt, ARegion *region) BLF_position( font_id, (float)(vos->sco[0] + vos->xoffs), (float)(vos->sco[1] + vos->yoffs), 2.0f); - - ((vos->flag & DRW_TEXT_CACHE_ASCII) ? BLF_draw_ascii : BLF_draw)( - font_id, - (vos->flag & DRW_TEXT_CACHE_STRING_PTR) ? *((const char **)vos->str) : vos->str, - vos->str_len); + BLF_draw(font_id, + (vos->flag & DRW_TEXT_CACHE_STRING_PTR) ? *((const char **)vos->str) : vos->str, + vos->str_len); } } @@ -235,7 +233,7 @@ void DRW_text_edit_mesh_measure_stats(ARegion *region, * etc.). See bug T36090. */ struct DRWTextStore *dt = DRW_text_cache_ensure(); - const short txt_flag = DRW_TEXT_CACHE_GLOBALSPACE | (unit->system ? 0 : DRW_TEXT_CACHE_ASCII); + const short txt_flag = DRW_TEXT_CACHE_GLOBALSPACE; Mesh *me = ob->data; BMEditMesh *em = me->edit_mesh; float v1[3], v2[3], v3[3], vmid[3], fvec[3]; diff --git a/source/blender/draw/intern/draw_manager_text.h b/source/blender/draw/intern/draw_manager_text.h index f6dff335f1f..760259018bb 100644 --- a/source/blender/draw/intern/draw_manager_text.h +++ b/source/blender/draw/intern/draw_manager_text.h @@ -48,7 +48,7 @@ void DRW_text_edit_mesh_measure_stats(struct ARegion *region, const struct UnitSettings *unit); enum { - DRW_TEXT_CACHE_ASCII = (1 << 0), + // DRW_UNUSED_1 = (1 << 0), /* dirty */ DRW_TEXT_CACHE_GLOBALSPACE = (1 << 1), DRW_TEXT_CACHE_LOCALCLIP = (1 << 2), /* reference the string by pointer */ diff --git a/source/blender/editors/interface/view2d_draw.c b/source/blender/editors/interface/view2d_draw.c index 95427e49495..fd4dba30c1c 100644 --- a/source/blender/editors/interface/view2d_draw.c +++ b/source/blender/editors/interface/view2d_draw.c @@ -349,7 +349,7 @@ static void draw_horizontal_scale_indicators(const ARegion *region, const float text_width = BLF_width(font_id, text, strlen(text)); if (xpos_region - text_width / 2.0f >= xmin && xpos_region + text_width / 2.0f <= xmax) { - BLF_draw_default_ascii(xpos_region - text_width / 2.0f, ypos, 0.0f, text, sizeof(text)); + BLF_draw_default(xpos_region - text_width / 2.0f, ypos, 0.0f, text, sizeof(text)); } } } @@ -411,7 +411,7 @@ static void draw_vertical_scale_indicators(const ARegion *region, const float text_width = BLF_width(font_id, text, strlen(text)); if (ypos_region - text_width / 2.0f >= ymin && ypos_region + text_width / 2.0f <= ymax) { - BLF_draw_default_ascii(xpos, ypos_region - text_width / 2.0f, 0.0f, text, sizeof(text)); + BLF_draw_default(xpos, ypos_region - text_width / 2.0f, 0.0f, text, sizeof(text)); } } diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c index 92ceb00d5c0..4f66506d28b 100644 --- a/source/blender/editors/space_image/image_draw.c +++ b/source/blender/editors/space_image/image_draw.c @@ -196,21 +196,21 @@ void ED_image_draw_info(Scene *scene, BLF_color3ub(blf_mono_font, 255, 255, 255); SNPRINTF(str, "X:%-4d Y:%-4d |", x, y); BLF_position(blf_mono_font, dx, dy, 0); - BLF_draw_ascii(blf_mono_font, str, sizeof(str)); + BLF_draw(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str, sizeof(str)); if (zp) { BLF_color3ub(blf_mono_font, 255, 255, 255); SNPRINTF(str, " Z:%-.4f |", 0.5f + 0.5f * (((float)*zp) / (float)0x7fffffff)); BLF_position(blf_mono_font, dx, dy, 0); - BLF_draw_ascii(blf_mono_font, str, sizeof(str)); + BLF_draw(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str, sizeof(str)); } if (zpf) { BLF_color3ub(blf_mono_font, 255, 255, 255); SNPRINTF(str, " Z:%-.3f |", *zpf); BLF_position(blf_mono_font, dx, dy, 0); - BLF_draw_ascii(blf_mono_font, str, sizeof(str)); + BLF_draw(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str, sizeof(str)); } @@ -223,7 +223,7 @@ void ED_image_draw_info(Scene *scene, } BLF_color3ub(blf_mono_font, 255, 255, 255); BLF_position(blf_mono_font, dx, dy, 0); - BLF_draw_ascii(blf_mono_font, str, sizeof(str)); + BLF_draw(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str, sizeof(str)); } @@ -239,7 +239,7 @@ void ED_image_draw_info(Scene *scene, STRNCPY(str, " R:-"); } BLF_position(blf_mono_font, dx, dy, 0); - BLF_draw_ascii(blf_mono_font, str, sizeof(str)); + BLF_draw(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str, sizeof(str)); BLF_color3ubv(blf_mono_font, green); @@ -253,7 +253,7 @@ void ED_image_draw_info(Scene *scene, STRNCPY(str, " G:-"); } BLF_position(blf_mono_font, dx, dy, 0); - BLF_draw_ascii(blf_mono_font, str, sizeof(str)); + BLF_draw(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str, sizeof(str)); BLF_color3ubv(blf_mono_font, blue); @@ -267,7 +267,7 @@ void ED_image_draw_info(Scene *scene, STRNCPY(str, " B:-"); } BLF_position(blf_mono_font, dx, dy, 0); - BLF_draw_ascii(blf_mono_font, str, sizeof(str)); + BLF_draw(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str, sizeof(str)); if (channels == 4) { @@ -282,7 +282,7 @@ void ED_image_draw_info(Scene *scene, STRNCPY(str, "- "); } BLF_position(blf_mono_font, dx, dy, 0); - BLF_draw_ascii(blf_mono_font, str, sizeof(str)); + BLF_draw(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str, sizeof(str)); } @@ -307,7 +307,7 @@ void ED_image_draw_info(Scene *scene, SNPRINTF(str, " | CM R:%-.4f G:%-.4f B:%-.4f", rgba[0], rgba[1], rgba[2]); BLF_position(blf_mono_font, dx, dy, 0); - BLF_draw_ascii(blf_mono_font, str, sizeof(str)); + BLF_draw(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str, sizeof(str)); } } @@ -429,12 +429,12 @@ void ED_image_draw_info(Scene *scene, SNPRINTF(str, "V:%-.4f", val); BLF_position(blf_mono_font, dx, dy, 0); - BLF_draw_ascii(blf_mono_font, str, sizeof(str)); + BLF_draw(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str, sizeof(str)); SNPRINTF(str, " L:%-.4f", lum); BLF_position(blf_mono_font, dx, dy, 0); - BLF_draw_ascii(blf_mono_font, str, sizeof(str)); + BLF_draw(blf_mono_font, str, sizeof(str)); } else if (channels >= 3) { rgb_to_hsv(finalcol[0], finalcol[1], finalcol[2], &hue, &sat, &val); @@ -442,22 +442,22 @@ void ED_image_draw_info(Scene *scene, SNPRINTF(str, "H:%-.4f", hue); BLF_position(blf_mono_font, dx, dy, 0); - BLF_draw_ascii(blf_mono_font, str, sizeof(str)); + BLF_draw(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str, sizeof(str)); SNPRINTF(str, " S:%-.4f", sat); BLF_position(blf_mono_font, dx, dy, 0); - BLF_draw_ascii(blf_mono_font, str, sizeof(str)); + BLF_draw(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str, sizeof(str)); SNPRINTF(str, " V:%-.4f", val); BLF_position(blf_mono_font, dx, dy, 0); - BLF_draw_ascii(blf_mono_font, str, sizeof(str)); + BLF_draw(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str, sizeof(str)); SNPRINTF(str, " L:%-.4f", lum); BLF_position(blf_mono_font, dx, dy, 0); - BLF_draw_ascii(blf_mono_font, str, sizeof(str)); + BLF_draw(blf_mono_font, str, sizeof(str)); } } void draw_image_sample_line(SpaceImage *sima) diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index ec99affe43b..86f79718a68 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -1020,7 +1020,7 @@ static void draw_view_axis(RegionView3D *rv3d, const rcti *rect) const char axis_text[2] = {'x' + i, '\0'}; BLF_color4ubv(BLF_default(), axis_col[i]); - BLF_draw_default_ascii(axis_pos[i][0] + 2, axis_pos[i][1] + 2, 0.0f, axis_text, 1); + BLF_draw_default(axis_pos[i][0] + 2, axis_pos[i][1] + 2, 0.0f, axis_text, 1); } } @@ -1458,9 +1458,7 @@ static void draw_grid_unit_name( BLF_enable(font_id, BLF_SHADOW); BLF_shadow(font_id, 5, (const float[4]){0.0f, 0.0f, 0.0f, 1.0f}); BLF_shadow_offset(font_id, 1, -1); - BLF_draw_default_ascii( - xoffset, *yoffset, 0.0f, numstr[0] ? numstr : grid_unit, sizeof(numstr)); - + BLF_draw_default(xoffset, *yoffset, 0.0f, numstr[0] ? numstr : grid_unit, sizeof(numstr)); BLF_disable(font_id, BLF_SHADOW); } } @@ -2548,11 +2546,7 @@ void ED_scene_draw_fps(const Scene *scene, int xoffset, int *yoffset) *yoffset -= VIEW3D_OVERLAY_LINEHEIGHT; -#ifdef WITH_INTERNATIONAL BLF_draw_default(xoffset, *yoffset, 0.0f, printable, sizeof(printable)); -#else - BLF_draw_default_ascii(xoffset, *yoffset, 0.0f, printable, sizeof(printable)); -#endif BLF_disable(font_id, BLF_SHADOW); } diff --git a/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c b/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c index 05ea35f114f..baa54adaa83 100644 --- a/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c +++ b/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c @@ -300,7 +300,7 @@ static void gizmo_axis_draw(const bContext *C, wmGizmo *gz) text_color[3] = is_active ? 1.0f : 0.9f; } BLF_color4fv(font.id, text_color); - BLF_draw_ascii(font.id, axis_str, 2); + BLF_draw(font.id, axis_str, 2); GPU_matrix_pop(); } } diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 7a83fb71c28..7287927a0be 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -1372,11 +1372,7 @@ static void drawAutoKeyWarning(TransInfo *UNUSED(t), ARegion *region) uchar color[3]; UI_GetThemeColorShade3ubv(TH_TEXT_HI, -50, color); BLF_color3ubv(font_id, color); -#ifdef WITH_INTERNATIONAL BLF_draw_default(xco, yco, 0.0f, printable, BLF_DRAW_STR_DUMMY_MAX); -#else - BLF_draw_default_ascii(xco, yco, 0.0f, printable, BLF_DRAW_STR_DUMMY_MAX); -#endif /* autokey recording icon... */ GPU_blend(GPU_BLEND_ALPHA); diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index cbc2adf641f..9638ec8750e 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -710,7 +710,8 @@ void Transform_Properties(struct wmOperatorType *ot, int flags) } if (flags & P_VIEW2D_EDGE_PAN) { - prop = RNA_def_boolean(ot->srna, "view2d_edge_pan", false, "Edge Pan", "Enable edge panning in 2D view"); + prop = RNA_def_boolean( + ot->srna, "view2d_edge_pan", false, "Edge Pan", "Enable edge panning in 2D view"); RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); } -- cgit v1.2.3