//experiment /// <summary> /// build a multi-layer glyph (eg. Emoji) /// </summary> /// <param name="builder"></param> /// <param name="glyphIndex"></param> /// <param name="sizeInPoints"></param> /// <param name="tx"></param> public static void BuildFromGlyphIndex(this GlyphOutlineBuilderBase builder, ushort glyphIndex, float sizeInPoints, IMultiLayerGlyphTranslator tx) { //1. current typeface support multilayer or not if (builder.HasColorInfo) { Typeface typeface = builder.Typeface; COLR colrTable = typeface.COLRTable; CPAL cpalTable = typeface.CPALTable; if (colrTable.LayerIndices.TryGetValue(glyphIndex, out ushort colorLayerStart)) { //has color information on this glyphIndex ushort colorLayerCount = colrTable.LayerCounts[glyphIndex]; tx.HasColorInfo(colorLayerCount); for (int c = colorLayerStart; c < colorLayerStart + colorLayerCount; ++c) { ushort gIndex = colrTable.GlyphLayers[c]; tx.BeginSubGlyph(gIndex); //BEGIN SUB GLYPH int palette = 0; // FIXME: assume palette 0 for now cpalTable.GetColor( cpalTable.Palettes[palette] + colrTable.GlyphPalettes[c], //index out byte r, out byte g, out byte b, out byte a); tx.SetFillColor(r, g, b, a); //SET COLOR builder.BuildFromGlyphIndex(glyphIndex, sizeInPoints); builder.ReadShapes(tx); tx.EndSubGlyph(gIndex);//END SUB GLYPH } } else { //build as normal glyph builder.BuildFromGlyphIndex(glyphIndex, sizeInPoints); tx.HasColorInfo(0); builder.ReadShapes(tx); } } else { //build as normal glyph builder.BuildFromGlyphIndex(glyphIndex, sizeInPoints); tx.HasColorInfo(0); builder.ReadShapes(tx); } }
} // End Function GetExistingOrCreateGraphicsPath // public override void DrawFromGlyphPlans(GlyphPlanSequence glyphPlanList, int startAt, int len, float left, float top) public override void DrawFromGlyphPlans(GlyphPlanSequence seq, int startAt, int len, float x, float y) { UpdateVisualOutputSettings(); //draw data in glyph plan //3. render each glyph float sizeInPoints = this.FontSizeInPoints; float pxscale = _currentTypeface.CalculateScaleToPixelFromPointSize(sizeInPoints); Typeface typeface = this.Typeface; _glyphMeshCollections.SetCacheInfo(typeface, sizeInPoints, this.HintTechnique); //this draw a single line text span*** SvgGraphics g = this.TargetGraphics; float baseline = y; GlyphPlanSequenceSnapPixelScaleLayout snapToPxScale = new GlyphPlanSequenceSnapPixelScaleLayout(seq, startAt, len, pxscale); COLR colrTable = typeface.COLRTable; CPAL cpalTable = typeface.CPALTable; bool canUseColorGlyph = EnableColorGlyph && colrTable != null && cpalTable != null; while (snapToPxScale.Read()) { ushort glyphIndex = snapToPxScale.CurrentGlyphIndex; if (canUseColorGlyph && colrTable.LayerIndices.TryGetValue(glyphIndex, out ushort colorLayerStart)) { ushort colorLayerCount = colrTable.LayerCounts[glyphIndex]; for (int c = colorLayerStart; c < colorLayerStart + colorLayerCount; ++c) { SvgPath path = GetExistingOrCreateGraphicsPath(colrTable.GlyphLayers[c]); if (path == null) { #if DEBUG System.Diagnostics.Debug.WriteLine("gdi_printer: no path?"); #endif continue; } // End if (path == null) //then move pen point to the position we want to draw a glyph float cx = (float)System.Math.Round(snapToPxScale.ExactX + x); float cy = (float)System.Math.Floor(snapToPxScale.ExactY + baseline); int palette = 0; // FIXME: assume palette 0 for now cpalTable.GetColor( cpalTable.Palettes[palette] + colrTable.GlyphPalettes[c], //index out byte red, out byte green, out byte blue, out byte alpha); g.TranslateTransform(cx, cy); _fillBrush.Color = SvgColor.ToWebRgb(red, green, blue); if (FillBackground) { g.FillPath(_fillBrush, path); } if (DrawOutline) { g.DrawPath(_outlinePen, path); } // and then we reset back g.TranslateTransform(-cx, -cy); } // Next c } else { SvgPath path = GetExistingOrCreateGraphicsPath(glyphIndex); if (path == null) { #if DEBUG System.Diagnostics.Debug.WriteLine("gdi_printer: no path?"); #endif continue; } //------ //then move pen point to the position we want to draw a glyph float cx = (float)System.Math.Round(snapToPxScale.ExactX + x); float cy = (float)System.Math.Floor(snapToPxScale.ExactY + baseline); g.TranslateTransform(cx, cy); if (FillBackground) { g.FillPath(_fillBrush, path); } if (DrawOutline) { g.DrawPath(_outlinePen, path); } // and then we reset back g.TranslateTransform(-cx, -cy); } // End else } // Whend } // End Sub DrawFromGlyphPlans