MCPcopy Create free account
hub / github.com/codag-megalith/codag-visualizer / wrapTextToWidth

Function wrapTextToWidth

frontend/src/webview-client/export.ts:155–213  ·  view source on GitHub ↗

* Wrap text to fit within a given width using canvas measurement. * Used as fallback when DOM-based extraction fails (e.g., large zoomed-out graphs).

(text: string, maxWidth: number, fontSize: number, fontWeight: string = '400')

Source from the content-addressed store, hash-verified

153 * Used as fallback when DOM-based extraction fails (e.g., large zoomed-out graphs).
154 */
155function wrapTextToWidth(text: string, maxWidth: number, fontSize: number, fontWeight: string = '400'): string[] {
156 const canvas = document.createElement('canvas');
157 const ctx = canvas.getContext('2d');
158 if (!ctx) return [text];
159
160 ctx.font = `${fontWeight} ${fontSize}px "DM Sans", "Inter", "Segoe UI", -apple-system, sans-serif`;
161
162 const words = text.split(/\s+/);
163 const lines: string[] = [];
164 let currentLine = '';
165
166 for (const word of words) {
167 const testLine = currentLine ? `${currentLine} ${word}` : word;
168 const metrics = ctx.measureText(testLine);
169
170 if (metrics.width > maxWidth && currentLine) {
171 // Current line is full, start new line
172 lines.push(currentLine);
173 currentLine = word;
174 } else {
175 currentLine = testLine;
176 }
177 }
178
179 // Add the last line
180 if (currentLine) {
181 lines.push(currentLine);
182 }
183
184 // If a single word is too long, we need to break it with hyphens
185 const finalLines: string[] = [];
186 for (const line of lines) {
187 if (ctx.measureText(line).width > maxWidth && !line.includes(' ')) {
188 // Single word that's too long - break it
189 let remaining = line;
190 while (remaining.length > 0) {
191 let breakPoint = remaining.length;
192 for (let i = 1; i <= remaining.length; i++) {
193 const segment = remaining.substring(0, i) + (i < remaining.length ? '-' : '');
194 if (ctx.measureText(segment).width > maxWidth && i > 1) {
195 breakPoint = i - 1;
196 break;
197 }
198 }
199 if (breakPoint < remaining.length) {
200 finalLines.push(remaining.substring(0, breakPoint) + '-');
201 remaining = remaining.substring(breakPoint);
202 } else {
203 finalLines.push(remaining);
204 remaining = '';
205 }
206 }
207 } else {
208 finalLines.push(line);
209 }
210 }
211
212 return finalLines.length > 0 ? finalLines : [text];

Callers 1

prepareSVGForExportFunction · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected