/// <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); }
protected override void FitCurrentGlyph(Glyph glyph) { //not use interperter so we need to scale it with our mechanism //this demonstrate our auto hint engine *** //you can change this to your own hint engine*** _latestDynamicOutline = null;//reset if (this.UseTrueTypeInstructions) { base.FitCurrentGlyph(glyph); } else { // if (TemporaryDisableCustomFit) { return; } // if (this.UseVerticalHinting) { if (!_fitoutlineCollection.TryGetValue(glyph.GlyphIndex, out _latestDynamicOutline)) { //--------------------------------------------- //test code //GlyphContourBuilder contBuilder = new GlyphContourBuilder(); //contBuilder.Reset(); //int x = 100, y = 120, w = 700, h = 200; //contBuilder.MoveTo(x, y); //contBuilder.LineTo(x + w, y); //contBuilder.LineTo(x + w, y + h); //contBuilder.LineTo(x, y + h); //contBuilder.CloseFigure(); //--------------------------------------------- _latestDynamicOutline = _fitShapeAnalyzer.CreateDynamicOutline( _outputGlyphPoints, _outputContours); //add more information for later scaling process _latestDynamicOutline.OriginalAdvanceWidth = glyph.OriginalAdvanceWidth; _latestDynamicOutline.OriginalGlyphControlBounds = glyph.Bounds; //store to our dynamic outline collection //so we can reuse it _fitoutlineCollection.Add(glyph.GlyphIndex, _latestDynamicOutline); //------------------- // _latestDynamicOutline.GenerateOutput(null, Typeface.CalculateScaleToPixel(RecentFontSizeInPixels)); //------------------- } else { if (IsSizeChanged) { _latestDynamicOutline.GenerateOutput(null, Typeface.CalculateScaleToPixel(RecentFontSizeInPixels)); IsSizeChanged = false; } } } } }
/// <summary> /// get existing or create new one from current font setting /// </summary> /// <param name="glyphIndex"></param> /// <returns></returns> GlyphMeshData InternalGetGlyphMesh(ushort glyphIndex) { GlyphMeshData glyphMeshData; if (!_hintGlyphCollection.TryGetCacheGlyph(glyphIndex, out glyphMeshData)) { //if not found then create new glyph vxs and cache it _currentGlyphBuilder.SetHintTechnique(_currentHintTech); _currentGlyphBuilder.BuildFromGlyphIndex(glyphIndex, _currentFontSizeInPoints); GlyphDynamicOutline dynamicOutline = _currentGlyphBuilder.LatestGlyphFitOutline; //----------------------------------- glyphMeshData = new GlyphMeshData(); if (dynamicOutline != null) { //has dynamic outline data glyphMeshData.avgXOffsetToFit = dynamicOutline.AvgXFitOffset; glyphMeshData.orgBounds = dynamicOutline.OriginalGlyphControlBounds; glyphMeshData.dynamicOutline = dynamicOutline; } _hintGlyphCollection.RegisterCachedGlyph(glyphIndex, glyphMeshData); //----------------------------------- } return(glyphMeshData); }
/// <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); }
/// <summary> /// calculate and create GlyphFitOutline /// </summary> /// <param name="glyphPoints"></param> /// <param name="glyphContours"></param> /// <returns></returns> public GlyphDynamicOutline CreateDynamicOutline(GlyphPointF[] glyphPoints, ushort[] glyphContours) { //1. convert original glyph point to contour _glyphToContour.Read(glyphPoints, glyphContours); //2. get result as list of contour List <GlyphContour> contours = _glyphToContour.GetContours(); int cnt_count = contours.Count; // if (cnt_count > 0) { //3.before create dynamic contour we must flatten data inside the contour _glyphFlattener.NSteps = 2; for (int i = 0; i < cnt_count; ++i) { // (flatten each contour with the flattener) contours[i].Flatten(_glyphFlattener); } //4. after flatten, the we can create fit outline return(CreateDynamicOutline(contours)); } else { return(GlyphDynamicOutline.CreateBlankDynamicOutline()); } }
/// <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); } }
// public void Walk(GlyphDynamicOutline dynamicOutline) { #if DEBUG _dynamicOutline = dynamicOutline; int triNumber = 0; if (WalkTrianglesAndEdges) { foreach (GlyphTriangle tri in _dynamicOutline.dbugGetGlyphTriangles()) { float centroidX, centriodY; tri.CalculateCentroid(out centroidX, out centriodY); OnTriangle(triNumber++, tri.e0, tri.e1, tri.e2, centroidX, centriodY); } } //--------------- List <GlyphContour> contours = _dynamicOutline._contours; List <CentroidLineHub> centroidLineHubs = _dynamicOutline.dbugGetCentroidLineHubs(); foreach (CentroidLineHub lineHub in centroidLineHubs) { Dictionary <GlyphTriangle, CentroidLine> lines = lineHub.GetAllCentroidLines(); Vector2 hubCenter = lineHub.CalculateAvgHeadPosition(); OnBegingLineHub(hubCenter.X, hubCenter.Y); foreach (CentroidLine line in lines.Values) { List <GlyphBoneJoint> joints = line._joints; int pairCount = joints.Count; for (int i = 0; i < pairCount; ++i) { GlyphBoneJoint joint = joints[i]; if (WalkCentroidBone) { float px, py, qx, qy; joint.dbugGetCentroidBoneCenters(out px, out py, out qx, out qy); OnCentroidLine(px, py, qx, qy); //-------------------------------------------------- if (joint.TipEdgeP != null) { Vector2 pos = joint.TipPointP; OnCentroidLineTip_P(px, py, pos.X, pos.Y); } if (joint.TipEdgeQ != null) { Vector2 pos = joint.TipPointQ; OnCentroidLineTip_Q(qx, qy, pos.X, pos.Y); } } if (WalkGlyphBone) { OnBoneJoint(joint); } } if (WalkGlyphBone) { //draw bone list DrawBoneLinks(line); } } // OnEndLineHub(hubCenter.X, hubCenter.Y, lineHub.GetHeadConnectedJoint()); } //---------------- List <GlyphContour> cnts = _dynamicOutline._contours; int j = cnts.Count; for (int i = 0; i < j; ++i) { GlyphContour cnt = cnts[i]; List <GlyphPoint> points = cnt.flattenPoints; int n = points.Count; for (int m = 0; m < n; ++m) { OnGlyphEdgeN(points[m].E0); } } #endif }