コード例 #1
0
ファイル: gseparator.cpp プロジェクト: ramonelalto/gambas
static gboolean cb_draw(GtkWidget *wid, cairo_t *cr, gSeparator *data)
{
    gint x, y, w, h;
    gColor color;

    x = y = 0;
    w = data->width();
    h = data->height();

    if (w == 1 || h == 1)
    {
        color = data->foreground();
        if (color == COLOR_DEFAULT)
            color = gDesktop::lightfgColor();

        gt_cairo_set_source_color(cr, color);

        cairo_rectangle(cr, x, y, w, h);
        cairo_fill(cr);
    }
    else if (w>=h)
        gtk_render_line(gtk_widget_get_style_context(wid), cr, x, y + (h / 2), x + w - 1, y + (h / 2));
    else
        gtk_render_line(gtk_widget_get_style_context(wid), cr, x + (w / 2), y, x + (w / 2), y + h - 1);

    return false;
}
コード例 #2
0
ファイル: lyricshowviewport.c プロジェクト: wkt/liblyric
static gboolean
lyric_show_viewport_draw(GtkWidget  *widget,cairo_t *cr)
{
    LyricShowViewport *lsv;
    lsv = LYRIC_SHOW_VIEWPORT(widget);
    GtkStyleContext *context;

    GdkWindow   *bin = gtk_viewport_get_bin_window(GTK_VIEWPORT(widget));
    context = gtk_widget_get_style_context(widget);

    GTK_WIDGET_CLASS(lyric_show_viewport_parent_class)->draw(widget,cr);
    if(lsv->priv->is_pressed && gtk_cairo_should_draw_window(cr,bin))
    {
        gint y0,y1;
        y0=y1 = gtk_widget_get_allocated_height(widget)/2.0;///lsv->priv->pos+lsv->priv->pressed_pos;
        gtk_render_line(context,cr,0,y0,
                gtk_widget_get_allocated_width(widget),y1);
                                   
    }

    return FALSE;
}
コード例 #3
0
ファイル: meta-draw-op.c プロジェクト: GNOME/metacity
/* This code was originally rendering anti-aliased using X primitives, and
 * now has been switched to draw anti-aliased using cairo. In general, the
 * closest correspondence between X rendering and cairo rendering is given
 * by offsetting the geometry by 0.5 pixels in both directions before rendering
 * with cairo. This is because X samples at the upper left corner of the
 * pixel while cairo averages over the entire pixel. However, in the cases
 * where the X rendering was an exact rectangle with no "jaggies"
 * we need to be a bit careful about applying the offset. We want to produce
 * the exact same pixel-aligned rectangle, rather than a rectangle with
 * fuzz around the edges.
 */
