public void Set(GlyphPoint point)
 {
     Active  = true;
     OnCurve = point.OnCurve;
     X       = point.X;
     Y       = point.Y;
 }
		private static void LoadGlyph(Glyph glyph,int contourCount,FontParser parser,float range){
			
			// The contour count (tiny set):
			ushort[] endPointIndices=new ushort[contourCount];
			
			// Load each endpoint:
			for(int i=0;i<contourCount;i++){
				
				endPointIndices[i]=parser.ReadUInt16();
				
			}
			
			// How big is the instruction block?
			int instructionLength=parser.ReadUInt16();
			
			// And skip it!
			parser.Position+=instructionLength;
			
			// How many coordinates?
			int numberOfCoordinates=endPointIndices[endPointIndices.Length-1]+1;
			
			// Create the flag set:
			byte[] flags=new byte[numberOfCoordinates];
			
			// For each one..
			for (int i = 0; i < numberOfCoordinates;i++) {
				
				byte flag=parser.ReadByte();
				
				flags[i]=flag;
				
				// If bit 3 is set, we repeat this flag n times, where n is the next byte.
				if((flag&8)>0){
					int repeatCount = parser.ReadByte();
					
					for (int j = 0; j < repeatCount; j += 1) {
						i++;
						flags[i]=flag;
					}
				}
				
			}
			
			if (endPointIndices.Length > 0) {
				
				// X/Y coordinates are relative to the previous point, except for the first point which is relative to 0,0.
				if (numberOfCoordinates > 0){
					
					// Current coord:
					int coord=0;
					
					// Coord index:
					int coordIndex=0;
					
					// The coord set:
					float[] coords=new float[numberOfCoordinates*2];
					
					// Load X coords:
					for (int i = 0; i < numberOfCoordinates; i++) {
						byte flag = flags[i];
						
						coord = LoadGlyphCoordinate(parser,flag,coord,2,16);
						
						coords[coordIndex]=(float)coord/range;
						
						coordIndex+=2;
						
					}
					
					// Reset shared vars:
					coord=0;
					coordIndex=1;
					
					// Load Y coords:
					for (int i = 0; i < numberOfCoordinates; i++) {
						byte flag = flags[i];
						
						coord = LoadGlyphCoordinate(parser,flag,coord,4,32);
						
						coords[coordIndex]=(float)coord/range;
						
						coordIndex+=2;
						
					}
					
					int[] orderedEnds=new int[endPointIndices.Length];
					int currentEnd=0;
					
					for (int i = 0; i < numberOfCoordinates; i++) {
						
						// Grab the flag:
						byte flag=flags[i];
						
						// On curve flag - Control point otherwise:
						flag=(byte)(flag&1);
						
						// Last point of the current contour?
						
						// For each end point index (tiny set - better than hash):
						for(int e=endPointIndices.Length-1;e>=0;e--){
							
							if(endPointIndices[e]==i){
								
								orderedEnds[currentEnd]=i;
								
								currentEnd++;
								
								break;
							}
							
						}
						
						// Update the flag - it's now just a 1 or 0:
						flags[i]=flag;
						
					}
					
					// Reset shared index again:
					coordIndex=0;
					
					// Create our temp holders of point info:
					GlyphPoint firstPointRaw=new GlyphPoint(flags,coords);
					GlyphPoint lastPointRaw=new GlyphPoint(flags,coords);
					GlyphPoint prevPointRaw=new GlyphPoint(flags,coords);
					GlyphPoint currentPointRaw=new GlyphPoint(flags,coords);
					GlyphPoint controlPoint=new GlyphPoint(flags,coords);
					
					// For each contour..
					for(int i=0;i<contourCount;i++){
						
						int pointOffset=0;
						
						// Get the indices of the first/last points on this contour.
						int firstIndex=0;
						int lastIndex=orderedEnds[i];
						
						if(i!=0){
							firstIndex=orderedEnds[i-1]+1;
						}
						
						GlyphPoint firstPoint=firstPointRaw;
						firstPoint.Set(firstIndex);
						
						GlyphPoint lastPoint=lastPointRaw;
						lastPoint.Set(lastIndex);
						
						if(firstPoint.OnCurve){
							
							// No control point:
							controlPoint.Active=false;
							
							// The first point will be consumed by the moveTo command so skip it:
							pointOffset=1;
							
						}else{
							
							if(lastPoint.OnCurve){
								
								// If the first point is off-curve and the last point is on-curve,
								// start at the last point.
								firstPoint=lastPoint;
								
							}else{
								// If both first and last points are off-curve, start at their middle.
								
								firstPoint.X=(firstPoint.X+lastPoint.X)/2f;
								firstPoint.Y=(firstPoint.Y+lastPoint.Y)/2f;
								
							}
							
							controlPoint.Set(firstPoint);
							
						}
						
						glyph.MoveTo(firstPoint.X,firstPoint.Y);
						
						int contourStart=firstIndex+pointOffset;
						
						for(int j=contourStart;j<=lastIndex;j++){
							
							// Setup the previous point:
							GlyphPoint prevPoint;
							
							if(j==firstIndex){
								prevPoint=firstPoint;
							}else{
								prevPoint=prevPointRaw;
								prevPoint.Set(j-1);
							}
							
							// Setup the current point:
							GlyphPoint pt=currentPointRaw;
							pt.Set(j);
							
							if(prevPoint.OnCurve && pt.OnCurve) {
								
								// Just a line here:
								glyph.LineTo(pt.X,pt.Y);
								
							}else if (prevPoint.OnCurve && !pt.OnCurve){
								
								controlPoint.Set(pt);
								
							}else if(!prevPoint.OnCurve && !pt.OnCurve){
								
								float midPointX=(prevPoint.X+pt.X)/2f;
								float midPointY=(prevPoint.Y+pt.Y)/2f;
								
								glyph.QuadraticCurveTo(prevPoint.X,prevPoint.Y,midPointX,midPointY);
								controlPoint.Set(pt);
								
							}else if(!prevPoint.OnCurve && pt.OnCurve){
								
								// Previous point off-curve, this point on-curve.
								glyph.QuadraticCurveTo(controlPoint.X,controlPoint.Y,pt.X,pt.Y);
								
								controlPoint.Active=false;
								
							}
							
						}
						
						if(firstPoint!=lastPoint){
							// Close the path.
							
							if(controlPoint.Active){
								
								// Still got a spare control point:
								glyph.QuadraticCurveTo(controlPoint.X,controlPoint.Y,firstPoint.X,firstPoint.Y);
								
							}
							
							// Just a normal close:
							glyph.ClosePath();
							
						}
						
					}
					
				}
				
			}
			
			if(glyph.Font.WindingUnknown){
				// Find the winding now:
				glyph.Font.FindWinding(glyph);
			}
			
		}
