pango_layout_get_pixel_extents
2801 void 2802 pango_layout_get_pixel_extents (PangoLayout *layout, 2803 PangoRectangle *ink_rect, 2804 PangoRectangle *logical_rect) 2805 { 2806 g_return_if_fail (PANGO_IS_LAYOUT (layout)); 2807 2808 pango_layout_get_extents (layout, ink_rect, logical_rect); 2809 pango_extents_to_pixels (ink_rect, NULL); 2810 pango_extents_to_pixels (logical_rect, NULL); 2811 } 2812
2801 void 2802 pango_layout_get_pixel_extents (PangoLayout *layout, 2803 PangoRectangle *ink_rect, 2804 PangoRectangle *logical_rect) 2805 { 2806 g_return_if_fail (PANGO_IS_LAYOUT (layout)); 2807 2808 pango_layout_get_extents (layout, ink_rect, logical_rect); 2809 pango_extents_to_pixels (ink_rect, NULL); 2810 pango_extents_to_pixels (logical_rect, NULL); 2811 } 2812
layout: PangoLayout
ink_rect: レイアウトの物理的な範囲を格納するために使用する矩形、または計算結果が必要ない場合は NULL
logical_rect: レイアウトの論理的な範囲を格納するために使用する矩形、または計算結果が必要ない場合は NULL
2775 void 2776 pango_layout_get_extents (PangoLayout *layout, 2777 PangoRectangle *ink_rect, 2778 PangoRectangle *logical_rect) 2779 { 2780 g_return_if_fail (layout != NULL); 2781 2782 pango_layout_get_extents_internal (layout, ink_rect, logical_rect, NULL); 2783 }
2574 static void 2575 pango_layout_get_extents_internal (PangoLayout *layout, 2576 PangoRectangle *ink_rect, 2577 PangoRectangle *logical_rect, 2578 GSList **line_extents) 2579 { 2580 GSList *line_list; 2581 int y_offset = 0; 2582 int width; 2583 gboolean need_width = FALSE; 2584 2585 g_return_if_fail (layout != NULL); 2586 2587 pango_layout_check_lines (layout); 2588 2589 if (ink_rect && layout->ink_rect_cached) 2590 { 2591 *ink_rect = layout->ink_rect; 2592 ink_rect = NULL; 2593 } 2594 if (logical_rect && layout->logical_rect_cached) 2595 { 2596 *logical_rect = layout->logical_rect; 2597 logical_rect = NULL; 2598 } 2599 if (!ink_rect && !logical_rect && !line_extents) 2600 return; 2601 2602 /* When we are not wrapping, we need the overall width of the layout to 2603 * figure out the x_offsets of each line. However, we only need the 2604 * x_offsets if we are computing the ink_rect or individual line extents. 2605 */ 2606 width = layout->width; 2607 2608 if (layout->auto_dir) 2609 { 2610 /* If one of the lines of the layout is not left aligned, then we need 2611 * the width of the layout to calculate line x-offsets; this requires 2612 * looping through the lines for layout->auto_dir. 2613 */ 2614 line_list = layout->lines; 2615 while (line_list && !need_width) 2616 { 2617 PangoLayoutLine *line = line_list->data; 2618 2619 if (get_alignment (layout, line) != PANGO_ALIGN_LEFT) 2620 need_width = TRUE; 2621 2622 line_list = line_list->next; 2623 } 2624 } 2625 else if (layout->alignment != PANGO_ALIGN_LEFT) 2626 need_width = TRUE; 2627 2628 if (width == -1 && need_width && (ink_rect || line_extents)) 2629 { 2630 PangoRectangle overall_logical; 2631 2632 pango_layout_get_extents_internal (layout, NULL, &overall_logical, NULL); 2633 width = overall_logical.width; 2634 } 2635 2636 if (logical_rect) 2637 { 2638 logical_rect->x = 0; 2639 logical_rect->y = 0; 2640 logical_rect->width = 0; 2641 logical_rect->height = 0; 2642 } 2643 2644 line_list = layout->lines; 2645 while (line_list) 2646 { 2647 PangoLayoutLine *line = line_list->data; 2648 /* Line extents in layout coords (origin at 0,0 of the layout) */ 2649 PangoRectangle line_ink_layout; 2650 PangoRectangle line_logical_layout; 2651 2652 int new_pos; 2653 2654 /* This block gets the line extents in layout coords */ 2655 { 2656 int baseline; 2657 2658 get_line_extents_layout_coords (layout, line, 2659 width, y_offset, 2660 &baseline, 2661 ink_rect ? &line_ink_layout : NULL, 2662 &line_logical_layout); 2663 2664 if (line_extents) 2665 { 2666 Extents *ext = g_slice_new (Extents); 2667 ext->baseline = baseline; 2668 ext->ink_rect = line_ink_layout; 2669 ext->logical_rect = line_logical_layout; 2670 *line_extents = g_slist_prepend (*line_extents, ext); 2671 } 2672 } 2673 2674 if (ink_rect) 2675 { 2676 /* Compute the union of the current ink_rect with 2677 * line_ink_layout 2678 */ 2679 2680 if (line_list == layout->lines) 2681 { 2682 *ink_rect = line_ink_layout; 2683 } 2684 else 2685 { 2686 new_pos = MIN (ink_rect->x, line_ink_layout.x); 2687 ink_rect->width = 2688 MAX (ink_rect->x + ink_rect->width, 2689 line_ink_layout.x + line_ink_layout.width) - new_pos; 2690 ink_rect->x = new_pos; 2691 2692 new_pos = MIN (ink_rect->y, line_ink_layout.y); 2693 ink_rect->height = 2694 MAX (ink_rect->y + ink_rect->height, 2695 line_ink_layout.y + line_ink_layout.height) - new_pos; 2696 ink_rect->y = new_pos; 2697 } 2698 } 2699 2700 if (logical_rect) 2701 { 2702 if (layout->width == -1) 2703 { 2704 /* When no width is set on layout, we can just compute the max of the 2705 * line lengths to get the horizontal extents ... logical_rect.x = 0. 2706 */ 2707 logical_rect->width = MAX (logical_rect->width, line_logical_layout.width); 2708 } 2709 else 2710 { 2711 /* When a width is set, we have to compute the union of the horizontal 2712 * extents of all the lines. 2713 */ 2714 if (line_list == layout->lines) 2715 { 2716 logical_rect->x = line_logical_layout.x; 2717 logical_rect->width = line_logical_layout.width; 2718 } 2719 else 2720 { 2721 new_pos = MIN (logical_rect->x, line_logical_layout.x); 2722 logical_rect->width = 2723 MAX (logical_rect->x + logical_rect->width, 2724 line_logical_layout.x + line_logical_layout.width) - new_pos; 2725 logical_rect->x = new_pos; 2726 2727 } 2728 } 2729 2730 logical_rect->height += line_logical_layout.height; 2731 2732 /* No space after the last line, of course. */ 2733 if (line_list->next != NULL) 2734 logical_rect->height += layout->spacing; 2735 } 2736 2737 y_offset += line_logical_layout.height + layout->spacing; 2738 line_list = line_list->next; 2739 } 2740 2741 if (ink_rect) 2742 { 2743 layout->ink_rect = *ink_rect; 2744 layout->ink_rect_cached = TRUE; 2745 } 2746 if (logical_rect) 2747 { 2748 layout->logical_rect = *logical_rect; 2749 layout->logical_rect_cached = TRUE; 2750 } 2751 if (line_extents) 2752 *line_extents = g_slist_reverse (*line_extents); 2753 }