public void DrawSample(Gdk.Drawable drawable, string text) { using (Cairo.Context ctx = Gdk.CairoHelper.Create(drawable)) { using (Pango.Layout layout = Pango.CairoHelper.CreateLayout(ctx)) { AssignLayout(layout); layout.SetText(text); // dest size int width, height; drawable.GetSize(out width, out height); // set pos Pango.Rectangle te = Pango.Rectangle.Zero; if (text.Length > 0) { Pango.Rectangle unused; layout.GetPixelExtents(out unused, out te); te.X = (width - te.Width) / 2; te.Y = (height - te.Height) / 2; } // fill background ctx.Save(); int boxSize = 20, padding = 0; Cairo.Color clr1 = Gui.CairoExtensions.RgbToColor(0xE77817); Cairo.Color clr2 = Gui.CairoExtensions.RgbToColor(0x383431); for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { ctx.Rectangle(i * (boxSize + padding), j * (boxSize + padding), boxSize, boxSize); if ((i + j) % 2 == 0) { ctx.SetSourceRGBA(clr1.R, clr1.G, clr1.B, clr1.A); } else { ctx.SetSourceRGBA(clr2.R, clr2.G, clr2.B, clr2.A); } ctx.Fill(); } } ctx.Restore(); // show text if (text.Length > 0) { ctx.Save(); ctx.MoveTo(te.X, te.Y); ctx.Color = new Cairo.Color(1.0, 1.0, 1.0, 1.0); ctx.Antialias = Cairo.Antialias.Gray; ctx.Operator = Cairo.Operator.Source; Pango.CairoHelper.ShowLayout(ctx, layout); ctx.Restore(); } } } }
public static Rectangle DrawText(this Context g, PointD p, string family, Cairo.FontSlant slant, Cairo.FontWeight weight, double size, Cairo.Color color, double width, string text) { g.Save(); g.MoveTo(p.X, p.Y); g.Color = color; Pango.Layout layout = Pango.CairoHelper.CreateLayout(g); layout.Wrap = Pango.WrapMode.Char; layout.Width = (int)(width * Pango.Scale.PangoScale); Pango.FontDescription fd = new Pango.FontDescription(); fd.Family = family; fd.Style = CairoToPangoSlant(slant); fd.Weight = CairoToPangoWeight(weight); fd.AbsoluteSize = size * Pango.Scale.PangoScale; layout.FontDescription = fd; layout.Spacing = 0; layout.Alignment = Pango.Alignment.Left; layout.SetText(text); Pango.Rectangle unused = Pango.Rectangle.Zero; Pango.Rectangle te = Pango.Rectangle.Zero; layout.GetExtents(out unused, out te); Pango.CairoHelper.ShowLayout(g, layout); layout.GetExtents(out unused, out te); (layout as IDisposable).Dispose(); g.Restore(); return(new Rectangle(p.X + unused.X / Pango.Scale.PangoScale, p.Y + unused.Y / Pango.Scale.PangoScale, (unused.Width / Pango.Scale.PangoScale), (unused.Height / Pango.Scale.PangoScale))); }
public static Rectangle DrawText(this Context g, PointD p, string family, FontSlant slant, FontWeight weight, double size, Color color, string text, bool antiAliasing) { g.Save(); g.MoveTo(p.X, p.Y); g.Color = color; g.Antialias = antiAliasing ? Antialias.Subpixel : Antialias.None; Pango.Layout layout = Pango.CairoHelper.CreateLayout(g); Pango.FontDescription fd = new Pango.FontDescription(); fd.Family = family; fd.Style = CairoToPangoSlant(slant); fd.Weight = CairoToPangoWeight(weight); fd.AbsoluteSize = size * Pango.Scale.PangoScale; layout.FontDescription = fd; layout.SetText(text); Pango.CairoHelper.ShowLayoutLine(g, layout.Lines[0]); Pango.Rectangle unused = Pango.Rectangle.Zero; Pango.Rectangle te = Pango.Rectangle.Zero; layout.GetExtents(out unused, out te); (layout as IDisposable).Dispose(); g.Restore(); return(new Rectangle(te.X, te.Y, te.Width, te.Height)); }
public override void DrawTextLayout(object backend, TextLayout layout, double x, double y) { Pango.Layout pl = (Pango.Layout)WidgetRegistry.GetBackend(layout); CairoContextBackend ctx = (CairoContextBackend)backend; ctx.Context.MoveTo(x, y); if (layout.Height <= 0) { Pango.CairoHelper.ShowLayout(ctx.Context, pl); } else { var lc = pl.LineCount; var scale = Pango.Scale.PangoScale; double h = 0; for (int i = 0; i < lc; i++) { var line = pl.Lines [i]; var ext = new Pango.Rectangle(); var extl = new Pango.Rectangle(); line.GetExtents(ref ext, ref extl); h += (extl.Height / scale); if (h > layout.Height) { break; } ctx.Context.MoveTo(x, y + h); Pango.CairoHelper.ShowLayoutLine(ctx.Context, line); } } }
public static void Write(this BinaryWriter file, Pango.Rectangle box) { file.Write((Int32)box.X); file.Write((Int32)box.Y); file.Write((Int32)box.Width); file.Write((Int32)box.Height); }
CodeCompletionContext ICompletionWidget.CreateCodeCompletionContext(int triggerOffset) { CodeCompletionContext c = new CodeCompletionContext(); c.TriggerLine = 0; c.TriggerOffset = triggerOffset; c.TriggerLineOffset = c.TriggerOffset; c.TriggerTextHeight = entry.SizeRequest().Height; c.TriggerWordLength = currentCompletionData.ExpressionLength; int x, y; int tx, ty; entry.GdkWindow.GetOrigin(out x, out y); entry.GetLayoutOffsets(out tx, out ty); int cp = entry.TextIndexToLayoutIndex(entry.Position); Pango.Rectangle rect = entry.Layout.IndexToPos(cp); tx += Pango.Units.ToPixels(rect.X) + x; y += entry.Allocation.Height; c.TriggerXCoord = tx; c.TriggerYCoord = y; return(c); }
public override void DrawTextLayout(object backend, TextLayout layout, double x, double y) { var be = (GtkTextLayoutBackendHandler.PangoBackend)Toolkit.GetBackend(layout); var pl = be.Layout; CairoContextBackend ctx = (CairoContextBackend)backend; ctx.Context.MoveTo(x, y); if (layout.Height <= 0) { Pango.CairoHelper.ShowLayout(ctx.Context, pl); } else { var lc = pl.LineCount; var scale = Pango.Scale.PangoScale; double h = 0; var fe = ctx.Context.FontExtents; var baseline = fe.Ascent / (fe.Ascent + fe.Descent); for (int i = 0; i < lc; i++) { var line = pl.Lines [i]; var ext = new Pango.Rectangle(); var extl = new Pango.Rectangle(); line.GetExtents(ref ext, ref extl); h += h == 0 ? (extl.Height / scale * baseline) : (extl.Height / scale); if (h > layout.Height) { break; } ctx.Context.MoveTo(x, y + h); Pango.CairoHelper.ShowLayoutLine(ctx.Context, line); } } }
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 Rect ToPerspex(this Pango.Rectangle rect) { return(new Rect( Pango.Units.ToDouble(rect.X), Pango.Units.ToDouble(rect.Y), Pango.Units.ToDouble(rect.Width), Pango.Units.ToDouble(rect.Height))); }
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)); }
public void GetGlyphExtents(uint glyph, Pango.Rectangle ink_rect, Pango.Rectangle logical_rect) { IntPtr native_ink_rect = GLib.Marshaller.StructureToPtrAlloc(ink_rect); IntPtr native_logical_rect = GLib.Marshaller.StructureToPtrAlloc(logical_rect); pango_font_get_glyph_extents(Handle, glyph, native_ink_rect, native_logical_rect); Marshal.FreeHGlobal(native_ink_rect); Marshal.FreeHGlobal(native_logical_rect); }
public void ExtentsRange(int start, int end, Pango.Font font, Pango.Rectangle ink_rect, Pango.Rectangle logical_rect) { IntPtr native_ink_rect = GLib.Marshaller.StructureToPtrAlloc(ink_rect); IntPtr native_logical_rect = GLib.Marshaller.StructureToPtrAlloc(logical_rect); pango_glyph_string_extents_range(Handle, start, end, font == null ? IntPtr.Zero : font.Handle, native_ink_rect, native_logical_rect); Marshal.FreeHGlobal(native_ink_rect); Marshal.FreeHGlobal(native_logical_rect); }
public Gdk.Pixbuf BuildImage(FontService fontService) { Cairo.ImageSurface image = new Cairo.ImageSurface(Cairo.Format.ARGB32, WIDTH, HEIGHT); Cairo.Context ctx = new Cairo.Context(image); Pango.Layout layout = Pango.CairoHelper.CreateLayout(ctx); fontService.AssignLayout(layout); // fill background ctx.Save(); ctx.Color = new Cairo.Color(0.0, 0.0, 0.0, 1.0); ctx.Paint(); ctx.Restore(); int charCode = 0; int maxHeight = 0; Cairo.Point pos = new Cairo.Point(PADDING, PADDING); while ((!fontService.OnlyEnglish && charCode < 224) || (fontService.OnlyEnglish && charCode < (224 - 66))) { layout.SetText(alphabet[charCode].ToString()); Pango.Rectangle te = GetTextExtents(layout, pos); // next line if (pos.X + te.Width + fontService.Spacing + PADDING > image.Width) { pos.X = PADDING; pos.Y = te.Y + maxHeight + PADDING; } te = DrawText(ctx, layout, pos); boxes[charCode] = te; pos.X = te.X + te.Width + fontService.Spacing + PADDING; maxHeight = Math.Max(maxHeight, te.Height); charCode++; } int cropHeight = NextP2(boxes[charCode - 1].Y + boxes[charCode - 1].Height - 1); Gdk.Pixbuf pixbuf = new Gdk.Pixbuf( image.Data, true, 8, image.Width, cropHeight, image.Stride); // manual dispose (image as IDisposable).Dispose(); (layout as IDisposable).Dispose(); (ctx.Target as IDisposable).Dispose(); (ctx as IDisposable).Dispose(); return(pixbuf); }
public static void ExtentsToPixels(ref Pango.Rectangle inclusive, ref Pango.Rectangle nearest) { IntPtr native_inclusive = GLib.Marshaller.StructureToPtrAlloc(inclusive); IntPtr native_nearest = GLib.Marshaller.StructureToPtrAlloc(nearest); pango_extents_to_pixels(native_inclusive, native_nearest); inclusive = Pango.Rectangle.New(native_inclusive); Marshal.FreeHGlobal(native_inclusive); nearest = Pango.Rectangle.New(native_nearest); Marshal.FreeHGlobal(native_nearest); }
public void GetCursorPos(int index_, out Pango.Rectangle strong_pos, out Pango.Rectangle weak_pos) { IntPtr native_strong_pos = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Pango.Rectangle))); IntPtr native_weak_pos = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Pango.Rectangle))); pango_layout_get_cursor_pos(Handle, index_, native_strong_pos, native_weak_pos); strong_pos = Pango.Rectangle.New(native_strong_pos); Marshal.FreeHGlobal(native_strong_pos); weak_pos = Pango.Rectangle.New(native_weak_pos); Marshal.FreeHGlobal(native_weak_pos); }
public void GetPixelExtents(out Pango.Rectangle ink_rect, out Pango.Rectangle logical_rect) { IntPtr native_ink_rect = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Pango.Rectangle))); IntPtr native_logical_rect = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Pango.Rectangle))); pango_layout_get_pixel_extents(Handle, native_ink_rect, native_logical_rect); ink_rect = Pango.Rectangle.New(native_ink_rect); Marshal.FreeHGlobal(native_ink_rect); logical_rect = Pango.Rectangle.New(native_logical_rect); Marshal.FreeHGlobal(native_logical_rect); }
public void GetPixelExtents(ref Pango.Rectangle ink_rect, ref Pango.Rectangle logical_rect) { IntPtr native_ink_rect = GLib.Marshaller.StructureToPtrAlloc(ink_rect); IntPtr native_logical_rect = GLib.Marshaller.StructureToPtrAlloc(logical_rect); pango_layout_line_get_pixel_extents(Handle, native_ink_rect, native_logical_rect); ink_rect = Pango.Rectangle.New(native_ink_rect); Marshal.FreeHGlobal(native_ink_rect); logical_rect = Pango.Rectangle.New(native_logical_rect); Marshal.FreeHGlobal(native_logical_rect); }
private Pango.Rectangle GetTextExtents(Pango.Layout layout, Cairo.Point p) { Pango.Rectangle unused = Pango.Rectangle.Zero; Pango.Rectangle te = Pango.Rectangle.Zero; layout.GetPixelExtents(out unused, out te); te.X += p.X; te.Y += p.Y; return(te); }
public void TransformRectangle(ref Pango.Rectangle rect) { IntPtr this_as_native = System.Runtime.InteropServices.Marshal.AllocHGlobal(System.Runtime.InteropServices.Marshal.SizeOf(this)); System.Runtime.InteropServices.Marshal.StructureToPtr(this, this_as_native, false); IntPtr native_rect = GLib.Marshaller.StructureToPtrAlloc(rect); pango_matrix_transform_rectangle(this_as_native, native_rect); ReadNative(this_as_native, ref this); System.Runtime.InteropServices.Marshal.FreeHGlobal(this_as_native); rect = Pango.Rectangle.New(native_rect); Marshal.FreeHGlobal(native_rect); }
public void GetExtents(out Pango.Rectangle ink_rect, out Pango.Rectangle logical_rect) { if (this.width >= 0) { ink_rect = logical_rect = new Pango.Rectangle { X = 0, Y = 0, Width = width, Height = height }; return; } layout.GetExtents(out ink_rect, out logical_rect); }
CodeCompletionContext ICompletionWidget.CreateCodeCompletionContext(int triggerOffset) { int x, y; entry.GdkWindow.GetOrigin(out x, out y); entry.GetLayoutOffsets(out var tx, out var ty); int cp = entry.TextIndexToLayoutIndex(entry.Position); Pango.Rectangle rect = entry.Layout.IndexToPos(cp); x += Pango.Units.ToPixels(rect.X) + tx; y += entry.Allocation.Height; return(new CodeCompletionContext( x, y, entry.SizeRequest().Height, triggerOffset, 0, triggerOffset, currentCompletionData.ExpressionLength )); }
int CalculateCaretXPos(bool useSubPositon) { int byteInRow = (int)Caret.Offset % BytesInRow; int groupNumber = byteInRow / Editor.Options.GroupBytes; int groupByte = byteInRow % Editor.Options.GroupBytes; int caretIndex = groupNumber * (Editor.Options.GroupBytes * 2 + 1) + groupByte * 2; if (useSubPositon) { caretIndex += Caret.SubPosition; } LayoutWrapper layout = GetLayout((int)Caret.Line); Pango.Rectangle rectangle = layout.Layout.IndexToPos(caretIndex); if (layout.IsUncached) { layout.Dispose(); } return(XOffset + (int)(rectangle.X / Pango.Scale.PangoScale)); }
public override void DrawTextLayout(object backend, TextLayout layout, double x, double y) { Pango.Layout pl = (Pango.Layout)WidgetRegistry.GetBackend (layout); CairoContextBackend ctx = (CairoContextBackend)backend; ctx.Context.MoveTo (x, y); if (layout.Height <= 0) { Pango.CairoHelper.ShowLayout (ctx.Context, pl); } else { var lc = pl.LineCount; var scale = Pango.Scale.PangoScale; double h = 0; for (int i=0; i<lc; i++) { var line = pl.Lines [i]; var ext = new Pango.Rectangle (); var extl = new Pango.Rectangle (); line.GetExtents (ref ext, ref extl); h += (extl.Height / scale); if (h > layout.Height) break; ctx.Context.MoveTo (x, y + h); Pango.CairoHelper.ShowLayoutLine (ctx.Context, line); } } }
public void Draw(Cairo.Context cr, Cairo.Rectangle area, DocumentLine lineSegment, double x, double y, double lineHeight) { int foundSegment = -1; if (lineSegment != null) { for (int i = 0; i < foldSegments.Count; i++) { FoldSegment segment = foldSegments [i]; if (segment.StartLine.Offset <= lineSegment.Offset && lineSegment.EndOffsetIncludingDelimiter <= segment.EndLine.EndOffsetIncludingDelimiter) { foundSegment = i; roles [i] = Roles.Between; if (segment.StartLine.Offset == lineSegment.Offset) { roles [i] |= Roles.Start; if (segment.IsFolded) { roles [i] |= Roles.End; } } if (segment.EndLine.Offset == lineSegment.Offset) { roles [i] |= Roles.End; } } } } TextViewMargin textViewMargin = editor.TextViewMargin; ISyntaxMode mode = Document.SyntaxMode != null && editor.Options.EnableSyntaxHighlighting ? Document.SyntaxMode : new SyntaxMode(Document); // Gdk.Rectangle lineArea = new Gdk.Rectangle (textViewMargin.XOffset, y, editor.Allocation.Width - textViewMargin.XOffset, editor.LineHeight); // Gdk.GC gc = new Gdk.GC (drawable); TextViewMargin.LayoutWrapper lineLayout = null; double brightness = HslColor.Brightness(editor.ColorStyle.Default.BackgroundColor); int colorCount = foldSegments.Count + 2; for (int segment = -1; segment <= foundSegment; segment++) { HslColor hslColor = new HslColor(editor.ColorStyle.Default.BackgroundColor); int colorPosition = segment + 1; if (segment == foldSegments.Count - 1) { colorPosition += 2; } if (brightness < 0.5) { hslColor.L = hslColor.L * 0.81 + hslColor.L * 0.25 * (colorCount - colorPosition) / colorCount; } else { hslColor.L = hslColor.L * 0.86 + hslColor.L * 0.1 * colorPosition / colorCount; } Roles role = Roles.Between; double xPos = textViewMargin.XOffset; double rectangleWidth = editor.Allocation.Width - xPos; if (segment >= 0) { DocumentLine segmentStartLine = foldSegments [segment].StartLine; lineLayout = textViewMargin.CreateLinePartLayout(mode, segmentStartLine, segmentStartLine.Offset, segmentStartLine.Length, -1, -1); Pango.Rectangle rectangle = lineLayout.Layout.IndexToPos(GetFirstNonWsIdx(lineLayout.Layout.Text)); xPos = System.Math.Max(textViewMargin.XOffset, (textViewMargin.XOffset + rectangle.X / Pango.Scale.PangoScale - editor.HAdjustment.Value)); DocumentLine segmentEndLine = foldSegments [segment].EndLine; lineLayout = textViewMargin.CreateLinePartLayout(mode, segmentEndLine, segmentEndLine.Offset, segmentEndLine.Length, -1, -1); rectangle = lineLayout.Layout.IndexToPos(GetFirstNonWsIdx(lineLayout.Layout.Text)); xPos = System.Math.Min(xPos, System.Math.Max(textViewMargin.XOffset, (textViewMargin.XOffset + rectangle.X / Pango.Scale.PangoScale - editor.HAdjustment.Value))); int width = editor.Allocation.Width; if (editor.HAdjustment.Upper > width) { width = (int)(textViewMargin.XOffset + editor.HAdjustment.Upper - editor.HAdjustment.Value); } rectangleWidth = (int)(width - xPos - 6 * (segment + 1)); role = roles [segment]; } DrawRoundRectangle(cr, (role & Roles.Start) == Roles.Start, (role & Roles.End) == Roles.End, xPos, y, editor.LineHeight / 2, rectangleWidth, lineHeight); cr.Color = ColorScheme.ToCairoColor(hslColor); cr.Fill(); /* if (segment == foldSegments.Count - 1) { * cr.Color = new Cairo.Color (0.5, 0.5, 0.5, 1); * cr.Stroke (); * }*/ if (lineLayout != null && lineLayout.IsUncached) { lineLayout.Dispose(); lineLayout = null; } } // gc.Dispose (); }
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()); }
public void GetExtents(out Pango.Rectangle ink_rect, out Pango.Rectangle logical_rect) { layout.GetExtents(out ink_rect, out logical_rect); }
public override void DrawTextLayout(object backend, TextLayout layout, double x, double y) { var be = (GtkTextLayoutBackendHandler.PangoBackend)Toolkit.GetBackend (layout); var pl = be.Layout; CairoContextBackend ctx = (CairoContextBackend)backend; ctx.Context.MoveTo (x, y); if (layout.Height <= 0) { Pango.CairoHelper.ShowLayout (ctx.Context, pl); } else { var lc = pl.LineCount; var scale = Pango.Scale.PangoScale; double h = 0; var fe = ctx.Context.FontExtents; var baseline = fe.Ascent / (fe.Ascent + fe.Descent); for (int i=0; i<lc; i++) { var line = pl.Lines [i]; var ext = new Pango.Rectangle (); var extl = new Pango.Rectangle (); line.GetExtents (ref ext, ref extl); h += h == 0 ? (extl.Height / scale * baseline) : (extl.Height / scale); if (h > layout.Height) break; ctx.Context.MoveTo (x, y + h); Pango.CairoHelper.ShowLayoutLine (ctx.Context, line); } } }
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()); }
public void GetCursorPos(int index_, out Pango.Rectangle strong_pos, out Pango.Rectangle weak_pos) { layout.GetCursorPos(index_, out strong_pos, out weak_pos); }
public void GetExtents (out Pango.Rectangle ink_rect, out Pango.Rectangle logical_rect) { if (this.width >= 0) { ink_rect = logical_rect = new Pango.Rectangle { X = 0, Y = 0, Width = width, Height = height }; return; } layout.GetExtents (out ink_rect, out logical_rect); }
public AttrShape(Pango.Rectangle ink_rect, Pango.Rectangle logical_rect) : this(pango_attr_shape_new(ref ink_rect, ref logical_rect)) { }
static extern IntPtr pango_attr_shape_new(ref Pango.Rectangle ink_rect, ref Pango.Rectangle logical_rect);
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(); } }
public static Rectangle DrawTextBlock(this Context g, TextBlock tb, bool render) { double topBottomSpan = tb.Padding.Top + tb.Padding.Bottom; double leftRightSpan = tb.Padding.Left + tb.Padding.Right; double vertAlgSpan = 0; g.Save (); Pango.Layout layout = createLayoutFromTextBlock(g,tb); g.Color = tb.FontColor.ToCairoColor(); Pango.Rectangle inkRect1; Pango.Rectangle logicalRect; layout.GetExtents (out inkRect1, out logicalRect); double measuredHeight = (logicalRect.Height) / (Pango.Scale.PangoScale * UnitMultiplier); double measuredY = logicalRect.Y / (Pango.Scale.PangoScale * UnitMultiplier); if(tb.VerticalAlignment != VerticalAlignment.Top) vertAlgSpan = measureVerticlaSpan(tb,measuredHeight); g.MoveTo ((tb.Left + tb.Padding.Left) * UnitMultiplier, (tb.Top + tb.Padding.Top + vertAlgSpan - measuredY) * UnitMultiplier); if (render) { Pango.CairoHelper.ShowLayout(g, layout); } layout.GetExtents (out inkRect1, out logicalRect); measuredHeight = (logicalRect.Height) / (Pango.Scale.PangoScale * UnitMultiplier); double measuredWidth = logicalRect.Width / (Pango.Scale.PangoScale * UnitMultiplier); measuredY = logicalRect.Y / (Pango.Scale.PangoScale * UnitMultiplier); if ( DebugTextBlock && render ) { Pango.Rectangle inklineRect = new Pango.Rectangle(); Pango.Rectangle logLineRect = new Pango.Rectangle(); { double span = measuredY; for(int d = 0 ; d < layout.LinesReadOnly.Length;d++){ var item = layout.LinesReadOnly[d]; item.GetExtents(ref inklineRect,ref logLineRect); //seems like when measuring line logLineRect.Y is not needed but i don't know why double h = ((logLineRect.Height / Pango.Scale.PangoScale)); double x = ((tb.Left + tb.Padding.Left) * UnitMultiplier + (logLineRect.X / Pango.Scale.PangoScale)); double y = (tb.Top + tb.Padding.Top) * UnitMultiplier + span; DrawDebugRect(g, new Cairo.Rectangle( x, y, ((logLineRect.Width / Pango.Scale.PangoScale)) , h )); span += h; } } } (layout as IDisposable).Dispose(); g.Restore (); return new Rectangle( tb.Left , tb.Top, measuredWidth + leftRightSpan , measuredHeight + topBottomSpan); }