void start_selectregion(GdkEvent *event) { double pt[2]; reset_selection(); ui.cur_item_type = ITEM_SELECTREGION; ui.selection = g_new(struct Selection, 1); ui.selection->type = ITEM_SELECTREGION; ui.selection->items = NULL; ui.selection->layer = ui.cur_layer; get_pointer_coords(event, pt); ui.selection->bbox.left = ui.selection->bbox.right = pt[0]; ui.selection->bbox.top = ui.selection->bbox.bottom = pt[1]; realloc_cur_path(1); ui.cur_path.num_points = 1; ui.cur_path.coords[0] = ui.cur_path.coords[2] = pt[0]; ui.cur_path.coords[1] = ui.cur_path.coords[3] = pt[1]; ui.selection->canvas_item = gnome_canvas_item_new(ui.cur_layer->group, gnome_canvas_polygon_get_type(), "width-pixels", 1, "outline-color-rgba", 0x000000ff, "fill-color-rgba", 0x80808040, NULL); make_dashed(ui.selection->canvas_item); update_cursor(); }
void selection_delete(void) { struct UndoErasureData *erasure; GList *itemlist; struct Item *item; if (ui.selection == NULL) return; prepare_new_undo(); undo->type = ITEM_ERASURE; undo->layer = ui.selection->layer; undo->erasurelist = NULL; for (itemlist = ui.selection->items; itemlist!=NULL; itemlist = itemlist->next) { item = (struct Item *)itemlist->data; if (item->canvas_item!=NULL) gtk_object_destroy(GTK_OBJECT(item->canvas_item)); erasure = g_new(struct UndoErasureData, 1); erasure->item = item; erasure->npos = g_list_index(ui.selection->layer->items, item); erasure->nrepl = 0; erasure->replacement_items = NULL; ui.selection->layer->items = g_list_remove(ui.selection->layer->items, item); ui.selection->layer->nitems--; undo->erasurelist = g_list_prepend(undo->erasurelist, erasure); } reset_selection(); /* NOTE: the erasurelist is built backwards; this guarantees that, upon undo, the erasure->npos fields give the correct position where each item should be reinserted as the list is traversed in the forward direction */ }
// paste external text void clipboard_paste_text(gchar *text) { struct Item *item; double pt[2]; reset_selection(); get_current_pointer_coords(pt); set_current_page(pt); ui.selection = g_new(struct Selection, 1); ui.selection->type = ITEM_SELECTRECT; ui.selection->layer = ui.cur_layer; ui.selection->items = NULL; item = g_new(struct Item, 1); ui.selection->items = g_list_append(ui.selection->items, item); ui.cur_layer->items = g_list_append(ui.cur_layer->items, item); ui.cur_layer->nitems++; item->type = ITEM_TEXT; g_memmove(&(item->brush), &(ui.brushes[ui.cur_mapping][TOOL_PEN]), sizeof(struct Brush)); item->text = text; // text was newly allocated, we keep it item->font_name = g_strdup(ui.font_name); item->font_size = ui.font_size; item->bbox.left = pt[0]; item->bbox.top = pt[1]; make_canvas_item_one(ui.cur_layer->group, item); update_item_bbox(item); // move the text to fit on the page if needed if (item->bbox.right > ui.cur_page->width) item->bbox.left += ui.cur_page->width-item->bbox.right; if (item->bbox.left < 0) item->bbox.left = 0; if (item->bbox.bottom > ui.cur_page->height) item->bbox.top += ui.cur_page->height-item->bbox.bottom; if (item->bbox.top < 0) item->bbox.top = 0; gnome_canvas_item_set(item->canvas_item, "x", item->bbox.left, "y", item->bbox.top, NULL); update_item_bbox(item); ui.selection->bbox = item->bbox; ui.selection->canvas_item = gnome_canvas_item_new(ui.cur_layer->group, gnome_canvas_rect_get_type(), "width-pixels", 1, "outline-color-rgba", 0x000000ff, "fill-color-rgba", 0x80808040, "x1", ui.selection->bbox.left, "x2", ui.selection->bbox.right, "y1", ui.selection->bbox.top, "y2", ui.selection->bbox.bottom, NULL); make_dashed(ui.selection->canvas_item); prepare_new_undo(); undo->type = ITEM_PASTE; undo->layer = ui.cur_layer; undo->itemlist = g_list_copy(ui.selection->items); update_copy_paste_enabled(); update_color_menu(); update_thickness_buttons(); update_color_buttons(); update_font_button(); update_cursor(); // FIXME: can't know if pointer is within selection! }
// paste an external image void clipboard_paste_image(GdkPixbuf *pixbuf) { double pt[2]; reset_selection(); get_current_pointer_coords(pt); set_current_page(pt); create_image_from_pixbuf(pixbuf, pt); }
void LxDcViCtl::modify_section_color(CDC* pDC, size_t section_begin_index, size_t section_begin_pgh, size_t section_end_index, size_t section_end_pgh, COLORREF src_color) { size_t index_b = section_begin_index < section_end_index ? section_begin_index : section_end_index; size_t index_e = section_end_index > section_begin_index ? section_end_index : section_begin_index; color_tree.modify(index_b, index_e, src_color); if (!section.active()) { reset_selection(pDC, section_begin_index, section_begin_pgh, section_end_index, section_end_pgh); } }
void create_image_from_pixbuf(GdkPixbuf *pixbuf, double *pt) { double scale; struct Item *item; item = g_new(struct Item, 1); item->type = ITEM_IMAGE; item->canvas_item = NULL; item->bbox.left = pt[0]; item->bbox.top = pt[1]; item->image = pixbuf; item->image_png = NULL; item->image_png_len = 0; // Scale at native size, unless that won't fit, in which case we shrink it down. scale = 1 / ui.zoom; if ((scale * gdk_pixbuf_get_width(item->image)) > ui.cur_page->width - item->bbox.left) scale = (ui.cur_page->width - item->bbox.left) / gdk_pixbuf_get_width(item->image); if ((scale * gdk_pixbuf_get_height(item->image)) > ui.cur_page->height - item->bbox.top) scale = (ui.cur_page->height - item->bbox.top) / gdk_pixbuf_get_height(item->image); item->bbox.right = item->bbox.left + scale * gdk_pixbuf_get_width(item->image); item->bbox.bottom = item->bbox.top + scale * gdk_pixbuf_get_height(item->image); ui.cur_layer->items = g_list_append(ui.cur_layer->items, item); ui.cur_layer->nitems++; make_canvas_item_one(ui.cur_layer->group, item); // add undo information prepare_new_undo(); undo->type = ITEM_IMAGE; undo->item = item; undo->layer = ui.cur_layer; ui.cur_item = NULL; ui.cur_item_type = ITEM_NONE; // select image reset_selection(); ui.selection = g_new0(struct Selection, 1); ui.selection->type = ITEM_SELECTRECT; ui.selection->layer = ui.cur_layer; ui.selection->bbox = item->bbox; ui.selection->items = g_list_append(ui.selection->items, item); ui.selection->canvas_item = gnome_canvas_item_new(ui.cur_layer->group, gnome_canvas_rect_get_type(), "width-pixels", 1, "outline-color-rgba", 0x000000ff, "fill-color-rgba", 0x80808040, "x1", ui.selection->bbox.left, "x2", ui.selection->bbox.right, "y1", ui.selection->bbox.top, "y2", ui.selection->bbox.bottom, NULL); make_dashed(ui.selection->canvas_item); update_copy_paste_enabled(); }
void LxDcViCtl::modify_section_font(CDC* pDC, size_t section_begin_index, size_t section_begin_pgh, size_t section_end_index, size_t section_end_pgh, size_t src_font) { size_t index_b = section_begin_index < section_end_index ? section_begin_index : section_end_index; size_t index_e = section_end_index > section_begin_index ? section_end_index : section_begin_index; font_tree.modify(index_b, index_e, src_font); gd_proxy.set_font_index(src_font); size_t pgh_b = section_begin_pgh < section_end_pgh ? section_begin_pgh : section_end_pgh; size_t pgh_e = section_begin_pgh < section_end_pgh ? section_end_pgh : section_begin_pgh; compose_doc.relayout_section(pDC, index_b, pgh_b, index_e, pgh_e); //重新计算cursor reset_selection(pDC, section_begin_index, section_begin_pgh, section_end_index, section_end_pgh); }
void finalize_selectrect(void) { double x1, x2, y1, y2; GList *itemlist; struct Item *item; ui.cur_item_type = ITEM_NONE; if (ui.selection->bbox.left > ui.selection->bbox.right) { x1 = ui.selection->bbox.right; x2 = ui.selection->bbox.left; ui.selection->bbox.left = x1; ui.selection->bbox.right = x2; } else { x1 = ui.selection->bbox.left; x2 = ui.selection->bbox.right; } if (ui.selection->bbox.top > ui.selection->bbox.bottom) { y1 = ui.selection->bbox.bottom; y2 = ui.selection->bbox.top; ui.selection->bbox.top = y1; ui.selection->bbox.bottom = y2; } else { y1 = ui.selection->bbox.top; y2 = ui.selection->bbox.bottom; } for (itemlist = ui.selection->layer->items; itemlist!=NULL; itemlist = itemlist->next) { item = (struct Item *)itemlist->data; if (item->bbox.left >= x1 && item->bbox.right <= x2 && item->bbox.top >= y1 && item->bbox.bottom <= y2) { ui.selection->items = g_list_append(ui.selection->items, item); } } if (ui.selection->items == NULL) { // if we clicked inside a text zone or image? item = click_is_in_text_or_image(ui.selection->layer, x1, y1); if (item!=NULL && item==click_is_in_text_or_image(ui.selection->layer, x2, y2)) { ui.selection->items = g_list_append(ui.selection->items, item); g_memmove(&(ui.selection->bbox), &(item->bbox), sizeof(struct BBox)); gnome_canvas_item_set(ui.selection->canvas_item, "x1", item->bbox.left, "x2", item->bbox.right, "y1", item->bbox.top, "y2", item->bbox.bottom, NULL); } } if (ui.selection->items == NULL) reset_selection(); else make_dashed(ui.selection->canvas_item); update_cursor(); update_copy_paste_enabled(); update_font_button(); }
void finalize_movesel(void) { GList *list, *link; if (ui.selection->items != NULL) { prepare_new_undo(); undo->type = ITEM_MOVESEL; undo->itemlist = g_list_copy(ui.selection->items); undo->val_x = ui.selection->last_x - ui.selection->anchor_x; undo->val_y = ui.selection->last_y - ui.selection->anchor_y; undo->layer = ui.selection->layer; undo->layer2 = ui.selection->move_layer; undo->auxlist = NULL; // build auxlist = pointers to Item's just before ours (for depths) for (list = ui.selection->items; list!=NULL; list = list->next) { link = g_list_find(ui.selection->layer->items, list->data); if (link!=NULL) link = link->prev; undo->auxlist = g_list_append(undo->auxlist, ((link!=NULL) ? link->data : NULL)); } ui.selection->layer = ui.selection->move_layer; move_journal_items_by(undo->itemlist, undo->val_x, undo->val_y, undo->layer, undo->layer2, (undo->layer == undo->layer2)?undo->auxlist:NULL); } if (ui.selection->move_pageno!=ui.selection->orig_pageno) do_switch_page(ui.selection->move_pageno, FALSE, FALSE); if (ui.cur_item_type == ITEM_MOVESEL_VERT) reset_selection(); else { ui.selection->bbox.left += undo->val_x; ui.selection->bbox.right += undo->val_x; ui.selection->bbox.top += undo->val_y; ui.selection->bbox.bottom += undo->val_y; make_dashed(ui.selection->canvas_item); /* update selection box object's offset to be trivial, and its internal coordinates to agree with those of the bbox; need this since resize operations will modify the box by setting its coordinates directly */ gnome_canvas_item_affine_absolute(ui.selection->canvas_item, NULL); gnome_canvas_item_set(ui.selection->canvas_item, "x1", ui.selection->bbox.left, "x2", ui.selection->bbox.right, "y1", ui.selection->bbox.top, "y2", ui.selection->bbox.bottom, NULL); } ui.cur_item_type = ITEM_NONE; update_cursor(); }
void LxDcViCtl::modify_section_font(CDC* pDC, size_t section_begin_index, size_t section_begin_pgh, size_t section_end_index, size_t section_end_pgh, StructuredSrcContext* font_context) { size_t index_b = section_begin_index < section_end_index ? section_begin_index : section_end_index; size_t index_e = section_end_index > section_begin_index ? section_end_index : section_begin_index; int _index_gbl = index_b; for (auto it_src : font_context->srcinfo_list) { font_tree.modify(_index_gbl, _index_gbl + it_src.first, it_src.second); _index_gbl += it_src.first; } size_t pgh_b = section_begin_pgh < section_end_pgh ? section_begin_pgh : section_end_pgh; size_t pgh_e = section_begin_pgh < section_end_pgh ? section_end_pgh : section_begin_pgh; compose_doc.relayout_section(pDC, index_b, pgh_b, index_e, pgh_e); //重新计算cursor reset_selection(pDC, section_begin_index, section_begin_pgh, section_end_index, section_end_pgh); }
void start_selectrect(GdkEvent *event) { double pt[2]; reset_selection(); ui.cur_item_type = ITEM_SELECTRECT; ui.selection = g_new(struct Selection, 1); ui.selection->type = ITEM_SELECTRECT; ui.selection->items = NULL; ui.selection->layer = ui.cur_layer; get_pointer_coords(event, pt); ui.selection->bbox.left = ui.selection->bbox.right = pt[0]; ui.selection->bbox.top = ui.selection->bbox.bottom = pt[1]; ui.selection->canvas_item = gnome_canvas_item_new(ui.cur_layer->group, gnome_canvas_rect_get_type(), "width-pixels", 1, "outline-color-rgba", 0x000000ff, "fill-color-rgba", 0x80808040, "x1", pt[0], "x2", pt[0], "y1", pt[1], "y2", pt[1], NULL); update_cursor(); }
void start_vertspace(GdkEvent *event) { double pt[2]; GList *itemlist; struct Item *item; reset_selection(); ui.cur_item_type = ITEM_MOVESEL_VERT; ui.selection = g_new(struct Selection, 1); ui.selection->type = ITEM_MOVESEL_VERT; ui.selection->items = NULL; ui.selection->layer = ui.cur_layer; get_pointer_coords(event, pt); ui.selection->bbox.top = ui.selection->bbox.bottom = pt[1]; for (itemlist = ui.cur_layer->items; itemlist!=NULL; itemlist = itemlist->next) { item = (struct Item *)itemlist->data; if (item->bbox.top >= pt[1]) { ui.selection->items = g_list_append(ui.selection->items, item); if (item->bbox.bottom > ui.selection->bbox.bottom) ui.selection->bbox.bottom = item->bbox.bottom; } } ui.selection->anchor_x = ui.selection->last_x = 0; ui.selection->anchor_y = ui.selection->last_y = pt[1]; ui.selection->orig_pageno = ui.pageno; ui.selection->move_pageno = ui.pageno; ui.selection->move_layer = ui.selection->layer; ui.selection->move_pagedelta = 0.; ui.selection->canvas_item = gnome_canvas_item_new(ui.cur_layer->group, gnome_canvas_rect_get_type(), "width-pixels", 1, "outline-color-rgba", 0x000000ff, "fill-color-rgba", 0x80808040, "x1", -100.0, "x2", ui.cur_page->width+100, "y1", pt[1], "y2", pt[1], NULL); update_cursor(); }
// paste xournal native data void clipboard_paste_from_xournal(GtkSelectionData *sel_data) { unsigned char *p; int nitems, npts, i, len; struct Item *item; double hoffset, voffset, cx, cy; double *pf; int sx, sy, wx, wy; reset_selection(); ui.selection = g_new(struct Selection, 1); p = sel_data->data + sizeof(int); g_memmove(&nitems, p, sizeof(int)); p+= sizeof(int); ui.selection->type = ITEM_SELECTRECT; ui.selection->layer = ui.cur_layer; g_memmove(&ui.selection->bbox, p, sizeof(struct BBox)); p+= sizeof(struct BBox); ui.selection->items = NULL; // find by how much we translate the pasted selection gnome_canvas_get_scroll_offsets(canvas, &sx, &sy); gdk_window_get_geometry(GTK_WIDGET(canvas)->window, NULL, NULL, &wx, &wy, NULL); gnome_canvas_window_to_world(canvas, sx + wx/2, sy + wy/2, &cx, &cy); cx -= ui.cur_page->hoffset; cy -= ui.cur_page->voffset; if (cx + (ui.selection->bbox.right-ui.selection->bbox.left)/2 > ui.cur_page->width) cx = ui.cur_page->width - (ui.selection->bbox.right-ui.selection->bbox.left)/2; if (cx - (ui.selection->bbox.right-ui.selection->bbox.left)/2 < 0) cx = (ui.selection->bbox.right-ui.selection->bbox.left)/2; if (cy + (ui.selection->bbox.bottom-ui.selection->bbox.top)/2 > ui.cur_page->height) cy = ui.cur_page->height - (ui.selection->bbox.bottom-ui.selection->bbox.top)/2; if (cy - (ui.selection->bbox.bottom-ui.selection->bbox.top)/2 < 0) cy = (ui.selection->bbox.bottom-ui.selection->bbox.top)/2; hoffset = cx - (ui.selection->bbox.right+ui.selection->bbox.left)/2; voffset = cy - (ui.selection->bbox.top+ui.selection->bbox.bottom)/2; ui.selection->bbox.left += hoffset; ui.selection->bbox.right += hoffset; ui.selection->bbox.top += voffset; ui.selection->bbox.bottom += voffset; ui.selection->canvas_item = gnome_canvas_item_new(ui.cur_layer->group, gnome_canvas_rect_get_type(), "width-pixels", 1, "outline-color-rgba", 0x000000ff, "fill-color-rgba", 0x80808040, "x1", ui.selection->bbox.left, "x2", ui.selection->bbox.right, "y1", ui.selection->bbox.top, "y2", ui.selection->bbox.bottom, NULL); make_dashed(ui.selection->canvas_item); while (nitems-- > 0) { item = g_new(struct Item, 1); ui.selection->items = g_list_append(ui.selection->items, item); ui.cur_layer->items = g_list_append(ui.cur_layer->items, item); ui.cur_layer->nitems++; g_memmove(&item->type, p, sizeof(int)); p+= sizeof(int); if (item->type == ITEM_STROKE) { g_memmove(&item->brush, p, sizeof(struct Brush)); p+= sizeof(struct Brush); g_memmove(&npts, p, sizeof(int)); p+= sizeof(int); item->path = gnome_canvas_points_new(npts); pf = (double *)p; for (i=0; i<npts; i++) { item->path->coords[2*i] = pf[2*i] + hoffset; item->path->coords[2*i+1] = pf[2*i+1] + voffset; } p+= 2*item->path->num_points*sizeof(double); if (item->brush.variable_width) { item->widths = g_memdup(p, (item->path->num_points-1)*sizeof(double)); p+= (item->path->num_points-1)*sizeof(double); } else item->widths = NULL; update_item_bbox(item); make_canvas_item_one(ui.cur_layer->group, item); } if (item->type == ITEM_TEXT) { g_memmove(&item->brush, p, sizeof(struct Brush)); p+= sizeof(struct Brush); g_memmove(&item->bbox.left, p, sizeof(double)); p+= sizeof(double); g_memmove(&item->bbox.top, p, sizeof(double)); p+= sizeof(double); item->bbox.left += hoffset; item->bbox.top += voffset; g_memmove(&len, p, sizeof(int)); p+= sizeof(int); item->text = g_malloc(len+1); g_memmove(item->text, p, len+1); p+= len+1; g_memmove(&len, p, sizeof(int)); p+= sizeof(int); item->font_name = g_malloc(len+1); g_memmove(item->font_name, p, len+1); p+= len+1; g_memmove(&item->font_size, p, sizeof(double)); p+= sizeof(double); make_canvas_item_one(ui.cur_layer->group, item); } if (item->type == ITEM_IMAGE) { item->canvas_item = NULL; item->image_png = NULL; item->image_png_len = 0; g_memmove(&item->bbox, p, sizeof(struct BBox)); p+= sizeof(struct BBox); item->bbox.left += hoffset; item->bbox.right += hoffset; item->bbox.top += voffset; item->bbox.bottom += voffset; g_memmove(&item->image_png_len, p, sizeof(gsize)); p+= sizeof(gsize); if (item->image_png_len > 0) { item->image_png = g_memdup(p, item->image_png_len); item->image = pixbuf_from_buffer(item->image_png, item->image_png_len); p+= item->image_png_len; } else { item->image = NULL; } make_canvas_item_one(ui.cur_layer->group, item); } } prepare_new_undo(); undo->type = ITEM_PASTE; undo->layer = ui.cur_layer; undo->itemlist = g_list_copy(ui.selection->items); gtk_selection_data_free(sel_data); update_copy_paste_enabled(); update_color_menu(); update_thickness_buttons(); update_color_buttons(); update_font_button(); update_cursor(); // FIXME: can't know if pointer is within selection! }
void finalize_selectregion(void) { GList *itemlist; struct Item *item; ArtVpath *vpath; ArtSVP *lassosvp; int i, n; double *pt; ui.cur_item_type = ITEM_NONE; // build SVP for the lasso path n = ui.cur_path.num_points; vpath = g_malloc((n+2)*sizeof(ArtVpath)); for (i=0; i<n; i++) { vpath[i].x = ui.cur_path.coords[2*i]; vpath[i].y = ui.cur_path.coords[2*i+1]; } vpath[n].x = vpath[0].x; vpath[n].y = vpath[0].y; vpath[0].code = ART_MOVETO; for (i=1; i<=n; i++) vpath[i].code = ART_LINETO; vpath[n+1].code = ART_END; lassosvp = art_svp_from_vpath(vpath); g_free(vpath); // see which items we selected for (itemlist = ui.selection->layer->items; itemlist!=NULL; itemlist = itemlist->next) { item = (struct Item *)itemlist->data; if (hittest_item(lassosvp, item)) { // update the selection bbox if (ui.selection->items==NULL || ui.selection->bbox.left>item->bbox.left) ui.selection->bbox.left = item->bbox.left; if (ui.selection->items==NULL || ui.selection->bbox.right<item->bbox.right) ui.selection->bbox.right = item->bbox.right; if (ui.selection->items==NULL || ui.selection->bbox.top>item->bbox.top) ui.selection->bbox.top = item->bbox.top; if (ui.selection->items==NULL || ui.selection->bbox.bottom<item->bbox.bottom) ui.selection->bbox.bottom = item->bbox.bottom; // add the item ui.selection->items = g_list_append(ui.selection->items, item); } } art_svp_free(lassosvp); if (ui.selection->items == NULL) { // if we clicked inside a text zone or image? pt = ui.cur_path.coords; item = click_is_in_text_or_image(ui.selection->layer, pt[0], pt[1]); if (item!=NULL) { for (i=0; i<n; i++, pt+=2) { if (pt[0]<item->bbox.left || pt[0]>item->bbox.right || pt[1]<item->bbox.top || pt[1]>item->bbox.bottom) { item = NULL; break; } } } if (item!=NULL) { ui.selection->items = g_list_append(ui.selection->items, item); g_memmove(&(ui.selection->bbox), &(item->bbox), sizeof(struct BBox)); } } if (ui.selection->items == NULL) reset_selection(); else { // make a selection rectangle instead of the lasso shape gtk_object_destroy(GTK_OBJECT(ui.selection->canvas_item)); ui.selection->canvas_item = gnome_canvas_item_new(ui.cur_layer->group, gnome_canvas_rect_get_type(), "width-pixels", 1, "outline-color-rgba", 0x000000ff, "fill-color-rgba", 0x80808040, "x1", ui.selection->bbox.left, "x2", ui.selection->bbox.right, "y1", ui.selection->bbox.top, "y2", ui.selection->bbox.bottom, NULL); make_dashed(ui.selection->canvas_item); ui.selection->type = ITEM_SELECTRECT; } update_cursor(); update_copy_paste_enabled(); update_font_button(); }