Beispiel #1
0
/*!
 * \brief Rotate path towards clicked point
 *
 * Rotate the given path around it's center with the angle given by
 * the top center handle and the clicked point. This function is
 * available with the context menu of the 'Standard - Path' object.
 * @return Undo information
 *
 * \relates _StdPath
 */
static ObjectChange *
_path_rotate_callback (DiaObject *obj, Point *clicked, gpointer data)
{
  StdPath *sp = (StdPath *)obj;
  real cx = (sp->object.bounding_box.left + sp->object.bounding_box.right) / 2;
  real cy = (sp->object.bounding_box.top + sp->object.bounding_box.bottom) / 2;
  DiaMatrix m = {1, 0, 0, 1, 0, 0 };
  DiaMatrix translate = {1, 0, 0, 1, 0, 0 };
  Point d;

  d.x = clicked->x - cx;
  d.y = clicked->y - cy;
  point_normalize (&d);
  /* to make the top, center handle clicked no rotation we subtract -PI/2 */
  dia_matrix_set_angle_and_scales (&m, atan2 (d.y, d.x) + M_PI/2.0, 1.0, 1.0);

  /* rotate around center */
  translate.x0 = cx;
  translate.y0 = cy;
  dia_matrix_multiply (&m, &m, &translate);
  translate.x0 = -cx;
  translate.y0 = -cy;
  dia_matrix_multiply (&m, &translate, &m);

  _path_transform (sp, &m);
  return _path_object_transform_change_create (obj, &m);
}
Beispiel #2
0
static void
_textobj_get_poly (const Textobj *textobj, Point poly[4])
{
  Point ul, lr;
  Point pt = textobj->text_handle.pos;
  Rectangle box;
  DiaMatrix m = { 1, 0, 0, 1, pt.x, pt.y };
  DiaMatrix t = { 1, 0, 0, 1, -pt.x, -pt.y };
  int i;

  dia_matrix_set_angle_and_scales (&m, G_PI * textobj->text_angle / 180.0, 1.0, 1.0);
  dia_matrix_multiply (&m, &t, &m);

  text_calc_boundingbox (textobj->text, &box);
  ul.x = box.left - textobj->margin;
  ul.y = box.top - textobj->margin;
  lr.x = box.right + textobj->margin;
  lr.y = box.bottom + textobj->margin;

  poly[0].x = ul.x;
  poly[0].y = ul.y;
  poly[1].x = lr.x;
  poly[1].y = ul.y;
  poly[2].x = lr.x;
  poly[2].y = lr.y;
  poly[3].x = ul.x;
  poly[3].y = lr.y;

  for (i = 0; i < 4; ++i)
    transform_point (&poly[i], &m);
}
Beispiel #3
0
/*!
 * \brief Flip the path over the vertical or horizontal axis
 *
 * Flip horizontal/vertical like custom objects do, except that this
 * function is modifying the underlying point data. This function is
 * available with the context menu of the 'Standard - Path' object.
 * @return Undo information
 *
 * \relates _StdPath
 */
static ObjectChange *
_path_flip_callback (DiaObject *obj, Point *clicked, gpointer data)
{
  gboolean horz = data == NULL;
  StdPath *sp = (StdPath *)obj;
  DiaMatrix m = {horz ? -1 : 1, 0, 0, horz ? 1 : -1, 0, 0 };
  DiaMatrix translate = {1, 0, 0, 1, 0, 0 };
  real cx = (sp->object.bounding_box.left + sp->object.bounding_box.right) / 2;
  real cy = (sp->object.bounding_box.top + sp->object.bounding_box.bottom) / 2;

  /* flip around center */
  translate.x0 = cx;
  translate.y0 = cy;
  dia_matrix_multiply (&m, &m, &translate);
  translate.x0 = -cx;
  translate.y0 = -cy;
  dia_matrix_multiply (&m, &translate, &m);

  _path_transform (sp, &m);
  return _path_object_transform_change_create (obj, &m);
}
Beispiel #4
0
  void updateCTM(GfxState *state,
		 double m11, double m12,
		 double m21, double m22,
		 double m31, double m32)
  {
    DiaMatrix mat;

    mat.xx = m11;
    mat.yx = m12;
    mat.xy = m21;
    mat.yy = m22;
    mat.x0 = m31 * scale;
    mat.y0 = m32 * scale;

    //this->matrix = mat;
    dia_matrix_multiply (&this->matrix, &mat, &this->matrix);

    updateLineDash(state);
    updateLineJoin(state);
    updateLineCap(state);
    updateLineWidth(state);
  }
