public RectD GetBounds() { //find bound //TODO: review here if (_needBoundUpdate) { int partCount = _vxList.Length; for (int i = 0; i < partCount; ++i) { SvgPart vx = _vxList[i]; if (vx.Kind != SvgRenderVxKind.Path) { continue; } RectD rectTotal = RectD.ZeroIntersection; BoundingRect.GetBoundingRect(new VertexStoreSnap(vx.GetVxs()), ref rectTotal); _boundRect.ExpandToInclude(rectTotal); } _needBoundUpdate = false; } return(_boundRect); }
public BlurWithPainter() { //m_rbuf2 = new ReferenceImage(); m_shape_bounds = new RectD(); m_shadow_ctrl = new PolygonEditWidget(4); this.FlattenCurveChecked = true; this.BlurMethod = BlurMethod.RecursiveBlur; this.BlurRadius = 15; Font svgFont = SvgFontStore.LoadFont("svg-LiberationSansFont", 300); m_pathVxs = svgFont.GetGlyph('a').originalVxs;// typeFaceForLargeA.GetGlyphForCharacter('a'); Affine shape_mtx = Affine.NewMatix(AffinePlan.Translate(150, 100)); m_pathVxs = shape_mtx.TransformToVxs(m_pathVxs); var curveFlattener = new CurveFlattener(); m_path_2 = new VertexStoreSnap(curveFlattener.MakeVxs(m_pathVxs)); BoundingRect.GetBoundingRect(m_path_2, ref m_shape_bounds); m_shadow_ctrl.SetXN(0, m_shape_bounds.Left); m_shadow_ctrl.SetYN(0, m_shape_bounds.Bottom); m_shadow_ctrl.SetXN(1, m_shape_bounds.Right); m_shadow_ctrl.SetYN(1, m_shape_bounds.Bottom); m_shadow_ctrl.SetXN(2, m_shape_bounds.Right); m_shadow_ctrl.SetYN(2, m_shape_bounds.Top); m_shadow_ctrl.SetXN(3, m_shape_bounds.Left); m_shadow_ctrl.SetYN(3, m_shape_bounds.Top); m_shadow_ctrl.LineColor = ColorRGBAf.MakeColorRGBA(0f, 0.3f, 0.5f, 0.3f); }
public override Rectangle GetRectBounds() { if (!_evalRectBounds) { // Q1RectD bound1 = BoundingRect.GetBoundingRect(_vxs); _bounds = new Rectangle( (int)Math.Round(bound1.Left), (int)Math.Round(bound1.Bottom), //*** (int)Math.Round(bound1.Width), (int)Math.Round(bound1.Height)); _evalRectBounds = true; } return(_bounds); }
static SimpleFontAtlasBuilder CreateAggSubPixelRenderingTextureFont( Typeface typeface, float sizeInPoint, HintTechnique hintTech, IEnumerable <ushort> glyphIndexIter) { ////read type face from file //Typeface typeface; //using (var fs = new FileStream(fontfile, FileMode.Open, FileAccess.Read)) //{ // var reader = new OpenFontReader(); // //1. read typeface from font file // typeface = reader.Read(fs); //} //sample: create sample msdf texture //------------------------------------------------------------- var builder = new GlyphPathBuilder(typeface); builder.SetHintTechnique(hintTech); //------------------------------------------------------------- var atlasBuilder = new SimpleFontAtlasBuilder(); atlasBuilder.SetAtlasInfo(TextureKind.AggSubPixel, sizeInPoint); VertexStorePool vxsPool = new VertexStorePool(); //create agg cavnas foreach (ushort gindex in glyphIndexIter) { //build glyph builder.BuildFromGlyphIndex(gindex, sizeInPoint); var txToVxs = new GlyphTranslatorToVxs(); builder.ReadShapes(txToVxs); // //create new one var glyphVxs = new VertexStore(); txToVxs.WriteOutput(glyphVxs, vxsPool); //find bound //-------------------------------------------- //GlyphImage glyphImg = new GlyphImage() RectD bounds = new Agg.RectD(); BoundingRect.GetBoundingRect(new VertexStoreSnap(glyphVxs), ref bounds); //-------------------------------------------- int w = (int)System.Math.Ceiling(bounds.Width); int h = (int)System.Math.Ceiling(bounds.Height); if (w < 5) { w = 5; } if (h < 5) { h = 5; } //translate to positive quadrant double dx = (bounds.Left < 0) ? -bounds.Left : 0; double dy = (bounds.Bottom < 0) ? -bounds.Bottom : 0; w = w * 4; if (dx != 0 || dy != 0) { Agg.Transform.Affine transformMat = Agg.Transform.Affine.NewTranslation(dx, dy); VertexStore vxs2 = new VertexStore(); glyphVxs.TranslateToNewVxs(dx, dy, vxs2); glyphVxs = vxs2; } //-------------------------------------------- //create glyph img ActualImage img = new Agg.ActualImage(w, h, PixelFormat.ARGB32); ImageGraphics2D imgCanvas2d = new Agg.ImageGraphics2D(img); AggCanvasPainter painter = new Agg.AggCanvasPainter(imgCanvas2d); //we use white glyph on black bg for this texture painter.Clear(Color.Black); //fill with black painter.FillColor = Color.White; painter.StrokeColor = Color.White; //-------------------------------------------- painter.UseSubPixelRendering = true; //-------------------------------------------- //-------------------------------------------- painter.Fill(glyphVxs); //-------------------------------------------- var glyphImage = new GlyphImage(w, h); glyphImage.TextureOffsetX = dx; glyphImage.TextureOffsetY = dy; glyphImage.SetImageBuffer(ActualImage.GetBuffer2(img), false); //copy data from agg canvas to glyph image atlasBuilder.AddGlyph(gindex, glyphImage); //int[] buffer = glyphImage.GetImageBuffer(); //using (var bmp = new System.Drawing.Bitmap(glyphImage.Width, glyphImage.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb)) //{ // var bmpdata = bmp.LockBits(new System.Drawing.Rectangle(0, 0, glyphImage.Width, glyphImage.Height), // System.Drawing.Imaging.ImageLockMode.ReadWrite, bmp.PixelFormat); // System.Runtime.InteropServices.Marshal.Copy(buffer, 0, bmpdata.Scan0, buffer.Length); // bmp.UnlockBits(bmpdata); // bmp.Save("d:\\WImageTest\\a001_subpix_xn2_" + gindex + ".png"); //} } //var glyphImg2 = atlasBuilder.BuildSingleImage(); //using (var bmp = new System.Drawing.Bitmap(glyphImg2.Width, glyphImg2.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb)) //{ // var bmpdata = bmp.LockBits(new System.Drawing.Rectangle(0, 0, glyphImg2.Width, glyphImg2.Height), // System.Drawing.Imaging.ImageLockMode.ReadWrite, bmp.PixelFormat); // int[] intBuffer = glyphImg2.GetImageBuffer(); // System.Runtime.InteropServices.Marshal.Copy(intBuffer, 0, bmpdata.Scan0, intBuffer.Length); // bmp.UnlockBits(bmpdata); // bmp.Save("d:\\WImageTest\\a_total.png"); //} //atlasBuilder.SaveFontInfo("d:\\WImageTest\\a_info.xml"); return(atlasBuilder); }
public void RenderChar(char testChar, HintTechnique hint) { builder.SetHintTechnique(hint); #if DEBUG GlyphBoneJoint.dbugTotalId = 0;//reset builder.dbugAlwaysDoCurveAnalysis = true; #endif _infoView.Clear(); _latestHint = hint; _testChar = testChar; //---------------------------------------------------- // builder.Build(testChar, _sizeInPoint); var txToVxs1 = new GlyphTranslatorToVxs(); builder.GlyphDynamicEdgeOffset = this.GlyphEdgeOffset; builder.ReadShapes(txToVxs1); #if DEBUG var ps = txToVxs1.dbugGetPathWriter(); _infoView.ShowOrgBorderInfo(ps.Vxs); #endif PixelFarm.Drawing.VertexStore vxs = new PixelFarm.Drawing.VertexStore(); txToVxs1.WriteOutput(vxs); //---------------------------------------------------- //---------------------------------------------------- painter.UseSubPixelLcdEffect = this.UseLcdTechnique; //5. use PixelFarm's Agg to render to bitmap... //5.1 clear background painter.Clear(PixelFarm.Drawing.Color.White); RectD bounds = new RectD(); BoundingRect.GetBoundingRect(new PixelFarm.Drawing.VertexStoreSnap(vxs), ref bounds); //---------------------------------------------------- float scale = _typeface.CalculateScaleToPixelFromPointSize(_sizeInPoint); _pxscale = scale; this._infoView.PxScale = scale; var left2 = 0; int floor_1 = (int)left2; float diff = left2 - floor_1; //---------------------------------------------------- if (OffsetMinorX) { MinorOffsetInfo = left2.ToString() + " =>" + floor_1 + ",diff=" + diff; } else { MinorOffsetInfo = left2.ToString(); } //5. use PixelFarm's Agg to render to bitmap... //5.1 clear background painter.Clear(PixelFarm.Drawing.Color.White); if (FillBackGround) { //5.2 painter.FillColor = PixelFarm.Drawing.Color.Black; float xpos = 5;// - diff; if (OffsetMinorX) { xpos -= diff; } painter.SetOrigin(xpos, 10); painter.Fill(vxs); } if (DrawBorder) { //5.4 painter.StrokeColor = PixelFarm.Drawing.Color.Green; //user can specific border width here... //5.5 painter.Draw(vxs); //-------------- int markOnVertexNo = _infoView.DebugMarkVertexCommand; double x, y; vxs.GetVertex(markOnVertexNo, out x, out y); painter.FillRect(x, y, 4, 4, PixelFarm.Drawing.Color.Red); //-------------- _infoView.ShowFlatternBorderInfo(vxs); //-------------- } #if DEBUG builder.dbugAlwaysDoCurveAnalysis = false; #endif if (ShowTess) { RenderTessTesult(); } //if (DrawDynamicOutline) //{ // GlyphDynamicOutline dynamicOutline = builder.LatestGlyphFitOutline; // WalkDynamicOutline(painter, dynamicOutline, scale, DrawRegenerateOutline); //} }
GlyphBitmap GetGlyphBitmapFromColorOutlineGlyph(ushort glyphIndex, GlyphMeshStore glyphMeshStore, ushort colorLayerStart) { //not found=> create a newone Typography.OpenFont.Tables.COLR _colrTable = _typeface.COLRTable; Typography.OpenFont.Tables.CPAL _cpalTable = _typeface.CPALTable; Q1RectD totalBounds = Q1RectD.ZeroIntersection(); { //calculate bounds of this glyph ushort colorLayerCount = _colrTable.LayerCounts[glyphIndex]; for (int c = colorLayerStart; c < colorLayerStart + colorLayerCount; ++c) { BoundingRect.GetBoundingRect(glyphMeshStore.GetGlyphMesh(_colrTable.GlyphLayers[c]), ref totalBounds); } } //dbugExportCount++; var memBmp = new MemBitmap((int)Math.Round(totalBounds.Width), (int)Math.Round(totalBounds.Height));//??? int offset_x = 0; int offset_y = 0; using (Tools.BorrowAggPainter(memBmp, out AggPainter painter)) { painter.Clear(Color.Transparent); painter.SetOrigin(0, 0); offset_x = -(int)(totalBounds.Left); offset_y = -(int)(totalBounds.Bottom); ushort colorLayerCount = _colrTable.LayerCounts[glyphIndex]; int palette = 0; // FIXME: assume palette 0 for now for (int c = colorLayerStart; c < colorLayerStart + colorLayerCount; ++c) { _cpalTable.GetColor( _cpalTable.Palettes[palette] + _colrTable.GlyphPalettes[c], //index out byte r, out byte g, out byte b, out byte a); ushort gIndex = _colrTable.GlyphLayers[c]; VertexStore vxs = glyphMeshStore.GetGlyphMesh(gIndex); using (Tools.BorrowVxs(out var v1)) { vxs.TranslateToNewVxs(offset_x, offset_y, v1); painter.FillColor = new Color(r, g, b);//? a component painter.Fill(v1); } } //find ex #if DEBUG //memBmp.SaveImage("a0x" + (dbugExportCount) + ".png"); #endif } return(new GlyphBitmap { Bitmap = memBmp, Width = memBmp.Width, Height = memBmp.Height, ImageStartX = -offset_x, //offset back ImageStartY = -offset_y //offset back }); }
public GlyphImage CreateGlyphImage(GlyphPathBuilder builder, float pxscale) { //1. create var txToVxs = new GlyphTranslatorToVxs(); builder.ReadShapes(txToVxs); // //create new one var glyphVxs = new VertexStore(); txToVxs.WriteOutput(glyphVxs, pxscale); //find bound //-------------------------------------------- //GlyphImage glyphImg = new GlyphImage() RectD bounds = new RectD(); BoundingRect.GetBoundingRect(new VertexStoreSnap(glyphVxs), ref bounds); ////-------------------------------------------- int w = (int)System.Math.Ceiling(bounds.Width); int h = (int)System.Math.Ceiling(bounds.Height); if (w < 5) { w = 5; } if (h < 5) { h = 5; } ////translate to positive quadrant double dx = (bounds.Left < 0) ? -bounds.Left : 0; double dy = (bounds.Bottom < 0) ? -bounds.Bottom : 0; //we need some borders int horizontal_margin = 1; //'margin' 1px int vertical_margin = 1; //margin 1 px dx += horizontal_margin; //+ left margin dy += vertical_margin; //+ top margin //-------------------------------------------- //create glyph img w = (int)Math.Ceiling(dx + w + horizontal_margin); //+right margin h = (int)Math.Ceiling(dy + h + vertical_margin); //+bottom margin ActualImage img = new ActualImage(w, h, PixelFormat.ARGB32); AggRenderSurface aggsx = new AggRenderSurface(img); AggPainter painter = new AggPainter(aggsx); if (TextureKind == TextureKind.StencilLcdEffect) { VertexStore vxs2 = new VertexStore(); glyphVxs.TranslateToNewVxs(dx + 0.33f, dy, vxs2); //offset to proper x of subpixel rendering *** glyphVxs = vxs2; // painter.UseSubPixelLcdEffect = true; //we use white glyph on black bg for this texture painter.Clear(Color.Black); painter.FillColor = Color.White; painter.Fill(glyphVxs); //apply sharpen filter //painter.DoFilter(new RectInt(0, h, w, 0), 2); //painter.DoFilter(new RectInt(0, h, w, 0), 2); //? } else { VertexStore vxs2 = new VertexStore(); glyphVxs.TranslateToNewVxs(dx, dy, vxs2); glyphVxs = vxs2; painter.UseSubPixelLcdEffect = false; if (TextureKind == TextureKind.StencilGreyScale) { painter.Clear(Color.Empty); painter.FillColor = Color.Black; } else { painter.Clear(BackGroundColor); painter.FillColor = this.GlyphColor; } painter.Fill(glyphVxs); } // var glyphImage = new GlyphImage(w, h); glyphImage.TextureOffsetX = dx; glyphImage.TextureOffsetY = dy; glyphImage.SetImageBuffer(ActualImageExtensions.CopyImgBuffer(img, w), false); //copy data from agg canvas to glyph image return(glyphImage); }