فهرست منبع

obs-text: Fix alignment with extents

Exeldro 1 سال پیش
والد
کامیت
8c9e4c2822
1فایلهای تغییر یافته به همراه36 افزوده شده و 6 حذف شده
  1. 36 6
      plugins/obs-text/gdiplus/obs-text.cpp

+ 36 - 6
plugins/obs-text/gdiplus/obs-text.cpp

@@ -253,6 +253,7 @@ struct TextSource {
 	uint32_t outline_opacity = 100;
 
 	bool use_extents = false;
+	bool old_extents = false;
 	bool wrap = false;
 	uint32_t extents_cx = 0;
 	uint32_t extents_cy = 0;
@@ -264,10 +265,12 @@ struct TextSource {
 
 	/* --------------------------- */
 
-	inline TextSource(obs_source_t *source_, obs_data_t *settings)
+	inline TextSource(obs_source_t *source_, obs_data_t *settings,
+			  bool old_extents_)
 		: source(source_),
 		  hdc(CreateCompatibleDC(nullptr)),
-		  graphics(hdc)
+		  graphics(hdc),
+		  old_extents(old_extents_)
 	{
 		obs_source_update(source, settings);
 	}
@@ -338,8 +341,10 @@ void TextSource::UpdateFont()
 
 void TextSource::GetStringFormat(StringFormat &format)
 {
-	UINT flags = StringFormatFlagsNoFitBlackBox |
-		     StringFormatFlagsMeasureTrailingSpaces;
+	UINT flags = StringFormatFlagsNoFitBlackBox;
+
+	if (!use_extents || old_extents)
+		flags |= StringFormatFlagsMeasureTrailingSpaces;
 
 	if (vertical)
 		flags |= StringFormatFlagsDirectionVertical |
@@ -500,6 +505,24 @@ void TextSource::CalculateTextSizes(const StringFormat &format,
 	if (use_extents) {
 		text_size.cx = extents_cx;
 		text_size.cy = extents_cy;
+
+		if (!old_extents && !wrap) {
+			if (align == Align::Center) {
+				bounding_box.X +=
+					(extents_cx - bounding_box.Width) / 2;
+			} else if (align == Align::Right) {
+				bounding_box.X +=
+					extents_cx - bounding_box.Width;
+			}
+
+			if (valign == VAlign::Center) {
+				bounding_box.Y +=
+					(extents_cy - bounding_box.Height) / 2;
+			} else if (valign == VAlign::Bottom) {
+				bounding_box.Y +=
+					extents_cy - bounding_box.Height;
+			}
+		}
 	}
 
 	text_size.cx += text_size.cx % 2;
@@ -1117,7 +1140,7 @@ bool obs_module_load(void)
 		return obs_module_text("TextGDIPlus");
 	};
 	si.create = [](obs_data_t *settings, obs_source_t *source) {
-		return (void *)new TextSource(source, settings);
+		return (void *)new TextSource(source, settings, true);
 	};
 	si.destroy = [](void *data) {
 		delete reinterpret_cast<TextSource *>(data);
@@ -1169,13 +1192,20 @@ bool obs_module_load(void)
 
 	obs_source_info si_v2 = si;
 	si_v2.version = 2;
-	si_v2.output_flags &= ~OBS_SOURCE_CAP_OBSOLETE;
 	si_v2.get_defaults = [](obs_data_t *settings) {
 		defaults(settings, 2);
 	};
 
+	obs_source_info si_v3 = si_v2;
+	si_v3.version = 3;
+	si_v3.output_flags &= ~OBS_SOURCE_CAP_OBSOLETE;
+	si_v3.create = [](obs_data_t *settings, obs_source_t *source) {
+		return (void *)new TextSource(source, settings, false);
+	};
+
 	obs_register_source(&si);
 	obs_register_source(&si_v2);
+	obs_register_source(&si_v3);
 
 	const GdiplusStartupInput gdip_input;
 	GdiplusStartup(&gdip_token, &gdip_input, nullptr);