/// <summary> /// always create new vxs for this glyph, no caching /// </summary> /// <param name="glyphIndex"></param> /// <returns></returns> public VertexStore GetNewUnFlattenVxs(ushort glyphIndex) { _currentGlyphBuilder.BuildFromGlyphIndex(glyphIndex, _currentFontSizeInPoints); DynamicOutline dynamicOutline = _currentGlyphBuilder.LatestGlyphFitOutline; //----------------------------------- _tovxs.Reset(); float pxscale = _currentTypeface.CalculateScaleToPixelFromPointSize(_currentFontSizeInPoints); if (dynamicOutline != null) { //TODO: review dynamic outline dynamicOutline.GenerateOutput(new ContourToGlyphTranslator(_tovxs), pxscale); //version 3 using (Tools.BorrowVxs(out var v1)) { _tovxs.WriteUnFlattenOutput(v1, 1); return(FlipGlyphUpward ? v1.CreateTrim(s_flipY) : v1.CreateTrim()); } } else { using (Tools.BorrowVxs(out var v1)) { _currentGlyphBuilder.ReadShapes(_tovxs); _tovxs.WriteUnFlattenOutput(v1, 1); //write to temp buffer first //then return(FlipGlyphUpward ? v1.CreateTrim(s_flipY) : v1.CreateTrim()); } } }
/// <summary> /// get glyph mesh from current font setting /// </summary> /// <param name="glyphIndex"></param> /// <returns></returns> public VertexStore GetGlyphMesh(ushort glyphIndex) { GlyphMeshData glyphMeshData = InternalGetGlyphMesh(glyphIndex); if (glyphMeshData.vxsStore == null) { //build vxs _tovxs.Reset(); float pxscale = _currentTypeface.CalculateScaleToPixelFromPointSize(_currentFontSizeInPoints); GlyphDynamicOutline dynamicOutline = glyphMeshData.dynamicOutline; if (dynamicOutline != null) { dynamicOutline.GenerateOutput(_tovxs, pxscale); //version 3 if (_flipGlyphUpward) { _vxs1.Clear(); //write to temp buffer first _tovxs.WriteOutput(_vxs1); VertexStore vxs = new VertexStore(); PixelFarm.Agg.VertexStoreTransformExtensions.TransformToVxs(_invertY, _vxs1, vxs); //then glyphMeshData.vxsStore = vxs; } else { glyphMeshData.vxsStore = new VertexStore(); _tovxs.WriteOutput(glyphMeshData.vxsStore); } } else { if (_flipGlyphUpward) { _vxs1.Clear(); //write to temp buffer first _currentGlyphBuilder.ReadShapes(_tovxs); _tovxs.WriteOutput(_vxs1); VertexStore vxs = new VertexStore(); PixelFarm.Agg.VertexStoreTransformExtensions.TransformToVxs(_invertY, _vxs1, vxs); //then glyphMeshData.vxsStore = vxs; } else { //no dynamic outline _currentGlyphBuilder.ReadShapes(_tovxs); //TODO: review here, //float pxScale = _glyphPathBuilder.GetPixelScale(); glyphMeshData.vxsStore = new VertexStore(); _tovxs.WriteOutput(glyphMeshData.vxsStore); } } } return(glyphMeshData.vxsStore); }
/// <summary> /// get glyph mesh from current font setting /// </summary> /// <param name="glyphIndex"></param> /// <returns></returns> public VertexStore GetGlyphMesh(ushort glyphIndex) { GlyphMeshData glyphMeshData = InternalGetGlyphMesh(glyphIndex); if (glyphMeshData.vxsStore == null) { //build vxs _tovxs.Reset(); float pxscale = _currentTypeface.CalculateScaleToPixelFromPointSize(_currentFontSizeInPoints); GlyphDynamicOutline dynamicOutline = glyphMeshData.dynamicOutline; if (dynamicOutline != null) { dynamicOutline.GenerateOutput(_tovxs, pxscale); glyphMeshData.vxsStore = new VertexStore(); _tovxs.WriteOutput(glyphMeshData.vxsStore, _vxsPool); } else { //no dynamic outline glyphMeshData.vxsStore = new VertexStore(); _currentGlyphBuilder.ReadShapes(_tovxs); //TODO: review here, //float pxScale = _glyphPathBuilder.GetPixelScale(); _tovxs.WriteOutput(glyphMeshData.vxsStore, _vxsPool); } } return(glyphMeshData.vxsStore); }
public GlyphImage CreateGlyphImage(GlyphPathBuilder builder, float pxscale) { _txToVxs.Reset(); //1. builder read shape and translate it with _txToVxs builder.ReadShapes(_txToVxs); using (VxsTemp.Borrow(out var glyphVxs, out var vxs2)) { //2. write translated data (in the _txToVxs) to glyphVxs _txToVxs.WriteOutput(glyphVxs, pxscale); RectD bounds = glyphVxs.GetBoundingRect(); //-------------------------------------------- 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; } //we need some margin int horizontal_margin = 1; int vertical_margin = 1; //translate to positive quadrant and use minimum space int dx = (int)Math.Ceiling((bounds.Left < 0) ? -bounds.Left : 0); int dy = 0; //vertical adjust =>since we need to move it, then move it with integer value if (bounds.Bottom < 0) { dy = (int)Math.Ceiling(-bounds.Bottom); } else if (bounds.Bottom > 0) { dy = (int)Math.Floor(-bounds.Bottom); } dx += horizontal_margin; //margin left dy += vertical_margin; //-------------------------------------------- w = dx + w + horizontal_margin; //+right margin h = vertical_margin + h + vertical_margin; //+bottom margin AggPainter painter = Painter; if (TextureKind == TextureKind.StencilLcdEffect) { glyphVxs.TranslateToNewVxs(dx + 0.33f, dy, vxs2); //offset to proper x of subpixel rendering *** glyphVxs = vxs2; RectD bounds2 = vxs2.GetBoundingRect(); if (w < bounds2.Right) { w = (int)Math.Ceiling(bounds2.Right); } // 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 { 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); } // if (w > painter.RenderSurface.DestBitmap.Width) { w = painter.RenderSurface.DestBitmap.Width; } if (h > painter.RenderSurface.DestBitmap.Height) { h = painter.RenderSurface.DestBitmap.Height; } var glyphImage = new GlyphImage(w, h); #if DEBUG if (dx < short.MinValue || dx > short.MaxValue) { throw new NotSupportedException(); } if (dy < short.MinValue || dy > short.MaxValue) { throw new NotSupportedException(); } #endif glyphImage.TextureOffsetX = (short)dx; glyphImage.TextureOffsetY = (short)dy; glyphImage.SetImageBuffer(MemBitmapExtensions.CopyImgBuffer(painter.RenderSurface.DestBitmap, w, h), false); //copy data from agg canvas to glyph image return(glyphImage); } }
/// <summary> /// get glyph mesh from current font setting /// </summary> /// <param name="glyphIndex"></param> /// <returns></returns> public VertexStore GetGlyphMesh(ushort glyphIndex) { GlyphMeshData glyphMeshData = InternalGetGlyphMesh(glyphIndex); if (glyphMeshData.vxsStore == null) { //build vxs _tovxs.Reset(); float pxscale = _currentTypeface.CalculateScaleToPixelFromPointSize(_currentFontSizeInPoints); GlyphDynamicOutline dynamicOutline = glyphMeshData.dynamicOutline; if (dynamicOutline != null) { dynamicOutline.GenerateOutput(_tovxs, pxscale); //version 3 if (FlipGlyphUpward) { using (VxsTemp.Borrow(out var v1)) { _tovxs.WriteOutput(v1); //write to temp buffer first //then glyphMeshData.vxsStore = v1.CreateTrim(_invertY);// _temp2.CreateTrim(); } } else { using (VxsTemp.Borrow(out var v1)) { _tovxs.WriteOutput(v1); glyphMeshData.vxsStore = v1.CreateTrim(); } } } else { if (FlipGlyphUpward) { using (VxsTemp.Borrow(out var v1)) { _currentGlyphBuilder.ReadShapes(_tovxs); _tovxs.WriteOutput(v1); //write to temp buffer first //then glyphMeshData.vxsStore = v1.CreateTrim(_invertY); } } else { //no dynamic outline using (VxsTemp.Borrow(out var v1)) { _currentGlyphBuilder.ReadShapes(_tovxs); //TODO: review here, //float pxScale = _glyphPathBuilder.GetPixelScale(); _tovxs.WriteOutput(v1); glyphMeshData.vxsStore = v1.CreateTrim(); } } } } if (SimulateOblique) { if (glyphMeshData._synthOblique == null) { //create italic version SimulateQbliqueGlyph(glyphMeshData); } return(glyphMeshData._synthOblique.vxsStore); } else { return(glyphMeshData.vxsStore); } }