private Transform2d GetTextPositionTransform(GFNFont fnt, string txt, double x, double y, double size, double angle, TextAlign align, Transform2d t) { //computes the transformation needed to transform text drawn at origo to get to the wanted position Transform2d res = Transform2d.Translate(x, y); if (angle != 0.0) { res = Transform2d.Rotate(angle) * res; } if (align != TextAlign.BaseLeft) { double dx, dy; GetTextAlignDXDY(fnt, txt, size, align, out dx, out dy); res = Transform2d.Translate(dx, dy) * res; } res = Transform2d.Scale(size / fnt.CapHeight) * res; if (t != null) { return(res * t); } return(res); }
/// <summary> /// Computes how the font should be moved from baseline left to obey a specified alignment /// </summary> private void GetTextAlignDXDY(GFNFont fnt, string txt, double size, TextAlign align, out double dx, out double dy) { dx = 0.0; dy = 0.0; double w, h; //y align: if ((align & TextAlignAtom.TEXT_BOTTOM) != 0) { dy = fnt.GetDescent(size); } else if ((align & TextAlignAtom.TEXT_CENTER_Y) != 0) { dy = -size * 0.5; } else if ((align & TextAlignAtom.TEXT_TOP) != 0) { dy = -fnt.GetAscent(size); } //else align is baseline, dy=0.0 //x align: if ((align & TextAlignAtom.TEXT_RIGHT) != 0) { InternalGetTextSize(fnt, txt, size, out w, out h); dx = -w; } else if ((align & TextAlignAtom.TEXT_CENTER_X) != 0) { InternalGetTextSize(fnt, txt, size, out w, out h); dx = -w * 0.5; } //else align is left, dx=0.0 and we're done }
private static GFNFont FindFont(string fontname) { GFNFont res = null; string filename; if (string.IsNullOrEmpty(fontname)) { filename = "ISOCP"; } else if (fontname[0] == '*') //undecorate name that forces use of internal fonts { filename = fontname.Substring(1).ToUpper(); } else { filename = fontname.ToUpper(); //seems good as is } //already loaded? if (loadedfonts.TryGetValue(filename, out res)) { return(res); } //not loaded, try to load it now Stream fontstream = StreamUtils.FindResourceStream(filename + ".gfn"); if (fontstream == null) { //the font was not found, recursivly use isocp if (filename == "ISOCP") //avoid infinite recursion { throw new Exception("Fatal error: builtin font 'ISOCP' not found"); } res = FindFont("ISOCP"); //remember the non-existing name maps to isocp font for future reference loadedfonts[filename] = res; return(res); } res = GFNFont.FromStream(fontstream); fontstream.Close(); loadedfonts[filename] = res; //cache font for later use return(res); }
public static GFNFont FromString(string fntdef) { string[] lines = fntdef.Split('\n'); int linenum = 1; bool hascapheight = false; bool haslinespacing = false; bool hasstyle = false; bool hasascent = false; bool hasdescent = false; GFNFont res = new GFNFont(); foreach (string _line in lines) { string line = _line.Trim(); if (line == "") //skip empty line { continue; } int eqpos = line.LastIndexOf('='); if (eqpos < 0) { throw new Exception("Invalid definition in font on line " + linenum.ToString()); } string key = line.Substring(0, eqpos); string val = line.Substring(eqpos + 1); key = key.Trim(); val = val.Trim(); if (key.Length == 3) { key = key.Trim('\''); //allow for quoted characters to allow for space definition etc. } switch (key) { case "capheight": hascapheight = true; res.capheight = StrToFloat(val); break; case "linespacing": haslinespacing = true; res.linespacing = StrToFloat(val); break; case "style": if (val == "stroke") { res.filled = false; } else if (val == "fill") { res.filled = true; } else { throw new Exception("Invalid style in font defintion, line " + linenum.ToString()); } hasstyle = true; break; case "ascent": res.ascent = StrToFloat(val); hasascent = true; break; case "descent": res.descent = StrToFloat(val); hasdescent = true; break; case "remark": if (string.IsNullOrEmpty(res.remark)) { res.remark = val; } else { res.remark += "\n" + val; } break; default: if (key.Length != 1) { throw new Exception("Invalid definition in font file, key ='" + key + "' on line " + linenum.ToString()); } try { GFNGlyph glyph = ParseGlyph(val); res.CharLUT[key[0]] = glyph; } catch (Exception exc) { throw new Exception("Invalid font program on line " + linenum.ToString() + " : " + exc.Message); } break; } linenum++; } if (!hascapheight) { throw new Exception("capheight specifier in font missing"); } if (!haslinespacing) { throw new Exception("linespacing specifier in font missing"); } if (!hasstyle) { throw new Exception("style specifier in font missing"); } if (!hasdescent) { throw new Exception("descent specifier in font missing"); } if (!hasascent) { throw new Exception("ascent specifier in font missing"); } return(res); }