prawn_hebrew 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/prawn_hebrew.rb +102 -13
- data/lib/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c85ea02d489bf50f5f0c8facaab7928485a9042f324a54bfb06cd974708e5324
|
|
4
|
+
data.tar.gz: 21a63093c22ffe1baf7c9b646a000138ef05694448315f077642a0e7f72acf43
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c4ab1e0ce09de9756667400c9b77b43d2f859734056adce3252ffd327af19c1fc97d79ec8c4832c794ef1020a971980e32b9dbd4adf3d4b1960772e06e2edcc7
|
|
7
|
+
data.tar.gz: dc6e7cd6daae94a23eb250652dd9d1ec754439e921cd3d0707d2b3060cf6515d1e8859e5e32502e46ba0fdbfc8a55fdf62665a0b9089e4c92871a542ea75c66c
|
data/lib/prawn_hebrew.rb
CHANGED
|
@@ -8,12 +8,15 @@ module PrawnHebrew
|
|
|
8
8
|
|
|
9
9
|
# Set to true for debugging which text rendering path is used
|
|
10
10
|
DEBUG_MODE = false
|
|
11
|
-
INVISIBLE_CHARS = /[\u200B\u200C\u200D\u200E\u200F\uFEFF\u00AD\u202A\u202B\u202C\u202D\u202E]/.freeze
|
|
11
|
+
INVISIBLE_CHARS = /[\u2011\u2010\u2012\u2013\u2014\u2018\u2019\u201C\u201D\u2026\u200B\u200C\u200D\u200E\u200F\uFEFF\u00AD\u202A\u202B\u202C\u202D\u202E]/.freeze
|
|
12
12
|
NBSP_CHARS = /[\u00A0\u202F]/.freeze
|
|
13
13
|
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
14
17
|
def sanitize_text(text)
|
|
15
18
|
return text if text.nil?
|
|
16
|
-
text.to_s.gsub(INVISIBLE_CHARS, '').gsub(NBSP_CHARS, ' ')
|
|
19
|
+
text.to_s.gsub(INVISIBLE_CHARS, ' ').gsub(NBSP_CHARS, ' ')
|
|
17
20
|
end
|
|
18
21
|
|
|
19
22
|
def hebrew_formatted_text(text, size: 12, style: :normal, hebrew_font: DEFAULT_HEBREW_FONT, english_font: DEFAULT_ENGLISH_FONT)
|
|
@@ -78,6 +81,8 @@ module PrawnHebrew
|
|
|
78
81
|
rotation = box_opts.delete(:rotate) || 0
|
|
79
82
|
char_spacing = box_opts.delete(:character_spacing) || 0
|
|
80
83
|
leading = box_opts.delete(:leading) || 0
|
|
84
|
+
min_font_size = box_opts.delete(:min_font_size)
|
|
85
|
+
overflow = box_opts[:overflow]
|
|
81
86
|
|
|
82
87
|
# Check if text contains Hebrew characters
|
|
83
88
|
contains_hebrew = text.to_s =~ /\p{Hebrew}/
|
|
@@ -87,21 +92,38 @@ module PrawnHebrew
|
|
|
87
92
|
direction = contains_hebrew ? :rtl : :ltr
|
|
88
93
|
end
|
|
89
94
|
|
|
90
|
-
#
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
+
# Handle shrink_to_fit behavior
|
|
96
|
+
if overflow == :shrink_to_fit
|
|
97
|
+
box_opts.delete(:overflow)
|
|
98
|
+
|
|
99
|
+
if !contains_hebrew && direction == :ltr
|
|
100
|
+
# English-only: use Prawn's built-in shrink_to_fit
|
|
101
|
+
box_opts[:overflow] = :shrink_to_fit
|
|
102
|
+
box_opts[:min_font_size] = min_font_size if min_font_size
|
|
103
|
+
render_english_only_text(text, final_size, style, final_english_font,
|
|
104
|
+
rotation, char_spacing, leading, box_opts)
|
|
105
|
+
else
|
|
106
|
+
# Hebrew/mixed: implement shrinking manually
|
|
107
|
+
shrink_hebrew_text_to_fit(text, final_size, style, final_hebrew_font,
|
|
108
|
+
final_english_font, char_spacing, leading,
|
|
109
|
+
min_font_size, rotation, box_opts)
|
|
110
|
+
end
|
|
95
111
|
else
|
|
96
|
-
#
|
|
97
|
-
if
|
|
98
|
-
|
|
112
|
+
# Normal rendering without shrinking
|
|
113
|
+
if !contains_hebrew && direction == :ltr
|
|
114
|
+
render_english_only_text(text, final_size, style, final_english_font,
|
|
115
|
+
rotation, char_spacing, leading, box_opts)
|
|
116
|
+
else
|
|
117
|
+
# For Hebrew text or RTL direction, use formatted text approach
|
|
118
|
+
if rotation != 0
|
|
119
|
+
rotate(rotation, origin: box_opts[:at] || [0, 0]) do
|
|
120
|
+
render_hebrew_text_content(text, contains_hebrew, direction, final_size, style,
|
|
121
|
+
final_hebrew_font, final_english_font, char_spacing, leading, box_opts)
|
|
122
|
+
end
|
|
123
|
+
else
|
|
99
124
|
render_hebrew_text_content(text, contains_hebrew, direction, final_size, style,
|
|
100
125
|
final_hebrew_font, final_english_font, char_spacing, leading, box_opts)
|
|
101
126
|
end
|
|
102
|
-
else
|
|
103
|
-
render_hebrew_text_content(text, contains_hebrew, direction, final_size, style,
|
|
104
|
-
final_hebrew_font, final_english_font, char_spacing, leading, box_opts)
|
|
105
127
|
end
|
|
106
128
|
end
|
|
107
129
|
end
|
|
@@ -132,6 +154,73 @@ module PrawnHebrew
|
|
|
132
154
|
formatted_text_box(fragments, box_opts)
|
|
133
155
|
end
|
|
134
156
|
end
|
|
157
|
+
|
|
158
|
+
# Shrink Hebrew text to fit in the box by reducing font size
|
|
159
|
+
def shrink_hebrew_text_to_fit(text, initial_size, style, hebrew_font, english_font,
|
|
160
|
+
char_spacing, leading, min_font_size, rotation, box_opts)
|
|
161
|
+
min_size = min_font_size || 5
|
|
162
|
+
current_size = initial_size
|
|
163
|
+
|
|
164
|
+
# Try rendering with progressively smaller font sizes until it fits
|
|
165
|
+
while current_size >= min_size
|
|
166
|
+
# Create a copy of box_opts to test rendering
|
|
167
|
+
test_opts = box_opts.dup
|
|
168
|
+
|
|
169
|
+
# Try rendering at current size
|
|
170
|
+
fragments = hebrew_formatted_text(text, size: current_size, style: style,
|
|
171
|
+
hebrew_font: hebrew_font,
|
|
172
|
+
english_font: english_font)
|
|
173
|
+
|
|
174
|
+
test_opts[:leading] = leading if leading > 0
|
|
175
|
+
|
|
176
|
+
# Test if it fits by attempting to render
|
|
177
|
+
success = character_spacing(char_spacing) do
|
|
178
|
+
if rotation != 0
|
|
179
|
+
rotate(rotation, origin: test_opts[:at] || [0, 0]) do
|
|
180
|
+
result = formatted_text_box(fragments, test_opts.merge(dry_run: true))
|
|
181
|
+
result.empty? || result == ""
|
|
182
|
+
end
|
|
183
|
+
else
|
|
184
|
+
result = formatted_text_box(fragments, test_opts.merge(dry_run: true))
|
|
185
|
+
result.empty? || result == ""
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
# If it fits, render it for real and return
|
|
190
|
+
if success
|
|
191
|
+
character_spacing(char_spacing) do
|
|
192
|
+
if rotation != 0
|
|
193
|
+
rotate(rotation, origin: box_opts[:at] || [0, 0]) do
|
|
194
|
+
formatted_text_box(fragments, box_opts.merge(leading: leading > 0 ? leading : nil).compact)
|
|
195
|
+
end
|
|
196
|
+
else
|
|
197
|
+
formatted_text_box(fragments, box_opts.merge(leading: leading > 0 ? leading : nil).compact)
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
return
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
# Reduce font size and try again
|
|
204
|
+
current_size -= 0.5
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
# If we've reached min size, render at min size anyway
|
|
208
|
+
fragments = hebrew_formatted_text(text, size: min_size, style: style,
|
|
209
|
+
hebrew_font: hebrew_font,
|
|
210
|
+
english_font: english_font)
|
|
211
|
+
|
|
212
|
+
box_opts[:leading] = leading if leading > 0
|
|
213
|
+
|
|
214
|
+
character_spacing(char_spacing) do
|
|
215
|
+
if rotation != 0
|
|
216
|
+
rotate(rotation, origin: box_opts[:at] || [0, 0]) do
|
|
217
|
+
formatted_text_box(fragments, box_opts)
|
|
218
|
+
end
|
|
219
|
+
else
|
|
220
|
+
formatted_text_box(fragments, box_opts)
|
|
221
|
+
end
|
|
222
|
+
end
|
|
223
|
+
end
|
|
135
224
|
end
|
|
136
225
|
end
|
|
137
226
|
|
data/lib/version.rb
CHANGED