public void SetCurrentTypeface(Typeface typeface) { _currentTypeface = typeface; if (_cacheGlyphPathBuilders.TryGetValue(typeface, out _bitmapList)) { return; } //TODO: you can scale down to proper img size //or create a single texture atlas. //if not create a new one _bitmapList = new GlyphBitmapList(); _cacheGlyphPathBuilders.Add(typeface, _bitmapList); int glyphCount = typeface.GlyphCount; System.Text.StringBuilder stbuilder = new System.Text.StringBuilder(); for (ushort i = 0; i < glyphCount; ++i) { stbuilder.Length = 0;//reset Glyph glyph = typeface.GetGlyphByIndex(i); typeface.ReadSvgContent(glyph, stbuilder); //create bitmap from svg GlyphBitmap glyphBitmap = new GlyphBitmap(); glyphBitmap.Width = glyph.MaxX - glyph.MinX; glyphBitmap.Height = glyph.MaxY - glyph.MinY; if (glyphBitmap.Width == 0 || glyphBitmap.Height == 0) { continue; } glyphBitmap.Bitmap = _svgBmpBuilderFunc(stbuilder);// ParseAndRenderSvg(stbuilder, vgDocHost); if (glyphBitmap.Bitmap == null) { continue; } // //MemBitmapExtensions.SaveImage(glyphBitmap.Bitmap, "d:\\WImageTest\\testGlyphBmp_" + i + ".png"); _bitmapList.RegisterBitmap(glyph.GlyphIndex, glyphBitmap); } }
public void SetCurrentTypeface(Typeface typeface) { _currentTypeface = typeface; if (_cacheGlyphPathBuilders.TryGetValue(typeface, out _bitmapList)) { return; } //TODO: you can scale down to proper img size //or create a single texture atlas. //if not create a new one _bitmapList = new GlyphBitmapList(); _cacheGlyphPathBuilders.Add(typeface, _bitmapList); int glyphCount = typeface.GlyphCount; using (System.IO.MemoryStream ms = new System.IO.MemoryStream()) { for (ushort i = 0; i < glyphCount; ++i) { ms.SetLength(0); Glyph glyph = typeface.GetGlyphByIndex(i); typeface.ReadBitmapContent(glyph, ms); GlyphBitmap glyphBitmap = new GlyphBitmap(); glyphBitmap.Width = glyph.MaxX - glyph.MinX; glyphBitmap.Height = glyph.MaxY - glyph.MinY; //glyphBitmap.Bitmap = ... glyphBitmap.Bitmap = MemBitmap.LoadBitmap(ms); //MemBitmapExtensions.SaveImage(glyphBitmap.Bitmap, "d:\\WImageTest\\testGlyphBmp_" + i + ".png"); _bitmapList.RegisterBitmap(glyph.GlyphIndex, glyphBitmap); } } }
public void RegisterBitmap(ushort glyphIndex, GlyphBitmap bmp) { _dic.Add(glyphIndex, bmp); }
public bool TryGetBitmap(ushort glyphIndex, out GlyphBitmap bmp) { return(_dic.TryGetValue(glyphIndex, out bmp)); }
public override void DrawFromGlyphPlans(GlyphPlanSequence seq, int startAt, int len, float left, float top) { if (StartDrawOnLeftTop) { //version 2 //offset y down top += this.FontLineSpacingPx; } float fontSizePoint = this.FontSizeInPoints; float scale = _currentTypeface.CalculateScaleToPixelFromPointSize(fontSizePoint); //4. render each glyph float ox = _painter.OriginX; float oy = _painter.OriginY; Typography.OpenFont.Tables.COLR colrTable = _currentTypeface.COLRTable; Typography.OpenFont.Tables.CPAL cpalTable = _currentTypeface.CPALTable; bool hasColorGlyphs = (colrTable != null) && (cpalTable != null); //--------------------------------------------------- _glyphMeshStore.SetHintTechnique(this.HintTechnique); _glyphMeshStore.SetFont(_currentTypeface, fontSizePoint); _glyphMeshStore.SimulateOblique = this.SimulateSlant; //--------------------------------------------------- if (_currentTypeface.HasSvgTable()) { _glyphSvgStore.SetCurrentTypeface(_currentTypeface); int seqLen = seq.Count; if (len > seqLen) { len = seqLen; } var snapToPx = new GlyphPlanSequenceSnapPixelScaleLayout(seq, startAt, len, scale); while (snapToPx.Read()) { _painter.SetOrigin((float)Math.Round(left + snapToPx.ExactX) + 0.33f, (float)Math.Floor(top + snapToPx.ExactY)); GlyphBitmap glyphBmp = _glyphSvgStore.GetGlyphBitmap(snapToPx.CurrentGlyphIndex); //how to draw the image //1. if (glyphBmp != null) { _painter.DrawImage(glyphBmp.Bitmap); } } } else if (_currentTypeface.IsBitmapFont) { //check if we have exported all the glyph bitmap //to some 'ready' form? //if not then create it _glyphBitmapStore.SetCurrentTypeface(_currentTypeface); int seqLen = seq.Count; if (len > seqLen) { len = seqLen; } var snapToPx = new GlyphPlanSequenceSnapPixelScaleLayout(seq, startAt, len, scale); while (snapToPx.Read()) { _painter.SetOrigin((float)Math.Round(left + snapToPx.ExactX) + 0.33f, (float)Math.Floor(top + snapToPx.ExactY)); GlyphBitmap glyphBmp = _glyphBitmapStore.GetGlyphBitmap(snapToPx.CurrentGlyphIndex); //how to draw the image //1. _painter.DrawImage(glyphBmp.Bitmap); } } else { if (!hasColorGlyphs) { bool savedUseLcdMode = _painter.UseSubPixelLcdEffect; //save,restore later RenderQuality savedRederQuality = _painter.RenderQuality; _painter.RenderQuality = RenderQuality.HighQuality; _painter.UseSubPixelLcdEffect = true; int seqLen = seq.Count; if (len > seqLen) { len = seqLen; } var snapToPx = new GlyphPlanSequenceSnapPixelScaleLayout(seq, startAt, len, scale); while (snapToPx.Read()) { _painter.SetOrigin((float)Math.Round(left + snapToPx.ExactX) + 0.33f, (float)Math.Floor(top + snapToPx.ExactY)); _painter.Fill(_glyphMeshStore.GetGlyphMesh(snapToPx.CurrentGlyphIndex)); } //restore _painter.RenderQuality = savedRederQuality; _painter.UseSubPixelLcdEffect = savedUseLcdMode; } else { //------------- //this glyph has color information //------------- Color originalFillColor = _painter.FillColor; int seqLen = seq.Count; if (len > seqLen) { len = seqLen; } var snapToPx = new GlyphPlanSequenceSnapPixelScaleLayout(seq, startAt, len, scale); while (snapToPx.Read()) { _painter.SetOrigin((float)Math.Round(left + snapToPx.ExactX), (float)Math.Floor(top + snapToPx.ExactY)); ushort colorLayerStart; if (colrTable.LayerIndices.TryGetValue(snapToPx.CurrentGlyphIndex, out colorLayerStart)) { //TODO: optimize this //we found color info for this glyph ushort colorLayerCount = colrTable.LayerCounts[snapToPx.CurrentGlyphIndex]; byte r, g, b, a; for (int c = colorLayerStart; c < colorLayerStart + colorLayerCount; ++c) { ushort gIndex = colrTable.GlyphLayers[c]; int palette = 0; // FIXME: assume palette 0 for now cpalTable.GetColor( cpalTable.Palettes[palette] + colrTable.GlyphPalettes[c], //index out r, out g, out b, out a); //----------- _painter.FillColor = new Color(r, g, b);//? a component _painter.Fill(_glyphMeshStore.GetGlyphMesh(gIndex)); } } else { //----------------------------------- //TODO: review here *** //PERFORMANCE revisit here //if we have create a vxs we can cache it for later use? //----------------------------------- _painter.Fill(_glyphMeshStore.GetGlyphMesh(snapToPx.CurrentGlyphIndex)); } } _painter.FillColor = originalFillColor; //restore color } } //restore prev origin _painter.SetOrigin(ox, oy); }