public LongHorMetric GetMetric(int glyphId) { if (glyphId < 0 || glyphId >= numGlyphs) { return(null); } if (File.Exists(filePath) == false) { return(null); } if (glyphId < numberOfHMetrics) { using (Stream stream = File.OpenRead(filePath)) using (BinaryReaderFont reader = new BinaryReaderFont(stream)) { reader.Position = position + glyphId * LongHorMetric.ByteSize; return(LongHorMetric.Read(reader)); } } using (Stream stream = File.OpenRead(filePath)) using (BinaryReaderFont reader = new BinaryReaderFont(stream)) { reader.Position = position + numberOfHMetrics * LongHorMetric.ByteSize + (glyphId - numberOfHMetrics) * 2; LongHorMetric hMetric = new LongHorMetric(); hMetric.lsb = reader.ReadInt16(); return(hMetric); } /* * if (glyphId >= hMetrics.Count) { * return null; * } * return hMetrics[glyphId]; */ }
public void Reset() { UseInterpreter = false; UseBitmapGlyph = false; hMetric = null; GlyphId = 0; Glyph = null; X = 0; Bitmap = null; if (Graphics != null) { Graphics.Dispose(); } Graphics = null; }
public static void DrawGlyph(RendererContext context) { CFFTable cff = context.Font.Tables.CFF; HmtxTable hmtx = context.Font.Tables.hmtx; LongHorMetric hMetric = context.hMetric; //Console.WriteLine("glyphId: " + glyphId); bool hasWidth = false; if (hmtx != null) { hMetric = hmtx.GetMetric(context.GlyphId); if (cff.privateDict != null && hMetric != null) { //Console.WriteLine("advanceWidth: {0}", hMetric.advanceWidth); //Console.WriteLine("cff.privateDict.defaultWidthX: {0}", cff.privateDict.defaultWidthX); hasWidth = hMetric.advanceWidth != (ushort)cff.privateDict.defaultWidthX; } } //Console.WriteLine(); //Console.WriteLine("glyphId: {0}", context.GlyphId); //Console.WriteLine("Docode:\n{0}", CFFCharString.Decode(cff.charStrings[context.GlyphId])); GraphicsPath path = cff.GetGlyph(context.GlyphId, hasWidth); if (path == null) { if (hMetric != null) { context.X += hMetric.advanceWidth; return; } context.X += 100; return; } float imageSize = context.FontSize; float unitsPerEm = context.Font.Tables.head.unitsPerEm; float ascender = context.Font.Tables.hhea.ascender; float descender = context.Font.Tables.hhea.descender; float scale = imageSize / (ascender - descender); //float scale = imageSize / unitsPerEm; //scale *= 0.01f; float baseLine = scale * ascender; /* * GraphicsPath path = new GraphicsPath(FillMode.Alternate); * for (int i = 0; i < points.Count; i++) { * PointF p = points[i]; * Console.WriteLine("Point: {0}", points[i]); * p.X /= 10; * p.Y /= 10; * //p.X = -p.X; * //p.Y = -p.Y; * //p.X += 100; * //p.Y += 100; * points[i] = p; * } * Console.WriteLine(); */ //path.AddLines(points.ToArray()); //path.Transform(new Matrix(scale, 0, 0, -scale, (float)Math.Round(x * scale), baseLine)); float x = context.DX + context.X * scale; float y = context.DY + baseLine; path.Transform(new Matrix( scale, 0, 0, -scale, x, y) ); path.CloseFigure(); context.Graphics.FillPath(Brushes.Black, path); //Console.WriteLine("hMetric.advanceWidth: {0}", hMetric.advanceWidth); if (hMetric != null) { context.X += hMetric.advanceWidth; return; } context.X += 100; }
protected static void DrawSimpleGlyph(RendererContext context, SimpleGlyph simpleGlyph) { LongHorMetric hMetric = context.hMetric; //float unitsPerEm = font.Tables.head.unitsPerEm; float scale = context.Scale; //float scale = imageSize / unitsPerEm; //scale *= 0.01f; //float xMin = scale * (glyph.xMin + font.Tables.head.xMin); //float yMin = scale * (glyph.yMin + font.Tables.head.yMin); float xMin = context.X; // + glyph.xMin; float yMin = 0; if (hMetric != null) { //Console.WriteLine("hMetric.lsb: {0}", hMetric.lsb); //Console.WriteLine("hMetric.advanceWidth " + hMetric.advanceWidth); xMin += context.Glyph.xMin - hMetric.lsb; xMin = Math.Max(xMin, 0); } else { xMin += context.Glyph.xMin; } xMin *= scale; yMin = context.Ascender * scale; xMin += context.DX; yMin += context.DY; //xMin = (float)Math.Round(xMin); /* * //Console.WriteLine("unitsPerEm " + unitsPerEm); * Console.WriteLine("ascender " + ascender); * Console.WriteLine("descender " + descender); * Console.WriteLine("scale " + scale); * Console.WriteLine("baseLine " + baseLine); * Console.WriteLine("glyph.xMin " + glyph.xMin); * Console.WriteLine("glyph.xMax " + glyph.xMax); * Console.WriteLine("glyph.yMin " + glyph.yMin); * Console.WriteLine("glyph.yMax " + glyph.yMax); * Console.WriteLine("head.xMin " + font.Tables.head.xMin); * Console.WriteLine("xMin " + xMin); * Console.WriteLine("yMin " + yMin); * Console.WriteLine(); * //*/ ushort[] endPtsOfContours = simpleGlyph.endPtsOfContours; SimpleGlyphFlags[] flags = simpleGlyph.flags; short[] xCoordinates = simpleGlyph.xCoordinates; short[] yCoordinates = simpleGlyph.yCoordinates; GraphicsPath path = new GraphicsPath(FillMode.Alternate); int length = endPtsOfContours.Length; int start = 0; PointF[] on = new PointF[2]; PointF[] off = new PointF[8]; for (int n = 0; n < length; n++) { float fx = 0, fy = 0; int onCount = 0; int offCount = 0; int end = endPtsOfContours[n]; // first point is not on-curve if ((flags[start] & SimpleGlyphFlags.ON_CURVE_POINT) == 0) { float x0 = xMin + xCoordinates[end] * scale; float y0 = yMin - (yCoordinates[end] * scale); on[0].X = x0; on[0].Y = y0; onCount++; fx = x0; fy = y0; } for (int i = start; i <= end; i++) { float x0 = xMin + xCoordinates[i] * scale; float y0 = yMin - (yCoordinates[i] * scale); if ((flags[i] & SimpleGlyphFlags.ON_CURVE_POINT) > 0) { //if (onCount == 0) { // fx = x0; // fy = y0; //} on[onCount].X = x0; on[onCount].Y = y0; onCount++; if (onCount == 2) { CreateCurvePoints(path, on, off, offCount); onCount = 1; offCount = 0; on[0].X = on[1].X; on[0].Y = on[1].Y; } else { fx = x0; fy = y0; } } else { off[offCount].X = x0; off[offCount].Y = y0; offCount++; } } if (onCount == 1) { on[1].X = fx; on[1].Y = fy; CreateCurvePoints(path, on, off, offCount); } path.CloseFigure(); start = end + 1; } context.Graphics.FillPath(Brushes.Black, path); path.Dispose(); }