def wrap_text_to_width(text, font, max_width):
    pass
    """Wrap text to fit within specified width"""
    try:
        pass
        from PIL import ImageDraw, Image
        
        if not text.strip():
            pass
            return [""]
        
        # Create temporary image for measurements
        temp_img = Image.new('RGBA', (1, 1))
        draw = ImageDraw.Draw(temp_img)
        
        # Check if entire text fits
        bbox = draw.textbbox((0, 0), text, font=font)
        text_width = bbox[2] - bbox[0]
        
        if text_width <= max_width:
            pass
            return [text]
        
        # Split into words and wrap
        words = text.split()
        lines = []
        current_line = ""
        
        for word in words:
            pass
            test_line = current_line + (" " if current_line else "") + word
            bbox = draw.textbbox((0, 0), test_line, font=font)
            test_width = bbox[2] - bbox[0]
            
            if test_width <= max_width:
                pass
                current_line = test_line
            else:
                pass
                if current_line:
                    pass
                    lines.append(current_line)
                    current_line = word
                else:
                    pass
                    # Single word is too long, force wrap
                    lines.append(word)
                    current_line = ""
        
        if current_line:
            pass
            lines.append(current_line)
        
        return lines
        
    except Exception as e:
        pass
        return [text]

def render_text_with_stroke(draw, position, text, font, fill_color, stroke_color=None, stroke_width=0):
    pass
    """Render text with optional stroke/outline"""
    try:
        pass
        x, y = position
        
        if stroke_color and stroke_width > 0:
            pass
            # Render stroke by drawing text at offset positions
            for dx in range(-stroke_width, stroke_width + 1):
                pass
                for dy in range(-stroke_width, stroke_width + 1):
                    pass
                    if dx != 0 or dy != 0:
                        pass
                        draw.text((x + dx, y + dy), text, font=font, fill=stroke_color)
        
        # Render main text
        draw.text((x, y), text, font=font, fill=fill_color)
        
        
    except Exception as e:
        pass
        import traceback
        traceback.print_exc()

def calculate_text_metrics(text, font):
    pass
    """Calculate comprehensive text metrics"""
    try:
        pass
        from PIL import ImageDraw, Image
        
        # Create temporary image for measurements
        temp_img = Image.new('RGBA', (1, 1))
        draw = ImageDraw.Draw(temp_img)
        
        # Get bounding box
        bbox = draw.textbbox((0, 0), text, font=font)
        
        metrics = {
            'width': bbox[2] - bbox[0],
            'height': bbox[3] - bbox[1],
            'left_bearing': bbox[0],
            'top_bearing': bbox[1],
            'advance_width': bbox[2],
            'advance_height': bbox[3]
        }
        
        # Get additional font metrics if available
        try:
            pass
            metrics['ascent'] = font.getmetrics()[0]
            metrics['descent'] = font.getmetrics()[1]
        except:
            pass
            metrics['ascent'] = metrics['height']
            metrics['descent'] = 0
        
        return metrics
        
    except Exception as e:
        pass
        import traceback
        traceback.print_exc()
        return {'width': 0, 'height': 0}

def apply_text_effects(img, text_position, text_size, effects):
    pass
    """Apply various text effects like shadow, glow, etc."""
    try:
        pass
        from PIL import Image, ImageFilter, ImageEnhance
        
        
        result_img = img.copy()
        
        if 'shadow' in effects:
            pass
            shadow_config = effects['shadow']
            offset_x = shadow_config.get('offset_x', 2)
            offset_y = shadow_config.get('offset_y', 2)
            blur_radius = shadow_config.get('blur', 0)
            shadow_color = shadow_config.get('color', (0, 0, 0, 128))
            
            # Create shadow layer
            shadow_img = Image.new('RGBA', img.size, (0, 0, 0, 0))
            # Draw shadow text (this would need the actual text rendering logic)
            
            if blur_radius > 0:
                pass
                shadow_img = shadow_img.filter(ImageFilter.GaussianBlur(radius=blur_radius))
            
            # Composite shadow
            result_img = Image.alpha_composite(result_img, shadow_img)
        
        if 'glow' in effects:
            pass
            glow_config = effects['glow']
            glow_color = glow_config.get('color', (255, 255, 255, 128))
            glow_radius = glow_config.get('radius', 3)
            
            # Create glow effect
            glow_img = Image.new('RGBA', img.size, (0, 0, 0, 0))
            # Apply glow rendering logic here
            
            result_img = Image.alpha_composite(result_img, glow_img)
        
        if 'gradient' in effects:
            pass
            gradient_config = effects['gradient']
            start_color = gradient_config.get('start', (255, 255, 255))
            end_color = gradient_config.get('end', (0, 0, 0))
            direction = gradient_config.get('direction', 'horizontal')
            
            # Apply gradient to text
        
        return result_img
        
    except Exception as e:
        pass
        import traceback
        traceback.print_exc()
        return img

