のねのBlog

パソコンの問題や、ソフトウェアの開発で起きた問題など書いていきます。よろしくお願いします^^。

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 }