public override void DrawFromGlyphPlans(GlyphPlanList glyphPlanList, int startAt, int len, float x, float y) { CanvasPainter canvasPainter = this.TargetCanvasPainter; //Typeface typeface = _glyphPathBuilder.Typeface; //3. layout glyphs with selected layout technique //TODO: review this again, we should use pixel? float fontSizePoint = this.FontSizeInPoints; float scale = _currentTypeface.CalculateScaleToPixelFromPointSize(fontSizePoint); //4. render each glyph float ox = canvasPainter.OriginX; float oy = canvasPainter.OriginY; int endBefore = startAt + len; Typography.OpenFont.Tables.COLR colrTable = _currentTypeface.COLRTable; Typography.OpenFont.Tables.CPAL cpalTable = _currentTypeface.CPALTable; bool hasColorGlyphs = (colrTable != null) && (cpalTable != null); //--------------------------------------------------- _glyphMeshStore.SetFont(_currentTypeface, fontSizePoint); //--------------------------------------------------- float g_x = 0; float g_y = 0; float baseY = (int)y; if (!hasColorGlyphs) { for (int i = startAt; i < endBefore; ++i) { //----------------------------------- //TODO: review here *** //PERFORMANCE revisit here //if we have create a vxs we can cache it for later use? //----------------------------------- GlyphPlan glyphPlan = glyphPlanList[i]; g_x = glyphPlan.ExactX + x; g_y = glyphPlan.ExactY + y; canvasPainter.SetOrigin(g_x, g_y); //----------------------------------- canvasPainter.Fill(_glyphMeshStore.GetGlyphMesh(glyphPlan.glyphIndex)); } } else { //------------- //this glyph has color information //------------- Color originalFillColor = canvasPainter.FillColor; for (int i = startAt; i < endBefore; ++i) { GlyphPlan glyphPlan = glyphPlanList[i]; g_x = glyphPlan.ExactX + x; g_y = glyphPlan.ExactY + y; canvasPainter.SetOrigin(g_x, g_y); //----------------------------------- ushort colorLayerStart; if (colrTable.LayerIndices.TryGetValue(glyphPlan.glyphIndex, out colorLayerStart)) { //TODO: optimize this //we found color info for this glyph ushort colorLayerCount = colrTable.LayerCounts[glyphPlan.glyphIndex]; 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); //----------- canvasPainter.FillColor = new Color(r, g, b);//? a component canvasPainter.Fill(_glyphMeshStore.GetGlyphMesh(gIndex)); } } else { //----------------------------------- //TODO: review here *** //PERFORMANCE revisit here //if we have create a vxs we can cache it for later use? //----------------------------------- canvasPainter.Fill(_glyphMeshStore.GetGlyphMesh(glyphPlan.glyphIndex)); } } canvasPainter.FillColor = originalFillColor; //restore color } //restore prev origin canvasPainter.SetOrigin(ox, oy); }
public override void DrawFromGlyphPlans(GlyphPlanList glyphPlanList, int startAt, int len, float x, float y) { Painter painter = this.TargetCanvasPainter; if (StartDrawOnLeftTop) { //version 2 //offset y down y += this.FontLineSpacingPx; } //Typeface typeface = _glyphPathBuilder.Typeface; //3. layout glyphs with selected layout technique //TODO: review this again, we should use pixel? float fontSizePoint = this.FontSizeInPoints; float scale = _currentTypeface.CalculateScaleToPixelFromPointSize(fontSizePoint); //4. render each glyph float ox = painter.OriginX; float oy = painter.OriginY; int endBefore = startAt + len; Typography.OpenFont.Tables.COLR colrTable = _currentTypeface.COLRTable; Typography.OpenFont.Tables.CPAL cpalTable = _currentTypeface.CPALTable; bool hasColorGlyphs = (colrTable != null) && (cpalTable != null); //--------------------------------------------------- _glyphMeshStore.SetFont(_currentTypeface, fontSizePoint); //--------------------------------------------------- float g_x = 0; float g_y = 0; float baseY = (int)y; if (!hasColorGlyphs) { bool savedUseLcdMode = painter.UseSubPixelLcdEffect; //save,restore later RenderQualtity savedRederQuality = painter.RenderQuality; painter.RenderQuality = RenderQualtity.HighQuality; painter.UseSubPixelLcdEffect = true; for (int i = startAt; i < endBefore; ++i) { //----------------------------------- //TODO: review here *** //PERFORMANCE revisit here //if we have create a vxs we can cache it for later use? //----------------------------------- GlyphPlan glyphPlan = glyphPlanList[i]; g_x = glyphPlan.ExactX + x; g_y = glyphPlan.ExactY + y; painter.SetOrigin(g_x, g_y); //----------------------------------- //invert each glyph //version 3: painter.Fill(_glyphMeshStore.GetGlyphMesh(glyphPlan.glyphIndex)); //version2; //VertexStore vsx = _glyphMeshStore.GetGlyphMesh(glyphPlan.glyphIndex); //_vxs1 = _invertY.TransformToVxs(vsx, _vxs1); //painter.Fill(_vxs1); //_vxs1.Clear(); //version1 //painter.Fill(_glyphMeshStore.GetGlyphMesh(glyphPlan.glyphIndex)); } //restore painter.RenderQuality = savedRederQuality; painter.UseSubPixelLcdEffect = savedUseLcdMode; } else { //------------- //this glyph has color information //------------- Color originalFillColor = painter.FillColor; for (int i = startAt; i < endBefore; ++i) { GlyphPlan glyphPlan = glyphPlanList[i]; g_x = glyphPlan.ExactX + x; g_y = glyphPlan.ExactY + y; painter.SetOrigin(g_x, g_y); //----------------------------------- ushort colorLayerStart; if (colrTable.LayerIndices.TryGetValue(glyphPlan.glyphIndex, out colorLayerStart)) { //TODO: optimize this //we found color info for this glyph ushort colorLayerCount = colrTable.LayerCounts[glyphPlan.glyphIndex]; 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(glyphPlan.glyphIndex)); } } painter.FillColor = originalFillColor; //restore color } //restore prev origin painter.SetOrigin(ox, oy); }
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); }
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 }); }