static void
draw_op_draw_with_env (const MetaDrawOp    *op,
                       GtkStyleContext     *context,
                       cairo_t             *cr,
                       const MetaDrawInfo  *info,
                       MetaPositionExprEnv *env)
{
  GdkRGBA color;

  cairo_save (cr);

  cairo_set_line_width (cr, 1.0);

  switch (op->type)
    {
    case META_DRAW_LINE:
      {
        gdouble x1, x2, y1, y2;

        meta_color_spec_render (op->data.line.color_spec, context, &color);
        gdk_cairo_set_source_rgba (cr, &color);

        if (op->data.line.width > 0)
          cairo_set_line_width (cr, op->data.line.width);

        if (op->data.line.dash_on_length > 0 &&
            op->data.line.dash_off_length > 0)
          {
            double dash_list[2];
            dash_list[0] = op->data.line.dash_on_length;
            dash_list[1] = op->data.line.dash_off_length;
            cairo_set_dash (cr, dash_list, 2, 0);
          }

        x1 = meta_draw_spec_parse_x_position (op->data.line.x1, env);
        y1 = meta_draw_spec_parse_y_position (op->data.line.y1, env);

        if (!op->data.line.x2 && !op->data.line.y2 &&
            op->data.line.width == 0)
          {
            cairo_rectangle (cr, x1, y1, 1, 1);
            cairo_fill (cr);
          }
        else
          {
            if (op->data.line.x2)
              x2 = meta_draw_spec_parse_x_position (op->data.line.x2, env);
            else
              x2 = x1;

            if (op->data.line.y2)
              y2 = meta_draw_spec_parse_y_position (op->data.line.y2, env);
            else
              y2 = y1;

            /* This is one of the cases where we are matching the exact
             * pixel aligned rectangle produced by X; for zero-width lines
             * the generic algorithm produces the right result so we don't
             * need to handle them here.
             */
            if ((y1 == y2 || x1 == x2) && op->data.line.width != 0)
              {
                double offset = op->data.line.width % 2 ? .5 : 0;

                if (y1 == y2)
                  {
                    cairo_move_to (cr, x1, y1 + offset);
                    cairo_line_to (cr, x2, y2 + offset);
                  }
                else
                  {
                    cairo_move_to (cr, x1 + offset, y1);
                    cairo_line_to (cr, x2 + offset, y2);
                  }
              }
            else
              {
                /* zero-width lines include both end-points in X, unlike wide lines */
                if (op->data.line.width == 0)
                  cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);

                cairo_move_to (cr, x1 + .5, y1 + .5);
                cairo_line_to (cr, x2 + .5, y2 + .5);
              }
            cairo_stroke (cr);
          }
      }
      break;

    case META_DRAW_RECTANGLE:
      {
        gdouble rx, ry, rwidth, rheight;

        meta_color_spec_render (op->data.rectangle.color_spec, context, &color);
        gdk_cairo_set_source_rgba (cr, &color);

        rx = meta_draw_spec_parse_x_position (op->data.rectangle.x, env);
        ry = meta_draw_spec_parse_y_position (op->data.rectangle.y, env);
        rwidth = meta_draw_spec_parse_size (op->data.rectangle.width, env);
        rheight = meta_draw_spec_parse_size (op->data.rectangle.height, env);

        /* Filled and stroked rectangles are the other cases
         * we pixel-align to X rasterization
         */
        if (op->data.rectangle.filled)
          {
            cairo_rectangle (cr, rx, ry, rwidth, rheight);
            cairo_fill (cr);
          }
        else
          {
            cairo_rectangle (cr, rx + .5, ry + .5, rwidth, rheight);
            cairo_stroke (cr);
          }
      }
      break;

    case META_DRAW_ARC:
      {
        gdouble rx, ry, rwidth, rheight;
        double start_angle, end_angle;
        double center_x, center_y;

        meta_color_spec_render (op->data.arc.color_spec, context, &color);
        gdk_cairo_set_source_rgba (cr, &color);

        rx = meta_draw_spec_parse_x_position (op->data.arc.x, env);
        ry = meta_draw_spec_parse_y_position (op->data.arc.y, env);
        rwidth = meta_draw_spec_parse_size (op->data.arc.width, env);
        rheight = meta_draw_spec_parse_size (op->data.arc.height, env);

        start_angle = op->data.arc.start_angle * (M_PI / 180.)
                      - (.5 * M_PI); /* start at 12 instead of 3 oclock */
        end_angle = start_angle + op->data.arc.extent_angle * (M_PI / 180.);
        center_x = rx + (double)rwidth / 2. + .5;
        center_y = ry + (double)rheight / 2. + .5;

        cairo_save (cr);

        cairo_translate (cr, center_x, center_y);
        cairo_scale (cr, (double)rwidth / 2., (double)rheight / 2.);

        if (op->data.arc.extent_angle >= 0)
          cairo_arc (cr, 0, 0, 1, start_angle, end_angle);
        else
          cairo_arc_negative (cr, 0, 0, 1, start_angle, end_angle);

        cairo_restore (cr);

        if (op->data.arc.filled)
          {
            cairo_line_to (cr, center_x, center_y);
            cairo_fill (cr);
          }
        else
          cairo_stroke (cr);
      }
      break;

    case META_DRAW_CLIP:
      break;

    case META_DRAW_TINT:
      {
        gdouble rx, ry, rwidth, rheight;

        rx = meta_draw_spec_parse_x_position (op->data.tint.x, env);
        ry = meta_draw_spec_parse_y_position (op->data.tint.y, env);
        rwidth = meta_draw_spec_parse_size (op->data.tint.width, env);
        rheight = meta_draw_spec_parse_size (op->data.tint.height, env);

        meta_color_spec_render (op->data.tint.color_spec, context, &color);
        meta_alpha_gradient_spec_render (op->data.tint.alpha_spec, color, cr,
                                         rx, ry, rwidth, rheight);
      }
      break;

    case META_DRAW_GRADIENT:
      {
        gdouble rx, ry, rwidth, rheight;

        rx = meta_draw_spec_parse_x_position (op->data.gradient.x, env);
        ry = meta_draw_spec_parse_y_position (op->data.gradient.y, env);
        rwidth = meta_draw_spec_parse_size (op->data.gradient.width, env);
        rheight = meta_draw_spec_parse_size (op->data.gradient.height, env);

        meta_gradient_spec_render (op->data.gradient.gradient_spec,
                                   op->data.gradient.alpha_spec,
                                   cr, context, rx, ry, rwidth, rheight);
      }
      break;

    case META_DRAW_IMAGE:
      {
        gdouble scale;
        gdouble rx, ry, rwidth, rheight;
        cairo_surface_t *surface;

        scale = info->scale;
        cairo_scale (cr, 1.0 / scale, 1.0 / scale);

        if (op->data.image.pixbuf)
          {
            env->object_width = gdk_pixbuf_get_width (op->data.image.pixbuf);
            env->object_height = gdk_pixbuf_get_height (op->data.image.pixbuf);
          }

        rwidth = meta_draw_spec_parse_size (op->data.image.width, env) * scale;
        rheight = meta_draw_spec_parse_size (op->data.image.height, env) * scale;

        surface = draw_op_as_surface (op, context, info, rwidth, rheight);

        if (surface)
          {
            rx = meta_draw_spec_parse_x_position (op->data.image.x, env) * scale;
            ry = meta_draw_spec_parse_y_position (op->data.image.y, env) * scale;

            cairo_set_source_surface (cr, surface, rx, ry);

            if (op->data.image.alpha_spec)
              {
                cairo_pattern_t *pattern;

                cairo_translate (cr, rx, ry);
                cairo_scale (cr, rwidth, rheight);

                pattern = meta_alpha_gradient_spec_get_mask (op->data.image.alpha_spec);
                cairo_mask (cr, pattern);

                cairo_pattern_destroy (pattern);
              }
            else
              {
                cairo_paint (cr);
              }

            cairo_surface_destroy (surface);
          }
      }
      break;

    case META_DRAW_GTK_ARROW:
      {
        gdouble rx, ry, rwidth, rheight;
        double angle = 0, size;

        rx = meta_draw_spec_parse_x_position (op->data.gtk_arrow.x, env);
        ry = meta_draw_spec_parse_y_position (op->data.gtk_arrow.y, env);
        rwidth = meta_draw_spec_parse_size (op->data.gtk_arrow.width, env);
        rheight = meta_draw_spec_parse_size (op->data.gtk_arrow.height, env);

        size = MAX(rwidth, rheight);

        switch (op->data.gtk_arrow.arrow)
          {
          case GTK_ARROW_UP:
            angle = 0;
            break;
          case GTK_ARROW_RIGHT:
            angle = M_PI / 2;
            break;
          case GTK_ARROW_DOWN:
            angle = M_PI;
            break;
          case GTK_ARROW_LEFT:
            angle = 3 * M_PI / 2;
            break;
          case GTK_ARROW_NONE:
            return;
          default:
            break;
          }

        gtk_style_context_set_state (context, op->data.gtk_arrow.state);
        gtk_render_arrow (context, cr, angle, rx, ry, size);
      }
      break;

    case META_DRAW_GTK_BOX:
      {
        gdouble rx, ry, rwidth, rheight;

        rx = meta_draw_spec_parse_x_position (op->data.gtk_box.x, env);
        ry = meta_draw_spec_parse_y_position (op->data.gtk_box.y, env);
        rwidth = meta_draw_spec_parse_size (op->data.gtk_box.width, env);
        rheight = meta_draw_spec_parse_size (op->data.gtk_box.height, env);

        gtk_style_context_set_state (context, op->data.gtk_box.state);
        gtk_render_background (context, cr, rx, ry, rwidth, rheight);
        gtk_render_frame (context, cr, rx, ry, rwidth, rheight);
      }
      break;

    case META_DRAW_GTK_VLINE:
      {
        gdouble rx, ry1, ry2;

        rx = meta_draw_spec_parse_x_position (op->data.gtk_vline.x, env);
        ry1 = meta_draw_spec_parse_y_position (op->data.gtk_vline.y1, env);
        ry2 = meta_draw_spec_parse_y_position (op->data.gtk_vline.y2, env);

        gtk_style_context_set_state (context, op->data.gtk_vline.state);
        gtk_render_line (context, cr, rx, ry1, rx, ry2);
      }
      break;

    case META_DRAW_ICON:
      {
        gdouble rx, ry, rwidth, rheight;
        cairo_surface_t *surface;

        rwidth = meta_draw_spec_parse_size (op->data.icon.width, env);
        rheight = meta_draw_spec_parse_size (op->data.icon.height, env);

        surface = draw_op_as_surface (op, context, info, rwidth, rheight);

        if (surface)
          {
            rx = meta_draw_spec_parse_x_position (op->data.icon.x, env);
            ry = meta_draw_spec_parse_y_position (op->data.icon.y, env);

            cairo_set_source_surface (cr, surface, rx, ry);

            if (op->data.icon.alpha_spec)
              {
                cairo_pattern_t *pattern;

                cairo_translate (cr, rx, ry);
                cairo_scale (cr, rwidth, rheight);

                pattern = meta_alpha_gradient_spec_get_mask (op->data.icon.alpha_spec);
                cairo_mask (cr, pattern);

                cairo_pattern_destroy (pattern);
              }
            else
              {
                cairo_paint (cr);
              }

            cairo_surface_destroy (surface);
          }
      }
      break;

    case META_DRAW_TITLE:
      if (info->title_layout)
        {
          gdouble rx, ry;
          PangoRectangle ink_rect, logical_rect;

          meta_color_spec_render (op->data.title.color_spec, context, &color);
          gdk_cairo_set_source_rgba (cr, &color);

          rx = meta_draw_spec_parse_x_position (op->data.title.x, env);
          ry = meta_draw_spec_parse_y_position (op->data.title.y, env);

          if (op->data.title.ellipsize_width)
            {
              gdouble ellipsize_width;
              int right_bearing;

              ellipsize_width = meta_draw_spec_parse_x_position (op->data.title.ellipsize_width, env);
              /* HACK: meta_draw_spec_parse_x_position adds in env->rect.x, subtract out again */
              ellipsize_width -= env->rect.x;

              pango_layout_set_width (info->title_layout, -1);
              pango_layout_get_pixel_extents (info->title_layout,
                                              &ink_rect, &logical_rect);

              /* Pango's idea of ellipsization is with respect to the logical rect.
               * correct for this, by reducing the ellipsization width by the overflow
               * of the un-ellipsized text on the right... it's always the visual
               * right we want regardless of bidi, since since the X we pass in to
               * cairo_move_to() is always the left edge of the line.
               */
              right_bearing = (ink_rect.x + ink_rect.width) - (logical_rect.x + logical_rect.width);
              right_bearing = MAX (right_bearing, 0);

              ellipsize_width -= right_bearing;
              ellipsize_width = MAX (ellipsize_width, 0);

              /* Only ellipsizing when necessary is a performance optimization -
               * pango_layout_set_width() will force a relayout if it isn't the
               * same as the current width of -1.
               */
              if (ellipsize_width < logical_rect.width)
                pango_layout_set_width (info->title_layout, PANGO_SCALE * ellipsize_width);
            }
          else if (rx - env->rect.x + env->title_width >= env->rect.width)
          {
            const double alpha_margin = 30.0;
            int text_space = env->rect.x + env->rect.width -
                             (rx - env->rect.x) - env->right_width;

            double startalpha = 1.0 - (alpha_margin/((double)text_space));

            cairo_pattern_t *linpat;
            linpat = cairo_pattern_create_linear (rx, ry, text_space,
                                                  env->title_height);
            cairo_pattern_add_color_stop_rgba (linpat, 0, color.red,
                                                          color.green,
                                                          color.blue,
                                                          color.alpha);
            cairo_pattern_add_color_stop_rgba (linpat, startalpha,
                                                       color.red,
                                                       color.green,
                                                       color.blue,
                                                       color.alpha);
            cairo_pattern_add_color_stop_rgba (linpat, 1, color.red,
                                                          color.green,
                                                          color.blue, 0);
            cairo_set_source(cr, linpat);
            cairo_pattern_destroy(linpat);
          }

          cairo_move_to (cr, rx, ry);
          pango_cairo_show_layout (cr, info->title_layout);

          /* Remove any ellipsization we might have set; will short-circuit
           * if the width is already -1 */
          pango_layout_set_width (info->title_layout, -1);
        }
      break;

    case META_DRAW_OP_LIST:
      {
        MetaRectangleDouble d_rect;

        d_rect.x = meta_draw_spec_parse_x_position (op->data.op_list.x, env);
        d_rect.y = meta_draw_spec_parse_y_position (op->data.op_list.y, env);
        d_rect.width = meta_draw_spec_parse_size (op->data.op_list.width, env);
        d_rect.height = meta_draw_spec_parse_size (op->data.op_list.height, env);

        meta_draw_op_list_draw_with_style (op->data.op_list.op_list,
                                           context, cr, info, d_rect);
      }
      break;

    case META_DRAW_TILE:
      {
        gdouble rx, ry, rwidth, rheight;
        gdouble tile_xoffset, tile_yoffset;
        MetaRectangleDouble tile;

        rx = meta_draw_spec_parse_x_position (op->data.tile.x, env);
        ry = meta_draw_spec_parse_y_position (op->data.tile.y, env);
        rwidth = meta_draw_spec_parse_size (op->data.tile.width, env);
        rheight = meta_draw_spec_parse_size (op->data.tile.height, env);

        cairo_save (cr);

        cairo_rectangle (cr, rx, ry, rwidth, rheight);
        cairo_clip (cr);

        tile_xoffset = meta_draw_spec_parse_x_position (op->data.tile.tile_xoffset, env);
        tile_yoffset = meta_draw_spec_parse_y_position (op->data.tile.tile_yoffset, env);
        /* tile offset should not include x/y */
        tile_xoffset -= env->rect.x;
        tile_yoffset -= env->rect.y;

        tile.width = meta_draw_spec_parse_size (op->data.tile.tile_width, env);
        tile.height = meta_draw_spec_parse_size (op->data.tile.tile_height, env);

        tile.x = rx - tile_xoffset;

        while (tile.x < (rx + rwidth))
          {
            tile.y = ry - tile_yoffset;
            while (tile.y < (ry + rheight))
              {
                meta_draw_op_list_draw_with_style (op->data.tile.op_list,
                                                   context, cr, info, tile);

                tile.y += tile.height;
              }

            tile.x += tile.width;
          }
        cairo_restore (cr);
      }
      break;

    default:
      break;
    }

   cairo_restore (cr);
}
コード例 #4
0
ファイル: gtktearoffmenuitem.c プロジェクト: Davletvm/gtk
static gboolean
gtk_tearoff_menu_item_draw (GtkWidget *widget,
                            cairo_t   *cr)
{
    GtkMenuItem *menu_item;
    GtkStateFlags state;
    GtkStyleContext *context;
    GtkBorder padding;
    gint x, y, width, height;
    gint right_max;
    guint border_width;
    GtkTextDirection direction;
    GtkWidget *parent;
    gdouble angle;

    menu_item = GTK_MENU_ITEM (widget);
    context = gtk_widget_get_style_context (widget);
    direction = gtk_widget_get_direction (widget);
    state = gtk_widget_get_state_flags (widget);

    border_width = gtk_container_get_border_width (GTK_CONTAINER (menu_item));
    x = border_width;
    y = border_width;
    width = gtk_widget_get_allocated_width (widget) - border_width * 2;
    height = gtk_widget_get_allocated_height (widget) - border_width * 2;
    right_max = x + width;

    gtk_style_context_save (context);
    gtk_style_context_set_state (context, state);
    gtk_style_context_get_padding (context, state, &padding);

    if (state & GTK_STATE_FLAG_PRELIGHT)
    {
        gtk_render_background (context, cr, x, y, width, height);
        gtk_render_frame (context, cr, x, y, width, height);
    }

    parent = gtk_widget_get_parent (widget);
    if (GTK_IS_MENU (parent) && gtk_menu_get_tearoff_state (GTK_MENU (parent)))
    {
        gint arrow_x;

        if (menu_item->priv->toggle_size > ARROW_SIZE)
        {
            if (direction == GTK_TEXT_DIR_LTR)
            {
                arrow_x = x + (menu_item->priv->toggle_size - ARROW_SIZE)/2;
                angle = (3 * G_PI) / 2;
            }
            else
            {
                arrow_x = x + width - menu_item->priv->toggle_size + (menu_item->priv->toggle_size - ARROW_SIZE)/2;
                angle = G_PI / 2;
            }
            x += menu_item->priv->toggle_size + BORDER_SPACING;
        }
        else
        {
            if (direction == GTK_TEXT_DIR_LTR)
            {
                arrow_x = ARROW_SIZE / 2;
                angle = (3 * G_PI) / 2;
            }
            else
            {
                arrow_x = x + width - 2 * ARROW_SIZE + ARROW_SIZE / 2;
                angle = G_PI / 2;
            }
            x += 2 * ARROW_SIZE;
        }

        gtk_render_arrow (context, cr, angle,
                          arrow_x, height / 2 - 5,
                          ARROW_SIZE);
    }

    while (x < right_max)
    {
        gint x1, x2;

        if (direction == GTK_TEXT_DIR_LTR)
        {
            x1 = x;
            x2 = MIN (x + TEAR_LENGTH, right_max);
        }
        else
        {
            x1 = right_max - x;
            x2 = MAX (right_max - x - TEAR_LENGTH, 0);
        }

        gtk_render_line (context, cr,
                         x1, y + (height - padding.bottom) / 2,
                         x2, y + (height - padding.bottom) / 2);
        x += 2 * TEAR_LENGTH;
    }

    gtk_style_context_restore (context);

    return FALSE;
}