protected override void OnFontSizeChanged() { //update some font matrix property if (_currentTypeface != null) { float pointToPixelScale = _currentTypeface.CalculateFromPointToPixelScale(this.FontSizeInPoints); this.FontAscendingPx = _currentTypeface.Ascender * pointToPixelScale; this.FontDescedingPx = _currentTypeface.Descender * pointToPixelScale; this.FontLineGapPx = _currentTypeface.LineGap * pointToPixelScale; this.FontLineSpacingPx = FontAscendingPx - FontDescedingPx + FontLineGapPx; } }
public ManagedActualFont(ManagedFontFace ownerFace, float sizeInPoints, FontStyle style) { this.ownerFace = ownerFace; this.sizeInPoints = sizeInPoints; this.style = style; this.typeFace = ownerFace.Typeface; //calculate scale *** scale = typeFace.CalculateFromPointToPixelScale(sizeInPoints); }
public override void DrawGlyphPlanList(List <GlyphPlan> glyphPlanList, int startAt, int len, float xpos, float ypos) { 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 = typeface.CalculateFromPointToPixelScale(fontSizePoint); //4. render each glyph float ox = canvasPainter.OriginX; float oy = canvasPainter.OriginY; int endBefore = startAt + len; //--------------------------------------------------- //consider use cached glyph, to increase performance hintGlyphCollection.SetCacheInfo(typeface, fontSizePoint, this.HintTechnique); //--------------------------------------------------- for (int i = startAt; i < endBefore; ++i) { GlyphPlan glyphPlan = glyphPlanList[i]; //----------------------------------- //TODO: review here *** //PERFORMANCE revisit here //if we have create a vxs we can cache it for later use? //----------------------------------- VertexStore glyphVxs; if (!hintGlyphCollection.TryGetCacheGlyph(glyphPlan.glyphIndex, out glyphVxs)) { //if not found then create new glyph vxs and cache it _glyphPathBuilder.BuildFromGlyphIndex(glyphPlan.glyphIndex, fontSizePoint); //----------------------------------- _tovxs.Reset(); _glyphPathBuilder.ReadShapes(_tovxs); //TODO: review here, //float pxScale = _glyphPathBuilder.GetPixelScale(); glyphVxs = new VertexStore(); _tovxs.WriteOutput(glyphVxs, _vxsPool); // hintGlyphCollection.RegisterCachedGlyph(glyphPlan.glyphIndex, glyphVxs); } canvasPainter.SetOrigin((float)(glyphPlan.x * scale + xpos), (float)(glyphPlan.y * scale + ypos)); canvasPainter.Fill(glyphVxs); } //restore prev origin canvasPainter.SetOrigin(ox, oy); }
void Build(ushort glyphIndex, Glyph glyph) { //------------------------------------------- //1. start with original points/contours from glyph this._outputGlyphPoints = glyph.GlyphPoints; this._outputContours = glyph.EndPoints; //------------------------------------------- Typeface currentTypeFace = this._typeface; _recentPixelScale = currentTypeFace.CalculateFromPointToPixelScale(SizeInPoints); //*** _useAutoHint = false; //reset //------------------------------------------- //2. process glyph points if (UseTrueTypeInstructions && currentTypeFace.HasPrepProgramBuffer && glyph.HasGlyphInstructions) { _trueTypeInterpreter.UseVerticalHinting = this.UseVerticalHinting; //output as points, this._outputGlyphPoints = _trueTypeInterpreter.HintGlyph(glyphIndex, SizeInPoints); //all points are scaled from _trueTypeInterpreter, //so not need further scale.=> set _recentPixelScale=1 _recentPixelScale = 1; } else { //not use interperter so we need to scale it with our machnism //this demonstrate our auto hint engine *** //you can change this to your own hint engine*** if (this.UseVerticalHinting) { _useAutoHint = true; if (!_fitoutlineCollection.TryGetValue(glyphIndex, out _fitOutline)) { _fitOutline = _fitShapeAnalyzer.Analyze( this._outputGlyphPoints, this._outputContours); _fitoutlineCollection.Add(glyphIndex, _fitOutline); } } } }
List <ushort> inputGlyphs = new List <ushort>(); //not thread safe*** public void Print(Typeface typeface, float size, char[] str, List <GlyphPlan> glyphPlanBuffer) { //1. layout _glyphLayout.Layout(typeface, size, str, glyphPlanBuffer); var glyphPathBuilder = new MyGlyphPathBuilder(typeface); int j = glyphPlanBuffer.Count; float pxScale = typeface.CalculateFromPointToPixelScale(size); for (int i = 0; i < j; ++i) { GlyphPlan glyphPlan = glyphPlanBuffer[i]; //----------------------------------- //check if we static vxs/bmp for this glyph //if not, create and cache //----------------------------------- glyphPathBuilder.BuildFromGlyphIndex(glyphPlan.glyphIndex, size); //----------------------------------- var vxsBuilder = new GlyphPathBuilderVxs(); glyphPathBuilder.ReadShapes(vxsBuilder); glyphPlan.vxs = vxsBuilder.GetVxs(pxScale); } }
public float GetPixelScale() { return(_typeface.CalculateFromPointToPixelScale(SizeInPoints)); }
List <ushort> inputGlyphs = new List <ushort>(); //not thread safe*** public void Layout(Typeface typeface, float size, char[] str, List <GlyphPlan> glyphPlanBuffer) { //---------------------------------------------- //1. convert char[] to glyph[] //2. send to shaping engine //3. layout position of each glyph //---------------------------------------------- //check if we have created a glyph cache for the typeface GlyphsCache glyphCache; if (!_glyphCaches.TryGetValue(typeface, out glyphCache)) { //create new glyphCache = new GlyphsCache(typeface); _glyphCaches.Add(typeface, glyphCache); } //---------------------------------------------- int j = str.Length; inputGlyphs.Clear(); for (int i = 0; i < j; ++i) { //1. convert char[] to glyphIndex[] inputGlyphs.Add((ushort)typeface.LookupIndex(str[i])); } //---------------------------------------------- //glyph substitution if (j > 1) { GlyphSubStitution glyphSubstitution = new GlyphSubStitution(typeface, this.ScriptLang.shortname); glyphSubstitution.EnableLigation = this.EnableLigature; glyphSubstitution.DoSubstitution(inputGlyphs); } //---------------------------------------------- //glyph position j = inputGlyphs.Count; List <GlyphPos> glyphPositions = new List <GlyphPos>(j); for (int i = 0; i < j; ++i) { ushort glyIndex = inputGlyphs[i]; glyphPositions.Add(new GlyphPos( glyIndex, typeface.GetGlyphByIndex(glyIndex).GlyphClass, typeface.GetHAdvanceWidthFromGlyphIndex(glyIndex)) ); } PositionTecnhique posTech = this.PositionTechnique; if (j > 1 && posTech == PositionTecnhique.OpenFont) { GlyphSetPosition glyphSetPos = new GlyphSetPosition(typeface, ScriptLang.shortname); glyphSetPos.DoGlyphPosition(glyphPositions); } //-------------- float scale = typeface.CalculateFromPointToPixelScale(size); float cx = 0; float cy = 0; j = inputGlyphs.Count; for (int i = 0; i < j; ++i) { ushort glyIndex = inputGlyphs[i]; GlyphPlan glyphPlan = new GlyphPlan(glyIndex); glyphPlanBuffer.Add(glyphPlan); //this advWidth in font design unit float advWidth = typeface.GetHAdvanceWidthFromGlyphIndex(glyIndex) * scale; //---------------------------------- switch (posTech) { case PositionTecnhique.None: { glyphPlan.x = cx; glyphPlan.y = cy; glyphPlan.advX = advWidth; } break; case PositionTecnhique.OpenFont: { GlyphPos gpos_offset = glyphPositions[i]; glyphPlan.x = cx + (scale * gpos_offset.xoffset); glyphPlan.y = cy + (scale * gpos_offset.yoffset); glyphPlan.advX = advWidth; } break; case PositionTecnhique.Kerning: { glyphPlan.x = cx; glyphPlan.y = cy; glyphPlan.advX = advWidth; if (i > 0) { advWidth += typeface.GetKernDistance(glyphPlanBuffer[i - 1].glyphIndex, glyphPlanBuffer[i].glyphIndex) * scale; } } break; } cx += advWidth; } }
public override float GetScale(float pointSize) { return(typeface.CalculateFromPointToPixelScale(pointSize)); }