public void Print(Typeface typeface, float size, char[] str, GlyphPlan[] glyphPlanBuffer) { //check if we have created a glyph cache GlyphsCache glyphCache; if (!_glyphCaches.TryGetValue(typeface, out glyphCache)) { //create new glyphCache = new GlyphsCache(typeface); _glyphCaches.Add(typeface, glyphCache); } //---------------------------------------------- //1. convert char[] to glyph[] //2. send to shaping engine //3. layout position of each glyph //---------------------------------------------- var glyphPathBuilder = new GlyphPathBuilderVxs(typeface); int j = str.Length; if (j > 1) { //for debug } //TODO:.... //2. //shaping, glyph substitution for (int i = 0; i < j; ++i) { var glyphPlan = new GlyphPlan(); glyphPlan.glyphIndex = (ushort)typeface.LookupIndex(str[i]); glyphPlanBuffer[i] = glyphPlan; } float scale = typeface.CalculateScale(size); float cx = 0; float cy = 0; bool enable_kerning = this.EnableKerning; for (int i = 0; i < j; ++i) { GlyphPlan glyphPlan = glyphPlanBuffer[i]; ushort glyIndex = glyphPlan.glyphIndex; //----------------------------------- //check if we static vxs/bmp for this glyph //if not, create and cache //----------------------------------- glyphPathBuilder.BuildFromGlyphIndex(glyIndex, size); //----------------------------------- var vxs = glyphPathBuilder.GetVxs(); //this advWidth in font design unit float advWidth = typeface.GetAdvanceWidthFromGlyphIndex(glyIndex) * scale; //---------------------------------- glyphPlan.x = cx; glyphPlan.y = 0; glyphPlan.advX = advWidth; glyphPlan.vxs = vxs; // if (enable_kerning && i > 0) { //check kerning advWidth += typeface.GetKernDistance(glyphPlanBuffer[i - 1].glyphIndex, glyphPlanBuffer[i].glyphIndex) * scale; } cx += advWidth; } //TODO:.... //2. //shaping, glyph substitution //3. layout glyph position //---------------------------------------------- //4. actual render }
void RenderWithTextPrinterAndMiniAgg(Typeface typeface, string str, float sizeInPoint, int resolution) { //1. TextPrinter printer = new TextPrinter(); printer.EnableKerning = this.chkKern.Checked; int len = str.Length; GlyphPlan[] glyphPlanList = new GlyphPlan[len]; printer.Print(typeface, sizeInPoint, str, glyphPlanList); //-------------------------- //5. use PixelFarm's Agg to render to bitmap... //5.1 clear background p.Clear(PixelFarm.Drawing.Color.White); if (chkFillBackground.Checked) { //5.2 p.FillColor = PixelFarm.Drawing.Color.Black; //5.3 int glyphListLen = glyphPlanList.Length; float ox = p.OriginX; float oy = p.OriginY; float cx = 0; float cy = 10; for (int i = 0; i < glyphListLen; ++i) { GlyphPlan glyphPlan = glyphPlanList[i]; cx = glyphPlan.x; p.SetOrigin(cx, cy); p.Fill(glyphPlan.vxs); } p.SetOrigin(ox, oy); } if (chkBorder.Checked) { //5.4 p.StrokeColor = PixelFarm.Drawing.Color.Green; //user can specific border width here... //p.StrokeWidth = 2; //5.5 int glyphListLen = glyphPlanList.Length; for (int i = 0; i < glyphListLen; ++i) { GlyphPlan glyphPlan = glyphPlanList[i]; p.Draw(glyphPlan.vxs); } } //6. use this util to copy image from Agg actual image to System.Drawing.Bitmap BitmapHelper.CopyToWindowsBitmap(destImg, winBmp, new RectInt(0, 0, 300, 300)); //--------------- //7. just render our bitmap g.Clear(Color.White); g.DrawImage(winBmp, new Point(10, 0)); //-------------------------- }
public void Print(Typeface typeface, float size, string str, GlyphPlan[] glyphPlanBuffer) { Print(typeface, size, str.ToCharArray(), glyphPlanBuffer); }