/* 
 * renderer methods 
 */ 
static void 
draw_object(DiaRenderer *self,
            DiaObject   *object,
	    DiaMatrix   *matrix)
{
  DrsRenderer *renderer = DRS_RENDERER (self);
  DiaMatrix *m = g_queue_peek_tail (renderer->matrices);
  xmlNodePtr node;

  g_queue_push_tail (renderer->parents, renderer->root);
  renderer->root = node = xmlNewChild(renderer->root, NULL, (const xmlChar *)"object", NULL);
  xmlSetProp(node, (const xmlChar *)"type", (xmlChar *)object->type->name);
  /* if it looks like intdata store it as well */
  if ((int)object->type->default_user_data > 0 && (int)object->type->default_user_data < 0xFF) {
    gchar buffer[30];
    g_snprintf(buffer, sizeof(buffer), "%d", (int)object->type->default_user_data);
    xmlSetProp(node, (const xmlChar *)"intdata", (xmlChar *)buffer);
  }
  if (renderer->save_props) {
    xmlNodePtr props_node;

    props_node = xmlNewChild(node, NULL, (const xmlChar *)"properties", NULL);
    object_save_props (object, props_node, renderer->ctx);
  }
  if (matrix) {
    DiaMatrix *m2 = g_new (DiaMatrix, 1);
    if (m)
      dia_matrix_multiply (m2, matrix, m);
    else
      *m2 = *matrix;
    g_queue_push_tail (renderer->matrices, m2);
    /* lazy creation of our transformer */
    if (!renderer->transformer)
      renderer->transformer = dia_transform_renderer_new (self);
  }
  /* special handling for group objects:
   *  - for the render branch use DiaTransformRenderer, but not it's draw_object,
   *    to see all the children's draw_object ourself
   *  - for the object branch we rely on this draw_object being called so need
   *    to inline group_draw here
   *  - to maintain the correct transform build our own queue of matrices like
   *    the DiaTransformRenderer would do through it's draw_object
   */
  {
    g_queue_push_tail (renderer->parents, renderer->root);
    renderer->root = node = xmlNewChild(renderer->root, NULL, (const xmlChar *)"render", NULL);
    if (renderer->transformer) {
      DiaMatrix *m = g_queue_peek_tail (renderer->matrices);

      if (IS_GROUP (object)) {
	/* reimplementation of group_draw to use this draw_object method */
	GList *list;
	DiaObject *obj;

	list = group_objects (object);
	while (list != NULL) {
	  obj = (DiaObject *) list->data;

	  DIA_RENDERER_GET_CLASS(self)->draw_object(self, obj, m);
	  list = g_list_next(list);
	}
      } else {
	/* just the leaf */
	DIA_RENDERER_GET_CLASS(renderer->transformer)->draw_object(renderer->transformer, object, m);
      }
    } else {
      object->ops->draw(object, DIA_RENDERER (renderer));
    }
    renderer->root = g_queue_pop_tail (renderer->parents);
  }
  renderer->root = g_queue_pop_tail (renderer->parents);

  if (matrix)
    g_queue_pop_tail (renderer->matrices);
  /* one lost demand destruction */
  if (renderer->transformer && g_queue_is_empty (renderer->matrices)) {
    g_object_unref (renderer->transformer);
    renderer->transformer = NULL;
  }
}