func (t *PDFStreamTextObject) WriteAt(text string, props TypesettingProps, x float64, y float64) error { var layout *C.PangoLayout var font_description *C.PangoFontDescription font_description = C.pango_font_description_new() cfontname := C.CString(props.Fontname) defer C.free(unsafe.Pointer(cfontname)) C.pango_font_description_set_family(font_description, cfontname) C.pango_font_description_set_weight(font_description, C.PANGO_WEIGHT_NORMAL) C.pango_font_description_set_absolute_size(font_description, C.double(props.Fontsize)*C.PANGO_SCALE) layout = C.pango_cairo_create_layout(t.context) C.pango_layout_set_font_description(layout, font_description) width := props.PageWidth - props.LeftMargin - props.RightMargin fmt.Printf("width is %f\n", width) C.pango_layout_set_width(layout, C.int(width*C.PANGO_SCALE)) C.pango_layout_set_justify(layout, C.TRUE) ctext := C.CString(text) defer C.free(unsafe.Pointer(ctext)) C.pango_layout_set_text(layout, ctext, -1) C.cairo_set_source_rgb(t.context, 0.0, 0.0, 0.0) C.cairo_move_to(t.context, C.double(x), C.double(y)) skip := props.Baselineskip nlines := int(C.pango_layout_get_line_count(layout)) for i := 0; i < nlines; i++ { C.cairo_move_to(t.context, C.double(x), C.double(y+float64(i)*skip)) C.pango_cairo_show_layout_line(t.context, C.pango_layout_get_line(layout, C.int(i))) } C.g_object_unref(C.gpointer(layout)) C.pango_font_description_free(font_description) return nil }
func draw_selections(viewp, bufferp, crp unsafe.Pointer, mark_pairs []unsafe.Pointer) { view := (*C.GtkTextView)(viewp) buffer := (*C.GtkTextBuffer)(bufferp) cr := (*C.cairo_t)(crp) var alloc C.GtkAllocation C.gtk_widget_get_allocation((*C.GtkWidget)(viewp), &alloc) n := len(mark_pairs) var start_mark, stop_mark *C.GtkTextMark var location C.GdkRectangle var iter C.GtkTextIter var x, y C.gint var dx, dy C.double for i := 0; i < n; i += 2 { start_mark = (*C.GtkTextMark)(mark_pairs[i]) C.gtk_text_buffer_get_iter_at_mark(buffer, &iter, start_mark) C.gtk_text_view_get_iter_location(view, &iter, &location) C.gtk_text_view_buffer_to_window_coords(view, C.GTK_TEXT_WINDOW_WIDGET, C.gint(location.x), C.gint(location.y), &x, &y) if C.int(x) > alloc.width || C.int(y) > alloc.height || x < 0 || y < 0 { continue } dx = C.double(x) dy = C.double(y) C.cairo_set_source_rgb(cr, 1, 0, 0) C.cairo_move_to(cr, dx, dy) C.cairo_set_line_width(cr, 2) C.cairo_line_to(cr, dx+6, dy) C.cairo_stroke(cr) C.cairo_move_to(cr, dx, dy) C.cairo_set_line_width(cr, 1) C.cairo_line_to(cr, dx, dy+C.double(location.height)) C.cairo_stroke(cr) stop_mark = (*C.GtkTextMark)(mark_pairs[i+1]) C.gtk_text_buffer_get_iter_at_mark(buffer, &iter, stop_mark) C.gtk_text_view_get_iter_location(view, &iter, &location) C.gtk_text_view_buffer_to_window_coords(view, C.GTK_TEXT_WINDOW_WIDGET, C.gint(location.x), C.gint(location.y), &x, &y) if C.int(x) > alloc.width || C.int(y) > alloc.height || x < 0 || y < 0 { continue } dx = C.double(x) dy = C.double(y) C.cairo_set_source_rgb(cr, 0, 1, 0) C.cairo_move_to(cr, dx, dy) C.cairo_set_line_width(cr, 1) C.cairo_line_to(cr, dx, dy+C.double(location.height)) C.cairo_stroke(cr) C.cairo_move_to(cr, dx, dy+C.double(location.height)) C.cairo_set_line_width(cr, 2) C.cairo_line_to(cr, dx-6, dy+C.double(location.height)) C.cairo_stroke(cr) } }
// Draw given poligon path, automatically closing first and last point func (i *Image) DrawPoly(points ...float64) { C.cairo_move_to(i.Ctx, C.double(points[0]), C.double(points[1])) for j := 2; j < len(points); j += 2 { C.cairo_line_to(i.Ctx, C.double(points[j]), C.double(points[j+1])) } C.cairo_close_path(i.Ctx) }
func RedrawWindow(W *XWindow, tweetsList []*TweetInfo, mouseClick [2]int) { var Attribs C.XWindowAttributes C.XGetWindowAttributes(W.Display, W.Window, &Attribs) // TODO -- Do this only when resizing? C.cairo_xlib_surface_set_size(W.Surface, Attribs.width, Attribs.height) C.cairo_set_source_rgb(W.Cairo, 0.1, 0.1, 0.1) C.cairo_paint(W.Cairo) var Rect C.PangoRectangle yPos := 10.0 + W.Scroll WindowWidth := Attribs.width maxTweetWidth := PixelsToPango(float64(WindowWidth - 5*UIPadding - UserImageSize)) for i := 0; i < len(tweetsList); i++ { t := tweetsList[i] C.pango_layout_set_width(t.Layout, maxTweetWidth) C.pango_layout_get_extents(t.Layout, nil, &Rect) // Get tweet text size _, ry, _, rh := PangoRectToPixels(&Rect) // Position and add padding ry += yPos if rh < UserImageSize+2*UIPadding-UIPadding { rh = UserImageSize + 2*UIPadding } else { rh += UIPadding } // Draw rectangle around tweet C.cairo_set_source_rgb(W.Cairo, 0.2, 0.2, 0.2) C.cairo_rectangle(W.Cairo, UIPadding, C.double(ry), C.double(WindowWidth-2*UIPadding), C.double(rh)) C.cairo_fill(W.Cairo) if mouseClick[0] >= UIPadding && float64(mouseClick[1]) >= ry && float64(mouseClick[1]) <= ry+rh { fmt.Println("Clicked tweet", t.Text) } // Draw user image userImage := GetCachedImage(W.UserImages, t.UserImage) if userImage == nil || C.cairo_surface_status(userImage) != C.CAIRO_STATUS_SUCCESS { userImage = placeholderImage } C.cairo_set_source_surface(W.Cairo, userImage, 2*UIPadding, C.double(yPos+UIPadding)) C.cairo_paint(W.Cairo) // Draw tweet text C.cairo_move_to(W.Cairo, 63, C.double(yPos+SmallPadding)) C.cairo_set_source_rgb(W.Cairo, 0.95, 0.95, 0.95) C.pango_cairo_show_layout(W.Cairo, t.Layout) yPos += 5 + rh } }
func (self *Surface) MoveTo(x, y float64) { C.cairo_move_to(self.context, C.double(x), C.double(y)) }
// MoveTo is a wrapper around cairo_move_to(). func (v *Context) MoveTo(x, y float64) { C.cairo_move_to(v.native(), C.double(x), C.double(y)) }
//MoveTo begins a new sub-path and sets the current point to p. // //Originally cairo_move_to. func (c *Context) MoveTo(p Point) *Context { x, y := p.c() C.cairo_move_to(c.c, x, y) return c }