def optimize_text_layout(text_blocks, canvas_width, canvas_height):
    pass
    """Optimize layout of multiple text blocks to minimize overlap"""
    try:
        pass
        
        optimized_blocks = []
        
        for i, block in enumerate(text_blocks):
            pass
            x = block.get('x', 0)
            y = block.get('y', 0)
            width = block.get('width', 0)
            height = block.get('height', 0)
            
            # Check for overlaps with previous blocks
            overlap_found = False
            for prev_block in optimized_blocks:
                pass
                if rectangles_overlap(
                    (x, y, width, height),
                    (prev_block['x'], prev_block['y'], prev_block['width'], prev_block['height'])
                ):
                    overlap_found = True
                    break
            
            if overlap_found:
                pass
                # Find new position
                new_x, new_y = find_non_overlapping_position(
                    width, height, optimized_blocks, canvas_width, canvas_height
                )
                x, y = new_x, new_y
            
            optimized_block = block.copy()
            optimized_block.update({'x': x, 'y': y})
            optimized_blocks.append(optimized_block)
        
        return optimized_blocks
        
    except Exception as e:
        pass
        import traceback
        traceback.print_exc()
        return text_blocks

def rectangles_overlap(rect1, rect2):
    pass
    """Check if two rectangles overlap"""
    x1, y1, w1, h1 = rect1
    x2, y2, w2, h2 = rect2
    
    return not (x1 + w1 <= x2 or x2 + w2 <= x1 or y1 + h1 <= y2 or y2 + h2 <= y1)

def find_non_overlapping_position(width, height, existing_blocks, canvas_width, canvas_height):
    pass
    """Find a position that doesn't overlap with existing blocks"""
    # Try positions from top-left, moving right then down
    for y in range(0, canvas_height - height, 20):
        pass
        for x in range(0, canvas_width - width, 20):
            pass
            rect = (x, y, width, height)
            
            overlap = False
            for block in existing_blocks:
                pass
                if rectangles_overlap(rect, (block['x'], block['y'], block['width'], block['height'])):
                    pass
                    overlap = True
                    break
            
            if not overlap:
                pass
                return x, y
    
    # If no position found, return original or default
    return 0, 0

def validate_text_rendering(img, text_positions):
    pass
    """Validate that text rendering was successful"""
    try:
        pass
        
        validation_results = []
        
        for i, pos in enumerate(text_positions):
            pass
            result = {
                'position_index': i,
                'x': pos.get('x', 0),
                'y': pos.get('y', 0),
                'width': pos.get('width', 0),
                'height': pos.get('height', 0),
                'valid': True,
                'issues': []
            }
            
            # Check bounds
            if pos.get('x', 0) < 0 or pos.get('y', 0) < 0:
                pass
                result['valid'] = False
                result['issues'].append('Negative position')
            
            if pos.get('x', 0) + pos.get('width', 0) > img.width:
                pass
                result['valid'] = False
                result['issues'].append('Exceeds image width')
            
            if pos.get('y', 0) + pos.get('height', 0) > img.height:
                pass
                result['valid'] = False
                result['issues'].append('Exceeds image height')
            
            # Check for zero dimensions
            if pos.get('width', 0) == 0 or pos.get('height', 0) == 0:
                pass
                result['valid'] = False
                result['issues'].append('Zero dimensions')
            
            validation_results.append(result)
        
        valid_count = sum(1 for r in validation_results if r['valid'])
        
        return validation_results
        
    except Exception as e:
        pass
        import traceback
        traceback.print_exc()
        return []

def process_text_content(text: str) -> str:
    """Normalize text content for single-line rendering."""
    text = text.replace('\n', ' ')
    text = ' '.join(text.split())
    return text
