public void Translate(Outline.Point p) { xMin += p.X; yMin += p.Y; xMax += p.X; yMax += p.Y; }
// Construct from a TTF.Outline public TTFTextOutline(TTF.Outline ttfoutline, TTF.Outline.Point adv, bool reversed) { min = new Vector3(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity); max = new Vector3(float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity); size = Vector3.zero; nvertices = 0; points = new List <Vector3>(nvertices); blengthes = new List <int>(); advance = new Vector3((float)adv.X, (float)adv.Y, 0); int i = 0; List <Vector3> cb = new List <Vector3>(); while (i < ttfoutline.Size) { TTF.Outline.Point p = ttfoutline.Path[i]; Vector3 v = new Vector3((float)p.X, (float)p.Y, 0); if (ttfoutline.Types[i] == TTF.Outline.PointType.MoveTo) // new contour { cb = ClearDup(cb); if (cb.Count > 0) { if (reversed) { cb.Reverse(); } AddBoundary(cb); } cb.Clear(); } cb.Add(v); ++i; } cb = ClearDup(cb); if (cb.Count > 0) { if (reversed) { cb.Reverse(); } AddBoundary(cb); } //CheckDups("Constructor"); }
// Compute the Bounding box of a single glyph public BBox Measure(char c, out Outline.Point advance) { // load glyph for c in face slot int code = FT.FT_Load_Char(face_, (uint)c, (int)(FT.FT_LOAD_DEFAULT|( 1 << 3 ))); // FT_LOAD_DEFAULT, FT_LOAD_NO_BITMAP, FT_LOAD_NO_SCALE ? FT.CheckError(code); // Check that the glyph is in Outline format FT.FT_FaceRec facerec = FT.HandleToRecord<FT.FT_FaceRec>(face_); IntPtr slot = facerec.glyph; FT.FT_GlyphSlotRec slotrec = FT.HandleToRecord<FT.FT_GlyphSlotRec>(slot); if (slotrec.format != FT.GLYPH_FORMAT_OUTLINE) { throw new FTError("Bad glyph format (" + slotrec.format + ")"); } // get glyph in gptr IntPtr gptr; code = FT.FT_Get_Glyph(slot, out gptr); FT.CheckError(code); FT.FT_BBox ft_bbox; FT.FT_Glyph_Get_CBox(gptr, 0, out ft_bbox); FT.FT_Done_Glyph(gptr); BBox bbox = new BBox(ft_bbox, vectorScale_); advance = new Outline.Point(slotrec.advance, vectorScale_); return bbox; }
public Outline GetTextOutline(string[] lines, ref Outline.Point position, HorizontalJustification h, VerticalJustification v, bool useKerning, float interline) { //int nblines = lines.Length; // total cbox BBox bbox = Measure(lines, interline); float startY = 0; switch (v) { case VerticalJustification.Origin: startY = position.Y; break; case VerticalJustification.Top: startY = position.Y - bbox.yMax; break; case VerticalJustification.Bottom: startY = position.Y - bbox.yMin; break; case VerticalJustification.Center: startY = position.Y + (bbox.yMax - bbox.yMin) / 2 - bbox.yMax; break; } Outline outline = new Outline(); Outline.Point pos = new Outline.Point(); foreach (string line in lines) { pos.X = position.X; pos.Y = startY; Outline o = GetStringOutline(line, ref pos, h, VerticalJustification.Origin, useKerning); outline.AddOutline(o); startY -= Height * interline; } return outline; }
public Outline GetStringOutline(string txt, ref Outline.Point advance, HorizontalJustification h, VerticalJustification v) { return GetStringOutline(txt, ref advance, h, v, false); }
public Outline GetStringOutline(string txt, ref Outline.Point position, HorizontalJustification h, VerticalJustification v, bool useKerning) { return GetStringOutline(txt, ref position, h, v, useKerning, 1); }
public Outline GetStringOutline(string txt, ref Outline.Point position, float spacing, float emboldStrenght) { return GetStringOutline(txt, ref position, HorizontalJustification.Origin, VerticalJustification.Origin, false, spacing, emboldStrenght,4); }
// Compute the outline for a whole line public Outline GetStringOutline(string txt, ref Outline.Point position, HorizontalJustification h, VerticalJustification v, bool useKerning, float spacing, float emboldStrenght, int isteps) { Outline res = new Outline(); // first set pen position according to requested text justification if (h != HorizontalJustification.Origin || v != VerticalJustification.Origin) { // Compute Bounding box and set original advancement according to justification BBox bbox = Measure(txt); switch (h) { case HorizontalJustification.Left: position.X = position.X - bbox.xMin; break; case HorizontalJustification.Right: position.X = position.X - bbox.xMax; break; case HorizontalJustification.Center: position.X = position.X - (bbox.xMin + bbox.xMax) / 2; break; } switch (v) { case VerticalJustification.Top: position.Y = position.Y -bbox.yMax; break; case VerticalJustification.Bottom: position.Y = position.Y -bbox.yMin; break; case VerticalJustification.Center: position.Y = position.Y -(bbox.yMin + bbox.yMax) / 2; break; } } // Console.WriteLine("Original pen position=" + position); if (! HasKerning) { useKerning = false; } int prev = 0; for (int i = 0; i < txt.Length; ++i) { int idx = FT.FT_Get_Char_Index(face_, txt[i]); if (useKerning && prev != 0 && idx != 0) // adjust with kerning properties { position.Translate(GetKerning(prev, idx)); } Outline.Point adv; Outline o = GetGlyphOutline(idx, out adv, true, emboldStrenght,isteps); o.Translate(position); res.AddOutline(o); adv.Scale(spacing); position.Translate(adv); prev = idx; } /* foreach (char c in txt) { Outline.Point adv; Outline o = GetGlyphOutline(c, out adv, true); o.Translate(advance); res.AddOutline(o); advance.Translate(adv); } */ return res; }
/* * public Outline GetGlyphOutline(int idx, out Outline.Point advance, bool flatten) { return GetGlyphOutline(idx, out advance, flatten, 0, 4); } */ public Outline GetGlyphOutline(char c, out Outline.Point advance) { return GetGlyphOutline(c, out advance, true); }
public Outline GetGlyphOutline(char c, out Outline.Point advance, bool flatten) { int idx = FT.FT_Get_Char_Index(face_, c); return GetGlyphOutline(idx, out advance, flatten,0,4); }
public Outline GetGlyphOutline(char c, out Outline.Point advance, bool flatten, float embold, int isteps) { int idx = FT.FT_Get_Char_Index(face_, c); return GetGlyphOutline(idx, out advance, flatten, embold, isteps); }
// Compute outline for a single glyph // if flatten is true convert curve into a list of segments // out parameter advance is set to the default glyph advancement // if embold <> 0, embold the outline by the desired strength public Outline GetGlyphOutline(int idx, out Outline.Point advance, bool flatten, float embold, int isteps) { // TODO: add outline caching ? // load glyph for c in face slot //int code = FT.FT_Load_Char(face_, (uint)c, FT.FT_LOAD_DEFAULT); // FT_LOAD_DEFAULT, FT_LOAD_NO_BITMAP, FT_LOAD_NO_SCALE ? int code = FT.FT_Load_Glyph(face_, idx, FT.FT_LOAD_DEFAULT); FT.CheckError(code); // Check that the glyph is in Outline format FT.FT_FaceRec facerec = FT.HandleToRecord<FT.FT_FaceRec>(face_); IntPtr slot = facerec.glyph; FT.FT_GlyphSlotRec slotrec = FT.HandleToRecord<FT.FT_GlyphSlotRec>(slot); if (slotrec.format != FT.GLYPH_FORMAT_OUTLINE) { throw new FTError(string.Format("Bad glyph format (0x{0:x4})", slotrec.format)); //throw new FTError("Bad glyph format (" + slotrec.format + ")"); } // Get glyph outline in gptr IntPtr gptr; code = FT.FT_Get_Glyph(slot, out gptr); FT.CheckError(code); // Embold outline if (embold != 0) { // Console.WriteLine("EMBOLD=" + embold); IntPtr optr = FT.fthelper_glyph_get_outline_address(gptr); FT.FT_Outline_Embolden(optr, (int) (embold * 64 * 100)); // convert to 26.6 fractional format } // Decompose outline Outline outline = null; if (flatten) { outline = Outline.FlattenGlyph(gptr, vectorScale_,isteps); } else { outline = Outline.DecomposeGlyph(gptr, vectorScale_,isteps); } FT.FT_Done_Glyph(gptr); advance = new Outline.Point(slotrec.advance, vectorScale_); return outline; }
public static Outline DecomposeGlyph(IntPtr glyph, float scale, int isteps) { Outline outline = new Outline(isteps); if (odecomposer == null) { odecomposer = new OutlineDecomposer(scale); } lock (odecomposer) { odecomposer.scale = scale; odecomposer.LineToEv = outline.LineTo; odecomposer.MoveToEv = outline.MoveTo; odecomposer.ConicToEv = outline.ConicTo; odecomposer.CubicToEv = outline.CubicTo; odecomposer.Decompose(glyph); } return outline; }
public void AddOutline(Outline other) { for (int i = 0; i < other.Size; ++i) { AddPoint(other.Path[i], other.Types[i]); } }
// static constructor public static TTFTextOutline TTF2Outline(TTF.Outline ttfoutline, TTF.Outline.Point adv, bool reversed) { return(new TTFTextOutline(ttfoutline, adv, reversed)); }
// Compute the outline for a whole line public Outline GetStringOutline(string txt, ref Outline.Point position, HorizontalJustification h, VerticalJustification v, bool useKerning, float spacing, float emboldStrenght, int isteps) { Outline res = new Outline(); // first set pen position according to requested text justification if (h != HorizontalJustification.Origin || v != VerticalJustification.Origin) { // Compute Bounding box and set original advancement according to justification BBox bbox = Measure(txt); switch (h) { case HorizontalJustification.Left: position.X = position.X - bbox.xMin; break; case HorizontalJustification.Right: position.X = position.X - bbox.xMax; break; case HorizontalJustification.Center: position.X = position.X - (bbox.xMin + bbox.xMax) / 2; break; } switch (v) { case VerticalJustification.Top: position.Y = position.Y - bbox.yMax; break; case VerticalJustification.Bottom: position.Y = position.Y - bbox.yMin; break; case VerticalJustification.Center: position.Y = position.Y - (bbox.yMin + bbox.yMax) / 2; break; } } // Console.WriteLine("Original pen position=" + position); if (!HasKerning) { useKerning = false; } int prev = 0; for (int i = 0; i < txt.Length; ++i) { int idx = FT.FT_Get_Char_Index(face_, txt[i]); if (useKerning && prev != 0 && idx != 0) // adjust with kerning properties { position.Translate(GetKerning(prev, idx)); } Outline.Point adv; Outline o = GetGlyphOutline(idx, out adv, true, emboldStrenght, isteps); o.Translate(position); res.AddOutline(o); adv.Scale(spacing); position.Translate(adv); prev = idx; } /* * foreach (char c in txt) * { * Outline.Point adv; * Outline o = GetGlyphOutline(c, out adv, true); * o.Translate(advance); * res.AddOutline(o); * advance.Translate(adv); * } */ return(res); }