//--------------------------------------
Exemple #4
0
        private static void LoadGlyph(Glyph glyph, int contourCount, FontParser parser, float range)
        {
            // The contour count (tiny set):
            ushort[] endPointIndices = new ushort[contourCount];

            // Load each endpoint:
            for (int i = 0; i < contourCount; i++)
            {
                endPointIndices[i] = parser.ReadUInt16();
            }

            // How big is the instruction block?
            int instructionLength = parser.ReadUInt16();

            // And skip it!
            parser.Position += instructionLength;

            // How many coordinates?
            int numberOfCoordinates = endPointIndices[endPointIndices.Length - 1] + 1;

            // Create the flag set:
            byte[] flags = new byte[numberOfCoordinates];

            // For each one..
            for (int i = 0; i < numberOfCoordinates; i++)
            {
                byte flag = parser.ReadByte();

                flags[i] = flag;

                // If bit 3 is set, we repeat this flag n times, where n is the next byte.
                if ((flag & 8) > 0)
                {
                    int repeatCount = parser.ReadByte();

                    for (int j = 0; j < repeatCount; j += 1)
                    {
                        i++;
                        flags[i] = flag;
                    }
                }
            }

            if (endPointIndices.Length > 0)
            {
                // X/Y coordinates are relative to the previous point, except for the first point which is relative to 0,0.
                if (numberOfCoordinates > 0)
                {
                    // Current coord:
                    int coord = 0;

                    // Coord index:
                    int coordIndex = 0;

                    // The coord set:
                    float[] coords = new float[numberOfCoordinates * 2];

                    // Load X coords:
                    for (int i = 0; i < numberOfCoordinates; i++)
                    {
                        byte flag = flags[i];

                        coord = LoadGlyphCoordinate(parser, flag, coord, 2, 16);

                        coords[coordIndex] = (float)coord / range;

                        coordIndex += 2;
                    }

                    // Reset shared vars:
                    coord      = 0;
                    coordIndex = 1;

                    // Load Y coords:
                    for (int i = 0; i < numberOfCoordinates; i++)
                    {
                        byte flag = flags[i];

                        coord = LoadGlyphCoordinate(parser, flag, coord, 4, 32);

                        coords[coordIndex] = (float)coord / range;

                        coordIndex += 2;
                    }

                    int[] orderedEnds = new int[endPointIndices.Length];
                    int   currentEnd  = 0;

                    for (int i = 0; i < numberOfCoordinates; i++)
                    {
                        // Grab the flag:
                        byte flag = flags[i];

                        // On curve flag - Control point otherwise:
                        flag = (byte)(flag & 1);

                        // Last point of the current contour?

                        // For each end point index (tiny set - better than hash):
                        for (int e = endPointIndices.Length - 1; e >= 0; e--)
                        {
                            if (endPointIndices[e] == i)
                            {
                                orderedEnds[currentEnd] = i;

                                currentEnd++;

                                break;
                            }
                        }

                        // Update the flag - it's now just a 1 or 0:
                        flags[i] = flag;
                    }

                    // Reset shared index again:
                    coordIndex = 0;

                    // Create our temp holders of point info:
                    GlyphPoint firstPointRaw   = new GlyphPoint(flags, coords);
                    GlyphPoint lastPointRaw    = new GlyphPoint(flags, coords);
                    GlyphPoint prevPointRaw    = new GlyphPoint(flags, coords);
                    GlyphPoint currentPointRaw = new GlyphPoint(flags, coords);
                    GlyphPoint controlPoint    = new GlyphPoint(flags, coords);

                    // For each contour..
                    for (int i = 0; i < contourCount; i++)
                    {
                        int pointOffset = 0;

                        // Get the indices of the first/last points on this contour.
                        int firstIndex = 0;
                        int lastIndex  = orderedEnds[i];

                        if (i != 0)
                        {
                            firstIndex = orderedEnds[i - 1] + 1;
                        }

                        GlyphPoint firstPoint = firstPointRaw;
                        firstPoint.Set(firstIndex);

                        GlyphPoint lastPoint = lastPointRaw;
                        lastPoint.Set(lastIndex);

                        if (firstPoint.OnCurve)
                        {
                            // No control point:
                            controlPoint.Active = false;

                            // The first point will be consumed by the moveTo command so skip it:
                            pointOffset = 1;
                        }
                        else
                        {
                            if (lastPoint.OnCurve)
                            {
                                // If the first point is off-curve and the last point is on-curve,
                                // start at the last point.
                                firstPoint = lastPoint;
                            }
                            else
                            {
                                // If both first and last points are off-curve, start at their middle.

                                firstPoint.X = (firstPoint.X + lastPoint.X) / 2f;
                                firstPoint.Y = (firstPoint.Y + lastPoint.Y) / 2f;
                            }

                            controlPoint.Set(firstPoint);
                        }

                        glyph.MoveTo(firstPoint.X, firstPoint.Y);

                        int contourStart = firstIndex + pointOffset;

                        for (int j = contourStart; j <= lastIndex; j++)
                        {
                            // Setup the previous point:
                            GlyphPoint prevPoint;

                            if (j == firstIndex)
                            {
                                prevPoint = firstPoint;
                            }
                            else
                            {
                                prevPoint = prevPointRaw;
                                prevPoint.Set(j - 1);
                            }

                            // Setup the current point:
                            GlyphPoint pt = currentPointRaw;
                            pt.Set(j);

                            if (prevPoint.OnCurve && pt.OnCurve)
                            {
                                // Just a line here:
                                glyph.LineTo(pt.X, pt.Y);
                            }
                            else if (prevPoint.OnCurve && !pt.OnCurve)
                            {
                                controlPoint.Set(pt);
                            }
                            else if (!prevPoint.OnCurve && !pt.OnCurve)
                            {
                                float midPointX = (prevPoint.X + pt.X) / 2f;
                                float midPointY = (prevPoint.Y + pt.Y) / 2f;

                                glyph.QuadraticCurveTo(prevPoint.X, prevPoint.Y, midPointX, midPointY);
                                controlPoint.Set(pt);
                            }
                            else if (!prevPoint.OnCurve && pt.OnCurve)
                            {
                                // Previous point off-curve, this point on-curve.
                                glyph.QuadraticCurveTo(controlPoint.X, controlPoint.Y, pt.X, pt.Y);

                                controlPoint.Active = false;
                            }
                        }

                        if (firstPoint != lastPoint)
                        {
                            // Close the path.

                            if (controlPoint.Active)
                            {
                                // Still got a spare control point:
                                glyph.QuadraticCurveTo(controlPoint.X, controlPoint.Y, firstPoint.X, firstPoint.Y);
                            }

                            // Just a normal close:
                            glyph.ClosePath();
                        }
                    }
                }
            }

            if (glyph.Font.WindingUnknown)
            {
                // Find the winding now:
                glyph.Font.FindWinding(glyph);
            }
        }