void set_up_vertex_buffer(struct ft2_source *srcdata) { FT_UInt glyph_index = 0; uint32_t x = 0, space_pos = 0, word_width = 0; size_t len; if (!srcdata->text) return; if (srcdata->custom_width >= 100) srcdata->cx = srcdata->custom_width; else srcdata->cx = get_ft2_text_width(srcdata->text, srcdata); srcdata->cy = srcdata->max_h; obs_enter_graphics(); if (srcdata->vbuf != NULL) { gs_vertbuffer_t *tmpvbuf = srcdata->vbuf; srcdata->vbuf = NULL; gs_vertexbuffer_destroy(tmpvbuf); } srcdata->vbuf = create_uv_vbuffer((uint32_t)wcslen(srcdata->text) * 6, true); if (srcdata->custom_width <= 100) goto skip_word_wrap; if (!srcdata->word_wrap) goto skip_word_wrap; len = wcslen(srcdata->text); for (uint32_t i = 0; i <= len; i++) { if (i == wcslen(srcdata->text)) goto eos_check; if (srcdata->text[i] != L' ' && srcdata->text[i] != L'\n') goto next_char; eos_check:; if (x + word_width > srcdata->custom_width) { if (space_pos != 0) srcdata->text[space_pos] = L'\n'; x = 0; } if (i == wcslen(srcdata->text)) goto eos_skip; x += word_width; word_width = 0; if (srcdata->text[i] == L'\n') x = 0; if (srcdata->text[i] == L' ') space_pos = i; next_char:; glyph_index = FT_Get_Char_Index(srcdata->font_face, srcdata->text[i]); word_width += src_glyph->xadv; eos_skip:; } skip_word_wrap:; fill_vertex_buffer(srcdata); obs_leave_graphics(); }
OBSProjector::~OBSProjector() { bool isMultiview = type == ProjectorType::Multiview; obs_display_remove_draw_callback(GetDisplay(), isMultiview ? OBSRenderMultiview : OBSRender, this); if (source) obs_source_dec_showing(source); if (isMultiview) { for (OBSWeakSource &weakSrc : multiviewScenes) { OBSSource src = OBSGetStrongRef(weakSrc); if (src) obs_source_dec_showing(src); } obs_enter_graphics(); gs_vertexbuffer_destroy(actionSafeMargin); gs_vertexbuffer_destroy(graphicsSafeMargin); gs_vertexbuffer_destroy(fourByThreeSafeMargin); gs_vertexbuffer_destroy(leftLine); gs_vertexbuffer_destroy(topLine); gs_vertexbuffer_destroy(rightLine); obs_leave_graphics(); } if (type == ProjectorType::Multiview) multiviewProjectors.removeAll(this); if (isWindow) windowedProjectors.removeAll(this); App()->DecrementSleepInhibition(); }
static void ft2_source_destroy(void *data) { struct ft2_source *srcdata = data; if (srcdata->font_face != NULL) { FT_Done_Face(srcdata->font_face); srcdata->font_face = NULL; } for (uint32_t i = 0; i < num_cache_slots; i++) { if (srcdata->cacheglyphs[i] != NULL) { bfree(srcdata->cacheglyphs[i]); srcdata->cacheglyphs[i] = NULL; } } if (srcdata->font_name != NULL) bfree(srcdata->font_name); if (srcdata->font_style != NULL) bfree(srcdata->font_style); if (srcdata->text != NULL) bfree(srcdata->text); if (srcdata->texbuf != NULL) bfree(srcdata->texbuf); if (srcdata->colorbuf != NULL) bfree(srcdata->colorbuf); if (srcdata->text_file != NULL) bfree(srcdata->text_file); obs_enter_graphics(); if (srcdata->tex != NULL) { gs_texture_destroy(srcdata->tex); srcdata->tex = NULL; } if (srcdata->vbuf != NULL) { gs_vertexbuffer_destroy(srcdata->vbuf); srcdata->vbuf = NULL; } if (srcdata->draw_effect != NULL) { gs_effect_destroy(srcdata->draw_effect); srcdata->draw_effect = NULL; } obs_leave_graphics(); bfree(srcdata); }
gs_vertbuffer_t *device_vertexbuffer_create(gs_device_t *device, struct gs_vb_data *data, uint32_t flags) { struct gs_vertex_buffer *vb = bzalloc(sizeof(struct gs_vertex_buffer)); vb->device = device; vb->data = data; vb->num = data->num; vb->dynamic = flags & GS_DYNAMIC; if (!create_buffers(vb)) { blog(LOG_ERROR, "device_vertexbuffer_create (GL) failed"); gs_vertexbuffer_destroy(vb); return NULL; } return vb; }