Opera10 commited on
Commit
582146b
·
verified ·
1 Parent(s): 4eab0e5

Update styles/karaoke.py

Browse files
Files changed (1) hide show
  1. styles/karaoke.py +34 -26
styles/karaoke.py CHANGED
@@ -24,47 +24,60 @@ def draw_frame(draw, img, width, height, style_config, lines, line_metrics, acti
24
  bottom_reference = height - style_config.marginV
25
  start_y_of_block = bottom_reference - total_block_height
26
 
 
 
 
27
  space_w = draw.textlength(" ", font=font)
28
 
29
- # 1. محاسبه مختصات همه کلمات
 
 
 
 
 
 
 
 
 
 
 
 
30
  words_to_draw = []
31
  global_word_counter = 0
32
  temp_y = start_y_of_block
33
 
34
  for line_idx, metrics in enumerate(line_metrics):
35
- # محاسبه اینکه آیا کلمه فعال در این خط قرار دارد یا خیر
36
  line_start_idx = sum(len(m["words"]) for m in line_metrics[:line_idx])
37
  is_active_on_line = (active_idx >= line_start_idx and active_idx < line_start_idx + len(metrics["words"]))
38
 
39
- # محاسبه عرض خط: اگر کلمه فعال اینجاست، پدینگ آن را به عرض کل خط اضافه کن
40
- dynamic_line_width = metrics["width"] + (style_config.paddingX * 2 if is_active_on_line else 0)
41
  cursor_x = (width + dynamic_line_width) / 2 + style_config.x
42
 
43
- # تراز عمودی متن در وسط کادر ا توجه به پدینگ عمودی)
44
- text_y_pos = temp_y + style_config.paddingY
45
 
46
  for w_i, word in enumerate(metrics["words"]):
47
  g_idx = line_start_idx + w_i
48
  w_len = metrics["word_widths"][w_i]
49
 
50
- # فقط اگر این کلمه فعال بود، آفست پدینگ را اعمال کن
51
- current_word_padding = style_config.paddingX if g_idx == active_idx else 0
 
 
52
  word_x = cursor_x - w_len - current_word_padding
53
 
54
  words_to_draw.append({
55
  "text": word, "x": word_x, "y": text_y_pos, "width": w_len,
56
- "global_idx": global_word_counter
 
57
  })
58
 
59
- # جابجایی مکان‌نما برای کلمه بعدی: (عرض کلمه + فاصله خالی + پدینگ احتمالی)
60
  cursor_x -= (w_len + space_w + (current_word_padding * 2))
61
  global_word_counter += 1
62
 
63
  temp_y += line_height_px
64
 
65
  VERTICAL_CORRECTION = int(style_config.fontSize * 0.22)
66
- pad_x = style_config.paddingX
67
- pad_y = style_config.paddingY
68
 
69
  # 2. رسم کادرها (برای اینکه زیر متن باشند)
70
  for item in words_to_draw:
@@ -75,7 +88,6 @@ def draw_frame(draw, img, width, height, style_config, lines, line_metrics, acti
75
 
76
  if style_name == "auto_director" and is_active:
77
  should_draw_box = True
78
- # رنگ‌های متناوب برای اتو دایرکتور
79
  box_color = (0, 215, 255, 255) if item["global_idx"] % 2 == 0 else (255, 0, 128, 255)
80
 
81
  elif style_name == "karaoke_static" and is_active:
@@ -91,7 +103,7 @@ def draw_frame(draw, img, width, height, style_config, lines, line_metrics, acti
91
 
92
  draw.rounded_rectangle([bx1, by1, bx2, by2], radius=style_config.radius, fill=box_color)
93
 
94
- # 3. رسم متن
95
  for item in words_to_draw:
96
  is_active = (item["global_idx"] == active_idx) and getattr(style_config, 'useActiveColor', True)
97
 
@@ -104,7 +116,6 @@ def draw_frame(draw, img, width, height, style_config, lines, line_metrics, acti
104
 
105
  elif style_name == "auto_director":
106
  if is_active:
107
- # دریافت رنگ کلمه فعال مخصوص auto_director
108
  active_hex = style_config.styleActiveColors.get('auto_director', '#ffffff')
109
  fill_color = color_parser(active_hex, (255, 255, 255, 255))
110
  else:
@@ -113,21 +124,11 @@ def draw_frame(draw, img, width, height, style_config, lines, line_metrics, acti
113
 
114
  elif style_name == "karaoke_static":
115
  if is_active:
116
- # دریافت رنگ کلمه فعال مخصوص karaoke_static
117
  active_hex = style_config.styleActiveColors.get('karaoke_static', '#ffffff')
118
  fill_color = color_parser(active_hex, (255, 255, 255, 255))
119
  else:
120
  custom_text_hex = style_config.styleColors.get('karaoke_static', '#ffffff')
121
  fill_color = color_parser(custom_text_hex, (255, 255, 255, 255))
122
-
123
- elif style_name == "auto_director":
124
- if is_active:
125
- active_hex = style_config.styleActiveColors.get('auto_director', '#ffffff')
126
- fill_color = color_parser(active_hex, (255, 255, 255, 255))
127
- else:
128
- # خواندن رنگ متن اختصاصی از دیکشنری (پیش‌فرض سفید)
129
- custom_text_hex = style_config.styleColors.get('karaoke_static', '#ffffff')
130
- fill_color = color_parser(custom_text_hex, (255, 255, 255, 255))
131
 
132
  # اعمال رنگ دستی کاربر
133
  if word_infos and item["global_idx"] < len(word_infos):
@@ -135,4 +136,11 @@ def draw_frame(draw, img, width, height, style_config, lines, line_metrics, acti
135
  if hasattr(w_obj, 'color') and w_obj.color:
136
  fill_color = color_parser(w_obj.color, fill_color)
137
 
138
- draw.text((item["x"], item["y"]), item["text"], font=font, fill=fill_color, direction='rtl', language='fa')
 
 
 
 
 
 
 
 
24
  bottom_reference = height - style_config.marginV
25
  start_y_of_block = bottom_reference - total_block_height
26
 
27
+ pad_x = style_config.paddingX
28
+ pad_y = style_config.paddingY
29
+
30
  space_w = draw.textlength(" ", font=font)
31
 
32
+ # محاسبه متریک‌های استاندارد فونت بر اساس کلمه مرجع جهت تراز یکدست عمودی تمام کلمات
33
+ ref_word = "سلام"
34
+ try:
35
+ ref_bbox = draw.textbbox((0, 0), ref_word, font=font, direction='rtl', language='fa')
36
+ standard_text_visual_center_y = (ref_bbox[1] + ref_bbox[3]) / 2.0
37
+ standard_text_offset_y = ref_bbox[1]
38
+ standard_text_h = ref_bbox[3] - ref_bbox[1]
39
+ except:
40
+ standard_text_visual_center_y = style_config.fontSize / 2.0
41
+ standard_text_offset_y = 0
42
+ standard_text_h = style_config.fontSize
43
+
44
+ # 1. محاسبه مختصات همه کلمات با تراز دقیق
45
  words_to_draw = []
46
  global_word_counter = 0
47
  temp_y = start_y_of_block
48
 
49
  for line_idx, metrics in enumerate(line_metrics):
 
50
  line_start_idx = sum(len(m["words"]) for m in line_metrics[:line_idx])
51
  is_active_on_line = (active_idx >= line_start_idx and active_idx < line_start_idx + len(metrics["words"]))
52
 
53
+ dynamic_line_width = metrics["width"] + (pad_x * 2 if is_active_on_line else 0)
 
54
  cursor_x = (width + dynamic_line_width) / 2 + style_config.x
55
 
56
+ # مرکز عمودی دقیق و هندسی این خط فعلی
57
+ line_center_y = temp_y + (line_height_px / 2.0)
58
 
59
  for w_i, word in enumerate(metrics["words"]):
60
  g_idx = line_start_idx + w_i
61
  w_len = metrics["word_widths"][w_i]
62
 
63
+ # استفاده از مقدار ثابت برای جلوگیری از نوسان عمودی کلمات خط
64
+ text_y_pos = line_center_y - standard_text_visual_center_y
65
+
66
+ current_word_padding = pad_x if g_idx == active_idx else 0
67
  word_x = cursor_x - w_len - current_word_padding
68
 
69
  words_to_draw.append({
70
  "text": word, "x": word_x, "y": text_y_pos, "width": w_len,
71
+ "global_idx": global_word_counter,
72
+ "line_center_y": line_center_y
73
  })
74
 
 
75
  cursor_x -= (w_len + space_w + (current_word_padding * 2))
76
  global_word_counter += 1
77
 
78
  temp_y += line_height_px
79
 
80
  VERTICAL_CORRECTION = int(style_config.fontSize * 0.22)
 
 
81
 
82
  # 2. رسم کادرها (برای اینکه زیر متن باشند)
83
  for item in words_to_draw:
 
88
 
89
  if style_name == "auto_director" and is_active:
90
  should_draw_box = True
 
91
  box_color = (0, 215, 255, 255) if item["global_idx"] % 2 == 0 else (255, 0, 128, 255)
92
 
93
  elif style_name == "karaoke_static" and is_active:
 
103
 
104
  draw.rounded_rectangle([bx1, by1, bx2, by2], radius=style_config.radius, fill=box_color)
105
 
106
+ # 3. رسم متن با تراز عمودی کاملاً منطبق بر مرکز هندسی کادر
107
  for item in words_to_draw:
108
  is_active = (item["global_idx"] == active_idx) and getattr(style_config, 'useActiveColor', True)
109
 
 
116
 
117
  elif style_name == "auto_director":
118
  if is_active:
 
119
  active_hex = style_config.styleActiveColors.get('auto_director', '#ffffff')
120
  fill_color = color_parser(active_hex, (255, 255, 255, 255))
121
  else:
 
124
 
125
  elif style_name == "karaoke_static":
126
  if is_active:
 
127
  active_hex = style_config.styleActiveColors.get('karaoke_static', '#ffffff')
128
  fill_color = color_parser(active_hex, (255, 255, 255, 255))
129
  else:
130
  custom_text_hex = style_config.styleColors.get('karaoke_static', '#ffffff')
131
  fill_color = color_parser(custom_text_hex, (255, 255, 255, 255))
 
 
 
 
 
 
 
 
 
132
 
133
  # اعمال رنگ دستی کاربر
134
  if word_infos and item["global_idx"] < len(word_infos):
 
136
  if hasattr(w_obj, 'color') and w_obj.color:
137
  fill_color = color_parser(w_obj.color, fill_color)
138
 
139
+ # محاسبه مرکز هندسی کادر رسم شده برای قرارگیری دقیق متن در مرکز کادر
140
+ rect_y1 = item["y"] - int(pad_y * 1.3) + VERTICAL_CORRECTION
141
+ rect_y2 = item["y"] + style_config.fontSize + int(pad_y * 1.3) + VERTICAL_CORRECTION
142
+ rect_center_y = (rect_y1 + rect_y2) / 2.0
143
+
144
+ final_text_y = rect_center_y - standard_text_offset_y - (standard_text_h / 2.0)
145
+
146
+ draw.text((item["x"], final_text_y), item["text"], font=font, fill=fill_color, direction='rtl', language='fa')