Esempio n. 1
0
static void
schgui_cairo_drafter_draw_text(SchGUICairoDrafter *drafter, const struct _SchText *text)
{
    if (text != NULL)
    {
        int visible;

        sch_text_get_visible(text, &visible);

        if (visible)
        {

    SchGUICairoDrafterPrivate *privat = SCHGUI_CAIRO_DRAFTER_GET_PRIVATE(drafter);

    if (privat->cairo != NULL)
    {
        PangoLayout *layout;
        SchMultiline *multiline = sch_text_get_multiline(text);
        int point_size = sch_text_get_size(text);
        float height;
        int alignment;
        cairo_font_options_t *options;
        PangoContext *context;
        int baseline;
        PangoLayoutIter *iter;
        int index;
        int show;
        SchGUIDrawingCfgColor color;
        int          enabled;

        sch_text_get_color(text, &index);

        enabled = schgui_drawing_cfg_get_color(privat->config, index, &color);

        if (enabled)
        {
            if (0) /* show ink rect */
            {
                GeomBounds bounds;
                int        success;

                success = schgui_cairo_drafter_text_bounds(drafter, text, &bounds);

                if (success)
                {
                    cairo_set_source_rgb(privat->cairo, 1.0, 0, 0);
                
                    cairo_move_to(privat->cairo, bounds.min_x, bounds.min_y);
                    cairo_line_to(privat->cairo, bounds.max_x, bounds.min_y);
                
                    cairo_stroke(privat->cairo);

                    cairo_set_source_rgb(privat->cairo, 0.75, 0, 0);
                
                    cairo_move_to(privat->cairo, bounds.max_x, bounds.min_y);
                    cairo_line_to(privat->cairo, bounds.max_x, bounds.max_y);
                    cairo_line_to(privat->cairo, bounds.min_x, bounds.max_y);
                    cairo_line_to(privat->cairo, bounds.min_x, bounds.min_y);
                    //cairo_close_path(privat->cairo);

                    cairo_stroke(privat->cairo);
                
                    cairo_set_source_rgb(privat->cairo, 0, 0, 0);
                }

                cairo_set_source_rgb(privat->cairo, 0, 0, 1.0);
                cairo_new_sub_path(privat->cairo);
                cairo_arc(privat->cairo, sch_text_get_x(text), sch_text_get_y(text), 10, 0, 2 * M_PI);
                cairo_stroke(privat->cairo);
                cairo_set_source_rgb(privat->cairo, 0, 0, 0);
            }

            cairo_save(privat->cairo);
   
            height = 1000 * point_size / 72;

            layout = pango_cairo_create_layout(privat->cairo);
            pango_cairo_context_set_resolution(pango_layout_get_context(layout), 936);

//  context = pango_layout_get_context(layout);
//  options = cairo_font_options_create ();
//  cairo_font_options_set_hint_metrics (options, CAIRO_HINT_METRICS_OFF);
//  cairo_font_options_set_hint_style (options, CAIRO_HINT_STYLE_MEDIUM);
//  pango_cairo_context_set_font_options (context, options);
//  cairo_font_options_destroy (options);


            cairo_set_source_rgb(privat->cairo, color.red, color.green, color.blue);


            pango_font_description_set_size(privat->desc, point_size * PANGO_SCALE );
            pango_layout_set_spacing(layout, 40000);
        
            pango_layout_set_font_description(layout, privat->desc);

            sch_text_get_show(text, &show);
            pango_layout_set_markup(layout, sch_multiline_peek_markup(multiline, show), -1);


            PangoFontMetrics *metrics = pango_context_get_metrics(
                pango_layout_get_context(layout),
                privat->desc,
                NULL
                );

        
            cairo_move_to(privat->cairo, sch_text_get_x(text), sch_text_get_y(text));
        
            cairo_rotate(privat->cairo, M_PI * sch_text_get_angle(text) / 180);

            cairo_scale(privat->cairo, 1, -1);

            baseline = pango_layout_get_baseline(layout); 

            alignment = sch_text_get_alignment(text);
#if 1
            switch (alignment)
            {
                case 2:
                case 5:
                case 8: 
                /* upper */
                //cairo_rel_move_to(privat->cairo, 0, -pango_font_metrics_get_ascent(metrics)/(privat->zoom * PANGO_SCALE));
                //cairo_rel_move_to(privat->cairo, 0, height);
                break;

                case 1:
                case 4:
                case 7:
                    /* center */
                    cairo_rel_move_to(privat->cairo, 0, -pango_font_metrics_get_ascent(metrics)/(privat->zoom * PANGO_SCALE));
                    cairo_rel_move_to(privat->cairo, 0, height);
                    cairo_rel_move_to(privat->cairo, 0, -pango_font_metrics_get_ascent(metrics) * sch_multiline_lines(multiline)/(2 * privat->zoom * PANGO_SCALE));
                    cairo_rel_move_to(privat->cairo, 0, -pango_font_metrics_get_descent(metrics) * (sch_multiline_lines(multiline) - 1)/(2 * privat->zoom * PANGO_SCALE));
                    break;

                case 0:
                case 3:
                case 6:
                default:
                    /* lower */
                    //cairo_rel_move_to(privat->cairo, 0, -pango_font_metrics_get_ascent(metrics) * sch_multiline_lines(multiline)/(privat->zoom * PANGO_SCALE));
                    //cairo_rel_move_to(privat->cairo, 0, -pango_font_metrics_get_descent(metrics) * (sch_multiline_lines(multiline)-1)/(privat->zoom * PANGO_SCALE));
                    //cairo_rel_move_to(privat->cairo, 0, -pango_layout_get_spacing(layout) * (sch_multiline_lines(multiline)-1)/ PANGO_SCALE);
                    iter = pango_layout_get_iter(layout);
                    while (!pango_layout_iter_at_last_line(iter))
                    {
                        pango_layout_iter_next_line(iter);
                    }
                    cairo_rel_move_to(privat->cairo, 0, -pango_layout_iter_get_baseline(iter) / PANGO_SCALE);
                    pango_layout_iter_free(iter);
            }
#endif

            //g_debug("Ascent:    %d", pango_font_metrics_get_ascent(metrics));
            //g_debug("Descent:   %d", pango_font_metrics_get_descent(metrics));
            //g_debug("Spacing:   %d", pango_layout_get_spacing(layout));
            //g_debug("Font size: %d", pango_font_description_get_size(privat->desc));
            //g_debug("Baseline   %d", pango_layout_get_baseline(layout));            

            pango_font_metrics_unref(metrics);

            pango_cairo_show_layout(privat->cairo, layout);

            cairo_restore(privat->cairo);

            g_object_unref(layout);
        }
    }
}
}
 
}
Esempio n. 2
0
static void
schgui_cairo_text_draw(SchGUICairoDrawItem *item, cairo_t *cairo)
{
    if (cairo != NULL)
    {
        SchGUICairoTextPrivate *privat = SCHGUI_CAIRO_TEXT_GET_PRIVATE(item);

        if (privat != NULL)
        {
            PangoLayout *layout = pango_cairo_create_layout(cairo);

            if (layout != NULL)
            {
                PangoLayoutIter *iter;
                int width;

                cairo_save(cairo);

                cairo_set_source_rgba(cairo, privat->red, privat->green, privat->blue, privat->alpha);


                pango_cairo_context_set_resolution(pango_layout_get_context(layout), 936);
                pango_layout_set_spacing(layout, 40000);
                pango_layout_set_font_description(layout, privat->font_desc);

                pango_layout_set_markup(layout, privat->markup, -1);

                cairo_move_to(cairo, privat->x, privat->y);
                cairo_rotate(cairo, privat->angle);
                cairo_scale(cairo, 1, -1);

                switch (privat->alignment)
                {
                    case 2:
                    case 5:
                    case 8: 
                        /* upper */
                        break;

                    case 1:
                    case 4:
                    case 7:
                        /* center */
                        iter = pango_layout_get_iter(layout);
                        while (!pango_layout_iter_at_last_line(iter))
                        {
                            pango_layout_iter_next_line(iter);
                        }
                        cairo_rel_move_to(cairo, 0, -pango_layout_iter_get_baseline(iter) / PANGO_SCALE / 2);
                        pango_layout_iter_free(iter);
                        break;

                    case 0:
                    case 3:
                    case 6:
                    default:
                        /* lower */
                        iter = pango_layout_get_iter(layout);
                        while (!pango_layout_iter_at_last_line(iter))
                        {
                            pango_layout_iter_next_line(iter);
                        }
                        cairo_rel_move_to(cairo, 0, -pango_layout_iter_get_baseline(iter) / PANGO_SCALE);
                        pango_layout_iter_free(iter);
                }

                switch (privat->alignment)
                {

                    case 3:
                    case 4:
                    case 5:
                        /* center */
                        pango_layout_get_size(layout, &width, NULL);
                        cairo_rel_move_to(cairo, -width / PANGO_SCALE / 2, 0);
                        break;

                    case 6:
                    case 7:
                    case 8:
                        pango_layout_get_size(layout, &width, NULL);
                        cairo_rel_move_to(cairo, -width / PANGO_SCALE, 0);
                        /* right */
                        break;

                    case 0:
                    case 1:
                    case 2:
                    default:
                        /* left */
                        ;
                }

                pango_cairo_show_layout(cairo, layout);

                cairo_restore(cairo);

                g_object_unref(layout);
            }
        }
    }
}
Esempio n. 3
0
static void
render_para (GdkDrawable        *drawable,
             GtkTextRenderState *render_state,
             GtkTextLineDisplay *line_display,
             /* Top-left corner of paragraph including all margins */
             int                 x,
             int                 y,
             int                 selection_start_index,
             int                 selection_end_index,
             GList             **widgets)
{
  GSList *shaped_pointer = line_display->shaped_objects;
  PangoLayout *layout = line_display->layout;
  int byte_offset = 0;
  PangoLayoutIter *iter;
  PangoRectangle layout_logical;
  int screen_width;
  GdkGC *fg_gc, *bg_gc;
  gint state;
  
  gboolean first = TRUE;

  iter = pango_layout_get_iter (layout);

  pango_layout_iter_get_layout_extents (iter, NULL, &layout_logical);

  /* Adjust for margins */
  
  layout_logical.x += line_display->x_offset * PANGO_SCALE;
  layout_logical.y += line_display->top_margin * PANGO_SCALE;

  screen_width = line_display->total_width;
  
  if (GTK_WIDGET_HAS_FOCUS (render_state->widget))
    state = GTK_STATE_SELECTED;
  else
    state = GTK_STATE_ACTIVE;

  fg_gc = render_state->widget->style->text_gc [state];
  bg_gc = render_state->widget->style->base_gc [state];

  do
    {
      PangoLayoutLine *line = pango_layout_iter_get_line (iter);
      int selection_y, selection_height;
      int first_y, last_y;
      PangoRectangle line_rect;
      int baseline;
      
      pango_layout_iter_get_line_extents (iter, NULL, &line_rect);
      baseline = pango_layout_iter_get_baseline (iter);
      pango_layout_iter_get_line_yrange (iter, &first_y, &last_y);
      
      /* Adjust for margins */

      line_rect.x += line_display->x_offset * PANGO_SCALE;
      line_rect.y += line_display->top_margin * PANGO_SCALE;
      baseline += line_display->top_margin * PANGO_SCALE;

      /* Selection is the height of the line, plus top/bottom
       * margin if we're the first/last line
       */
      selection_y = y + PANGO_PIXELS (first_y) + line_display->top_margin;
      selection_height = PANGO_PIXELS (last_y) - PANGO_PIXELS (first_y);

      if (first)
        {
          selection_y -= line_display->top_margin;
          selection_height += line_display->top_margin;
        }
      
      if (pango_layout_iter_at_last_line (iter))
        selection_height += line_display->bottom_margin;
      
      first = FALSE;

      if (selection_start_index < byte_offset &&
          selection_end_index > line->length + byte_offset) /* All selected */
        {
          gdk_draw_rectangle (drawable,
                              bg_gc,
                              TRUE,
                              x + line_display->left_margin,
                              selection_y,
                              screen_width,
                              selection_height);

          render_layout_line (drawable, render_state, line, &shaped_pointer,
                              x + PANGO_PIXELS (line_rect.x),
                              y + PANGO_PIXELS (baseline),
                              TRUE,
                              widgets);
        }
      else
        {
          GSList *shaped_pointer_tmp = shaped_pointer;

          render_layout_line (drawable, render_state,
                              line, &shaped_pointer,
                              x + PANGO_PIXELS (line_rect.x),
                              y + PANGO_PIXELS (baseline),
                              FALSE,
                              widgets);

          if (selection_start_index <= byte_offset + line->length &&
              selection_end_index > byte_offset) /* Some selected */
            {
              GdkRegion *clip_region = get_selected_clip (render_state, layout, line,
                                                          x + line_display->x_offset,
                                                          selection_y,
                                                          selection_height,
                                                          selection_start_index, selection_end_index);
              gdk_gc_set_clip_region (fg_gc, clip_region);
              gdk_gc_set_clip_region (bg_gc, clip_region);

              gdk_draw_rectangle (drawable,
                                  bg_gc,
                                  TRUE,
                                  x + PANGO_PIXELS (line_rect.x),
                                  selection_y,
                                  PANGO_PIXELS (line_rect.width),
                                  selection_height);

              render_layout_line (drawable, render_state, line, &shaped_pointer_tmp,
                                  x + PANGO_PIXELS (line_rect.x),
                                  y + PANGO_PIXELS (baseline),
                                  TRUE,
                                  widgets);

              gdk_gc_set_clip_region (fg_gc, NULL);
              gdk_gc_set_clip_region (bg_gc, NULL);

              gdk_region_destroy (clip_region);

              /* Paint in the ends of the line */
              if (line_rect.x > line_display->left_margin * PANGO_SCALE &&
                  ((line_display->direction == GTK_TEXT_DIR_LTR && selection_start_index < byte_offset) ||
                   (line_display->direction == GTK_TEXT_DIR_RTL && selection_end_index > byte_offset + line->length)))
                {
                  gdk_draw_rectangle (drawable,
                                      bg_gc,
                                      TRUE,
                                      x + line_display->left_margin,
                                      selection_y,
                                      PANGO_PIXELS (line_rect.x) - line_display->left_margin,
                                      selection_height);
                }

              if (line_rect.x + line_rect.width <
                  (screen_width + line_display->left_margin) * PANGO_SCALE &&
                  ((line_display->direction == GTK_TEXT_DIR_LTR && selection_end_index > byte_offset + line->length) ||
                   (line_display->direction == GTK_TEXT_DIR_RTL && selection_start_index < byte_offset)))
                {
                  int nonlayout_width;

                  nonlayout_width =
                    line_display->left_margin + screen_width -
                    PANGO_PIXELS (line_rect.x) - PANGO_PIXELS (line_rect.width);

                  gdk_draw_rectangle (drawable,
                                      bg_gc,
                                      TRUE,
                                      x + PANGO_PIXELS (line_rect.x) + PANGO_PIXELS (line_rect.width),
                                      selection_y,
                                      nonlayout_width,
                                      selection_height);
                }
            }
        }

      byte_offset += line->length;
    }
  while (pango_layout_iter_next_line (iter));

  pango_layout_iter_free (iter);
}
Esempio n. 4
0
GpStatus
pango_MeasureString (GpGraphics *graphics, GDIPCONST WCHAR *stringUnicode, int length, GDIPCONST GpFont *font, GDIPCONST RectF *rc,
	GDIPCONST GpStringFormat *format, RectF *boundingBox, int *codepointsFitted, int *linesFilled)
{
	PangoLayout *layout;
	PangoLayoutLine *line;
	PangoRectangle logical;
	PangoLayoutIter *iter;
	int *charsRemoved = NULL;

	cairo_save (graphics->ct);

	layout = gdip_pango_setup_layout (graphics, stringUnicode, length, font, rc, boundingBox, format, &charsRemoved);
	if (!layout) {
		cairo_restore (graphics->ct);
		return OutOfMemory;
	}

	if (codepointsFitted) {
		int charsFitted;
		int lastIndex;
		int y0;
		int y1;
		double min_x;
		double max_x;
		double max_y;
		const char *layoutText;
		if (boundingBox && format && (format->formatFlags & StringFormatFlagsDirectionVertical)) {
			min_x = boundingBox->Y;
			max_x = boundingBox->Y + boundingBox->Height;
			max_y = boundingBox->X + boundingBox->Width;
		} else if (boundingBox) {
			min_x = boundingBox->X;
			max_x = boundingBox->X + boundingBox->Width;
			max_y = boundingBox->Y + boundingBox->Height;
		} else if (format && (format->formatFlags & StringFormatFlagsDirectionVertical)) {
			min_x = rc->Y;
			max_x = rc->Y + rc->Height;
			max_y = rc->X + rc->Width;
		} else {
			min_x = rc->X;
			max_x = rc->X + rc->Width;
			max_y = rc->Y + rc->Height;
		}
		lastIndex = 0;
		iter = pango_layout_get_iter (layout);
		do {
			if (iter == NULL)
				break;
			pango_layout_iter_get_line_yrange (iter, &y0, &y1);
			if (y0 / PANGO_SCALE >= max_y)
				break;
			if (pango_layout_iter_at_last_line (iter)) {
				do {
					pango_layout_iter_get_char_extents (iter, &logical);
					/* check both max and min to catch right-to-left text, also width may be negative */
					if ((logical.x / PANGO_SCALE > max_x || (logical.x + logical.width) / PANGO_SCALE > max_x) || (logical.x / PANGO_SCALE < min_x || (logical.x + logical.width) / PANGO_SCALE < min_x))
						break;
					lastIndex = pango_layout_iter_get_index (iter);
				} while (pango_layout_iter_next_char (iter));
				break;
			} else {
				line = pango_layout_iter_get_line_readonly (iter);
				lastIndex = line->start_index + line->length - 1;
			}
		} while (pango_layout_iter_next_line (iter));
		pango_layout_iter_free (iter);
		layoutText = pango_layout_get_text (layout);
		/* this can happen when the string ends in a newline */
		if (lastIndex >= strlen (layoutText))
			lastIndex = strlen (layoutText) - 1;
		/* Add back in any & characters removed and the final newline characters (if any) */
		charsFitted = g_utf8_strlen (layoutText, lastIndex + 1) + charsRemoved [lastIndex];
		//g_warning("lastIndex: %d\t\tcharsRemoved: %d", lastIndex, charsRemoved[lastIndex]);
		/* safe because of null termination */
		switch (layoutText [lastIndex + 1]) {
			case '\r':
				charsFitted++;
				if (layoutText [lastIndex + 2] == '\n')
					charsFitted++;
				break;
			case '\n':
				charsFitted++;
				break;
		}
		*codepointsFitted = charsFitted;
	}

	GdipFree (charsRemoved);

	if (linesFilled) {
		*linesFilled = pango_layout_get_line_count (layout);
// g_warning ("linesFilled %d", *linesFilled);
	}
// else g_warning ("linesFilled %d", pango_layout_get_line_count (layout));

	g_object_unref (layout);
	cairo_restore (graphics->ct);
	return Ok;
}
static VALUE
layout_iter_at_last_line(VALUE self)
{
    return CBOOL2RVAL(pango_layout_iter_at_last_line(_SELF(self)));
}