public Pango.LayoutLine GetLineReadonly(int line) { IntPtr raw_ret = pango_layout_get_line_readonly(Handle, line); Pango.LayoutLine ret = raw_ret == IntPtr.Zero ? null : (Pango.LayoutLine)GLib.Opaque.GetOpaque(raw_ret, typeof(Pango.LayoutLine), false); return(ret); }
public static Cairo.Region LayoutLineGetClipRegion(Pango.LayoutLine line, int x_origin, int y_origin, out int index_ranges, int n_ranges) { IntPtr raw_ret = gdk_pango_layout_line_get_clip_region(line == null ? IntPtr.Zero : line.Handle, x_origin, y_origin, out index_ranges, n_ranges); Cairo.Region ret = new Cairo.Region(raw_ret); return(ret); }
private void OnBeginPrint(object sender, Gtk.BeginPrintArgs args) { Gtk.PrintOperation op = (Gtk.PrintOperation)sender; Gtk.PrintContext context = args.Context; timestamp_footer = CreateTimestampLayout(context); // FIXME: These should be configurable settings later (UI Change) margin_top = CmToPixel(1.5, context.DpiY); margin_left = CmToPixel(1, context.DpiX); margin_right = CmToPixel(1, context.DpiX); margin_bottom = 0; double max_height = Pango.Units.FromPixels((int)context.Height - margin_top - margin_bottom - ComputeFooterHeight(context)); Gtk.TextIter position; Gtk.TextIter end_iter; Buffer.GetBounds(out position, out end_iter); double page_height = 0; bool done = position.Compare(end_iter) >= 0; while (!done) { Gtk.TextIter line_end = position; if (!line_end.EndsLine()) { line_end.ForwardToLineEnd(); } int paragraph_number = position.Line; int indentation; using (Pango.Layout layout = CreateParagraphLayout( context, position, line_end, out indentation)) { Pango.Rectangle ink_rect = Pango.Rectangle.Zero; Pango.Rectangle logical_rect = Pango.Rectangle.Zero; for (int line_in_paragraph = 0; line_in_paragraph < layout.LineCount; line_in_paragraph++) { Pango.LayoutLine line = layout.GetLine(line_in_paragraph); line.GetExtents(ref ink_rect, ref logical_rect); if (page_height + logical_rect.Height >= max_height) { PageBreak page_break = new PageBreak( paragraph_number, line_in_paragraph); page_breaks.Add(page_break); page_height = 0; } page_height += logical_rect.Height; } position.ForwardLine(); done = position.Compare(end_iter) >= 0; } } op.NPages = page_breaks.Count + 1; }
public static Size GetSize(this Pango.LayoutLine line) { var ext = new Pango.Rectangle(); var extl = new Pango.Rectangle(); var scale = Pango.Scale.PangoScale; line.GetExtents(ref ext, ref extl); return(new Size(extl.Width / scale, extl.Height / scale)); }
private void EllipsizeLayout(int width) { // no room to draw anything if (width < 1) { layout.SetMarkup(""); return; } // plenty of room int lw, lh; layout.GetPixelSize(out lw, out lh); if (width > lw) { return; } // not enough room for ... int ell_w, ell_h; Pango.Layout ell = layout.Copy(); ell.SetMarkup("..."); ell.GetPixelSize(out ell_w, out ell_h); if (width < ell_w) { layout.SetMarkup(""); return; } // subtract ellipses width width -= ell_w; int index, trailing; Pango.LayoutLine line = layout.GetLine(0); if (line.XToIndex(width * 1024, out index, out trailing)) { // Console.WriteLine ("length: {0} index: {1} trailing: {2}", layout.Text.Length, index, trailing); // FIXME: breaks on accented chars if (index < layout.Text.Length) { layout.SetMarkup(layout.Text.Substring(0, index) + "..."); } } }
public void DrawLayoutLine(Pango.LayoutLine line, int x, int y) { pango_renderer_draw_layout_line(Handle, line == null ? IntPtr.Zero : line.Handle, x, y); }
public void OnDrawPage(object sender, Gtk.DrawPageArgs args) { using (Cairo.Context cr = args.Context.CairoContext) { cr.MoveTo(margin_left, margin_top); PageBreak start; if (args.PageNr == 0) { start = new PageBreak(0, 0); } else { start = page_breaks [args.PageNr - 1]; } PageBreak end; if (args.PageNr < page_breaks.Count) { end = page_breaks [args.PageNr]; } else { end = new PageBreak(-1, -1); } Gtk.PrintContext context = args.Context; Gtk.TextIter position; Gtk.TextIter end_iter; Buffer.GetBounds(out position, out end_iter); // Fast-forward to the right starting paragraph while (position.Line < start.Paragraph) { position.ForwardLine(); } bool done = position.Compare(end_iter) >= 0; while (!done) { Gtk.TextIter line_end = position; if (!line_end.EndsLine()) { line_end.ForwardToLineEnd(); } int paragraph_number = position.Line; int indentation; using (Pango.Layout layout = CreateParagraphLayout( context, position, line_end, out indentation)) { for (int line_number = 0; line_number < layout.LineCount && !done; line_number++) { // Skip the lines up to the starting line in the // first paragraph on this page if ((paragraph_number == start.Paragraph) && (line_number < start.Line)) { continue; } // Break as soon as we hit the end line if ((paragraph_number == end.Paragraph) && (line_number == end.Line)) { done = true; break; } Pango.LayoutLine line = layout.Lines [line_number]; Pango.Rectangle ink_rect = Pango.Rectangle.Zero; Pango.Rectangle logical_rect = Pango.Rectangle.Zero; line.GetExtents(ref ink_rect, ref logical_rect); cr.MoveTo(margin_left + indentation, cr.CurrentPoint.Y); int line_height = Pango.Units.ToPixels(logical_rect.Height); Cairo.PointD new_line_point = new Cairo.PointD( margin_left + indentation, cr.CurrentPoint.Y + line_height); Pango.CairoHelper.ShowLayoutLine(cr, line); cr.MoveTo(new_line_point); } } position.ForwardLine(); done = done || position.Compare(end_iter) >= 0; } int total_height = (int)args.Context.Height; int total_width = (int)args.Context.Width; int footer_height = 0; Cairo.PointD footer_anchor; using (Pango.Layout pages_footer = CreatePagenumbersLayout( args.Context, args.PageNr + 1, page_breaks.Count + 1)) { Pango.Rectangle ink_footer_rect; Pango.Rectangle logical_footer_rect; pages_footer.GetExtents(out ink_footer_rect, out logical_footer_rect); footer_anchor = new Cairo.PointD( CmToPixel(0.5, args.Context.DpiX), total_height - margin_bottom); footer_height = Pango.Units.ToPixels(logical_footer_rect.Height); cr.MoveTo( total_width - Pango.Units.ToPixels(logical_footer_rect.Width) - CmToPixel(0.5, args.Context.DpiX), footer_anchor.Y); Pango.CairoHelper.ShowLayoutLine(cr, pages_footer.Lines [0]); } cr.MoveTo(footer_anchor); Pango.CairoHelper.ShowLayoutLine(cr, timestamp_footer.Lines [0]); cr.MoveTo(CmToPixel(0.5, args.Context.DpiX), total_height - margin_bottom - footer_height); cr.LineTo(total_width - CmToPixel(0.5, args.Context.DpiX), total_height - margin_bottom - footer_height); cr.Stroke(); } }
protected void prototype(Pango.Layout pl, double x, double y) { var text = pl.Text; foreach (var l in pl.Lines) { Trace.WriteLine(text.Substring(l.StartIndex, Math.Min(l.Length, text.Length - l.StartIndex))); } Trace.WriteLine("----------"); // see also: https://github.com/GNOME/tomboy/blob/master/Tomboy/Addins/PrintNotes/PrintNotesNoteAddin.cs // https://sourcecodebrowser.com/pango1.0/1.14.8/pango-renderer_8c.html#aaceb17b572fe371dc78068a27551ccbc // try with run var iter = pl.Iter; var lastline = default(Pango.LayoutLine); var lli = 0; var ll = 0; var li = 0; //text = text.Replace ("\n", "");//.Replace("\r",""); do { if (iter.Run.Glyphs != null) { ll = iter.Run.Glyphs.NumGlyphs; var newline = iter.Line != null && iter.Line.StartIndex != li; if (newline) { li = iter.Line.StartIndex; } if (newline && iter.Line.IsParagraphStart) { lli++; } var s = text.Substring(lli, Math.Min(ll, text.Length - lli)); Trace.WriteLine(s); lli += ll; } } while (iter.NextRun()); Trace.WriteLine("----------"); lastline = default(Pango.LayoutLine); lli = 0; ll = 0; li = 0; iter = pl.Iter; var iRun = 0; var numGlyph = 0; Pango.LayoutLine line = null; Pango.LayoutRun run;; //text = text.Replace ("\n", "");//.Replace("\r",""); Action render = () => { if (numGlyph == 0) { return; } ll = numGlyph; var newline = line != null && line.StartIndex != li; if (newline) { li = line.StartIndex; } if (iter.Line.StartIndex != line.StartIndex && iter.Line.IsParagraphStart) { ll--; } var s = text.Substring(lli, Math.Min(ll, text.Length - lli)); Trace.WriteLine(s); if (iter.Line.IsParagraphStart) { ll++; } lli += ll; }; do { var newRun = iter.Run.Glyphs != null && iter.Run.Item.Offset != iRun; if (newRun) { iRun = iter.Run.Item.Offset; render(); numGlyph = 0; line = null; } if (line == null) { line = iter.Line; run = iter.Run; } numGlyph++; } while (iter.NextChar()); render(); iter = pl.Iter; var logical_rect = new Pango.Rectangle(); var lineX = 0; Action <string, Func <bool> > traceiter = (s, f) => { lastline = null; Trace.Write(s + "\t"); iter = pl.Iter; do { var newLine = lastline == null || lastline.StartIndex != iter.Line.StartIndex; Trace.Write(string.Format("{1}{0}", iter.Index, (newLine ? "|" : " "))); if (newLine) { lastline = iter.Line; } } while (f()); Trace.WriteLine(""); }; traceiter("line", () => iter.NextLine()); traceiter("run", () => iter.NextRun()); traceiter("cluster", () => iter.NextCluster()); traceiter("char", () => iter.NextChar()); }
// TODO: mix with CairoContextBackendHandler.DrawTextLayout void Analyselayout(Pango.Layout pl, double x, double y) { var text = pl.Text; var iter = pl.Iter; var lli = 0; var ll = 0; var li = 0; var iRun = 0; var numGlyph = 0; Pango.LayoutLine line = null; Pango.LayoutRun run; Action render = () => { if (numGlyph == 0) { return; } ll = numGlyph; var newline = line != null && line.StartIndex != li; if (newline) { li = line.StartIndex; } if (iter.Line.StartIndex != line.StartIndex && iter.Line.IsParagraphStart) { ll--; } var s = text.Substring(lli, Math.Min(ll, text.Length - lli)); Trace.WriteLine(s); if (iter.Line.IsParagraphStart) { ll++; } lli += ll; }; do { var newRun = iter.Run.Glyphs != null && iter.Run.Item.Offset != iRun; if (newRun) { iRun = iter.Run.Item.Offset; render(); numGlyph = 0; line = null; } if (line == null) { line = iter.Line; run = iter.Run; } numGlyph++; } while (iter.NextChar()); render(); }
public static void LayoutLinePath(Cairo.Context cr, Pango.LayoutLine line) { pango_cairo_layout_line_path(cr == null ? IntPtr.Zero : cr.Handle, line == null ? IntPtr.Zero : line.Handle); }
public static void ShowLayoutLine(Cairo.Context cr, Pango.LayoutLine line) { pango_cairo_show_layout_line(cr == null ? IntPtr.Zero : cr.Handle, line == null ? IntPtr.Zero : line.Handle); }
IEnumerable <Line> Analyselayout(Pango.Layout pl) { var text = pl.Text; var iter = pl.Iter; var lli = 0; var ll = 0; var li = 0; var iRun = 0; var numGlyph = 0; Pango.LayoutLine line = iter.Line; Pango.LayoutRun run = iter.Run; var scale = Pango.Scale.PangoScale; Func <Line> render = () => { if (numGlyph == 0) { return(default(Line)); } ll = numGlyph; var newline = line != null && line.StartIndex != li; if (newline) { li = line.StartIndex; } if (iter.Line.StartIndex != line.StartIndex && iter.Line.IsParagraphStart) { ll--; } var llrect = new Pango.Rectangle(); var rect = new Pango.Rectangle(); line.GetExtents(ref rect, ref llrect); var lline = new Line { Pos = lli, Len = Math.Min(ll, text.Length - lli), Width = run.Glyphs.Width, Height = llrect.Height / scale }; if (iter.Line.IsParagraphStart) { ll++; } lli += ll; return(lline); }; do { var newRun = iter.Run.Glyphs != null && iter.Run.Item.Offset != iRun; if (newRun) { iRun = iter.Run.Item.Offset; yield return(render()); numGlyph = 0; line = null; } if (line == null) { line = iter.Line; run = iter.Run; } numGlyph++; } while(iter.NextChar()); yield return(render()); }