示例#1
0
		/**
		 * create a set of attributes.
		 * this calculates all of the glyph metrics from the graphic device.
		 */
		public StretchyGlyphAttributes(IFormattingContext context, IFontHandle fontHandle, ref StretchyGlyphIndices indices)
		{
			orientation = indices.Orientation;

			if(indices.SimpleIndices != null)
			{
				simpleGlyphs = new GlyphAttributes[indices.SimpleIndices.Length];
				for(int i = 0; i < simpleGlyphs.Length; i++)
				{
					simpleGlyphs[i] = new GlyphAttributes(context, fontHandle, 
						indices.SimpleIndices[i], GlyphAttributes.FudgeNone);
				}
			} 
			else
			{
				simpleGlyphs = null;
			}

			if(indices.CompoundIndices != null)
			{
				compoundGlyphs = new GlyphAttributes[indices.CompoundIndices.Length];
				for(int i = 0; i < compoundGlyphs.Length; i++)
				{
					// TODO deal with horizontal glyphs
					compoundGlyphs[i] = new GlyphAttributes(context, fontHandle, 
						indices.CompoundIndices[i], 
						i == StretchyGlyphIndices.Filler ? GlyphAttributes.FudgeHeight : GlyphAttributes.FudgeNone);
				}
			}
			else
			{
				compoundGlyphs = null;
			}
		}
示例#2
0
		/**
		 * set the attributes, but do not actually create a glyph 
		 * area.
		 * @param fontHandle a handle to a native font resource
		 * @param charIndex the index in the font of the desired glyph
		 * @param stretchyType if this glyph is a repeated section in a
		 *		  stretchy glyph, shrink the reported metrics by one, so
		 *		  we get a nice overlap.
		 */
    public GlyphAttributes(IFormattingContext context, IFontHandle fontHandle, short charIndex, int fudge)
		{
			Index = charIndex;
			glyphArea = null;
			float tmp;

			if(charIndex >= 0)
			{
				context.MeasureGlyph(fontHandle, (ushort)charIndex, out Box, 
					out Left, out Right);

				if(fudge == FudgeWidth)
				{
					Box.Width -= 2 * fudgeFactor;
				}
				else if(fudge == FudgeHeight)
				{
					if((tmp = Box.Height - fudgeFactor) >= 0.0f) Box.Height = tmp;
					if((tmp = Box.Depth - fudgeFactor) >= 0.0f) Box.Depth = tmp;
				}
			}
			else
			{
				Box = new BoundingBox();
				Left = 0;
				Right = 0;
			}
		}
示例#3
0
		public GlyphArea(IFontHandle fontHandle, ref GlyphAttributes attributes)
		{
			this.font = fontHandle;
			this.leftEdge = attributes.Left;
			this.rightEdge = attributes.Right;
			this.box = attributes.Box;
			this.index = (ushort)attributes.Index;
		}
示例#4
0
      public Area GetArea(IFormattingContext context, IFontHandle fontHandle, char c)
		{
			Area result = null;
			ushort glyphIndex = (ushort)(c + offset);
      if (glyphIndex >= first && glyphIndex <= last)
			{
				result = new GlyphArea(context, fontHandle, glyphIndex);
			}
			return result;
		}
示例#5
0
    public FontInstance(IFormattingContext context, string fontName, float pointSize, StretchyGlyphIndices[] glyphIndices)
		{
			cachedAreas = null;
			PointSize = pointSize;
			FontHandle = context.CreateFont(pointSize, false, 500, fontName);
			stretchyAttributes = new StretchyGlyphAttributes[glyphIndices.Length];
			for(int i = 0; i < stretchyAttributes.Length; i++)
			{
				stretchyAttributes[i] = new StretchyGlyphAttributes(
					context, FontHandle, ref glyphIndices[i]);
			}
		}
示例#6
0
        private Area[] StretchBottom(IFontHandle fontHandle, BoundingBox box)
        {
            Area[] result;
            Area   filler     = compoundGlyphs[StretchyGlyphIndices.Filler].GetGlyph(fontHandle);
            float  availSpace = (orientation == StretchyOrientation.Vertical ?
                                 box.VerticalExtent - compoundGlyphs[StretchyGlyphIndices.Bottom].Box.VerticalExtent :
                                 box.Width = compoundGlyphs[StretchyGlyphIndices.Bottom].Box.Width);
            int fillerCount = GetFillerCount(availSpace);

            result    = new Area[fillerCount + 1];
            result[0] = compoundGlyphs[StretchyGlyphIndices.Bottom].GetGlyph(fontHandle);
            for (int i = 1; i < result.Length; i++)
            {
                result[i] = filler;
            }

            return(result);
        }
示例#7
0
 /**
  * try to find a font in the list that matches the contents
  * of the formating context
  */
 private IFontHandle FindFont(float height, bool italic, int weight, string fontName)
 {
     for (int i = 0; i < fonts.Count; i++)
     {
         WeakReference w = (WeakReference)fonts[i];
         if (w.IsAlive)
         {
             IFontHandle f = (IFontHandle)w.Target;
             if (f.Equals(height, italic, weight, fontName))
             {
                 return(f);
             }
         }
         else
         {
             // reference is dead, so get rid of it
             fonts.RemoveAt(i--);
         }
     }
     // no font was found
     return(null);
 }
示例#8
0
        private Area[] StretchFillerOnly(IFontHandle fontHandle, BoundingBox box)
        {
            int fillerCount;

            Area[] result;
            Area   filler = compoundGlyphs[StretchyGlyphIndices.Filler].GetGlyph(fontHandle);

            if (orientation == StretchyOrientation.Vertical)
            {
                fillerCount = GetFillerCount(box.VerticalExtent);
            }
            else
            {
                fillerCount = GetFillerCount(box.HorizontalExtent);
            }

            result = new Area[fillerCount];
            for (int i = 0; i < result.Length; i++)
            {
                result[i] = filler;
            }
            return(result);
        }
示例#9
0
        /**
         * create a string area
         */
        public StringArea(IFormattingContext context, string content)
        {
            this.font    = context.GetFont();
            this.content = content;
            box          = BoundingBox.New();

            float left = 0, right = 0;

            for (int i = 0; i < content.Length; i++)
            {
                BoundingBox tmp = BoundingBox.New();
                context.MeasureGlyph(font, content[i], out tmp, out left, out right);
                box.Append(tmp);

                // left edge of first char
                if (i == 0)
                {
                    leftEdge = left;
                }
            }

            // right edge of last char
            rightEdge = right;
        }
示例#10
0
 /**
  * search through all of the simple glyphs for this character, and
  * return the first one that is just larger that the requested
  * size. return null if no mathching glyph is found
  */
 private Area GetSimpleArea(IFontHandle fontHandle, BoundingBox desiredSize)
 {
     if (orientation == StretchyOrientation.Vertical)
     {
         for (int i = 0; i < simpleGlyphs.Length; i++)
         {
             if (simpleGlyphs[i].Box.VerticalExtent >= desiredSize.VerticalExtent)
             {
                 return(simpleGlyphs[i].GetGlyph(fontHandle));
             }
         }
     }
     else
     {
         for (int i = 0; i < simpleGlyphs.Length; i++)
         {
             if (simpleGlyphs[i].Box.HorizontalExtent >= desiredSize.HorizontalExtent)
             {
                 return(simpleGlyphs[i].GetGlyph(fontHandle));
             }
         }
     }
     return(null);
 }
示例#11
0
		/**
		 * create a string area
		 */
		public StringArea(IFormattingContext context, string content)
		{
			this.font = context.GetFont();
			this.content = content;
			box = BoundingBox.New();

			float left = 0, right = 0;

			for(int i = 0; i < content.Length; i++)
			{
				BoundingBox tmp = BoundingBox.New();
				context.MeasureGlyph(font, content[i], out tmp, out left, out right);
				box.Append(tmp);

				// left edge of first char
				if(i == 0)
				{
					leftEdge = left;
				}
			}

			// right edge of last char
			rightEdge = right;
		}
示例#12
0
        /**
         * try to get a stretchy glyph 3 different ways, first try to find a
         * simple glyph that is just larger than the desired size. If we can
         * not find a simple glyph, we try to fit together a compound glyph
         * by repeating the filler area. If that fails, the last resort is
         * to just get the largest simple glyph.
         *
         * once a glyph is found, it is centered in the desiredSize region.
         */
        public Area GetStretchyArea(IFontHandle fontHandle, BoundingBox desiredSize, out float lineThickness)
        {
            Area result = null;

            if ((result = GetSimpleArea(fontHandle, desiredSize)) == null)
            {
                if ((result = GetCompoundArea(fontHandle, desiredSize)) == null)
                {
                    result = GetLargestSimpleArea(fontHandle);
                }
            }

            if (result != null)
            {
                lineThickness = GetLineThickness();
                result        = ShiftArea(result, desiredSize);
            }
            else
            {
                lineThickness = 0.0f;
            }

            return(result);
        }
示例#13
0
        private Area GetCompoundArea(IFontHandle fontHandle, BoundingBox desiredSize)
        {
            Area[] areas = null;
            if (compoundGlyphs[StretchyGlyphIndices.Bottom].Index >= 0)
            {
                if (compoundGlyphs[StretchyGlyphIndices.Top].Index >= 0)
                {
                    if (compoundGlyphs[StretchyGlyphIndices.Middle].Index >= 0)
                    {
                        areas = StretchBottomMiddleTop(fontHandle, desiredSize);
                    }
                    else
                    {
                        areas = StretchBottomTop(fontHandle, desiredSize);
                    }
                }
                else
                {
                    areas = StretchBottom(fontHandle, desiredSize);
                }
            }
            else
            {
                if (compoundGlyphs[StretchyGlyphIndices.Top].Index >= 0)
                {
                    areas = StretchTop(fontHandle, desiredSize);
                }
                else
                {
                    areas = StretchFillerOnly(fontHandle, desiredSize);
                }
            }

            return(orientation == StretchyOrientation.Vertical ?
                   (Area)(new VerticalCompoundGlyph(null, areas, 0)) : (Area)(new HorizontalCompoundGlyph(areas)));
        }
示例#14
0
		/**
		 * get a glyph area for this glyph.
		 * this searches through the glyphs list to see
		 * if an area has allready been created for the mathing
		 * set of glyph index and font, if none exists, a new 
		 * glyph area is created and cached via a weak reference.
		 */
    public Area GetArea(IFormattingContext context, IFontHandle fontHandle)
		{
			return new GlyphArea(context, fontHandle, GlyphIndex);
		}
示例#15
0
		private Area[] StretchFillerOnly(IFontHandle fontHandle, BoundingBox box)
		{
			int fillerCount;
			Area[] result;
			Area filler = compoundGlyphs[StretchyGlyphIndices.Filler].GetGlyph(fontHandle);

			if(orientation == StretchyOrientation.Vertical)
			{
				fillerCount = GetFillerCount(box.VerticalExtent);
			}
			else
			{
				fillerCount = GetFillerCount(box.HorizontalExtent);
			}

			result = new Area[fillerCount];
			for(int i = 0; i < result.Length; i++)
			{
				result[i] = filler;
			}
			return result;
		}
示例#16
0
		private Area[] StretchBottomMiddleTop(IFontHandle fontHandle, BoundingBox box)
		{
			float availSpace;
			Area[] result;
			Area filler = compoundGlyphs[StretchyGlyphIndices.Filler].GetGlyph(fontHandle);

			if(orientation == StretchyOrientation.Vertical)
			{
				availSpace = box.VerticalExtent - (
					compoundGlyphs[StretchyGlyphIndices.Bottom].Box.VerticalExtent +
					compoundGlyphs[StretchyGlyphIndices.Middle].Box.VerticalExtent +
					compoundGlyphs[StretchyGlyphIndices.Top].Box.VerticalExtent);
			}
			else
			{
				availSpace = box.Width - (
					compoundGlyphs[StretchyGlyphIndices.Bottom].Box.Width +
					compoundGlyphs[StretchyGlyphIndices.Middle].Box.Width +
					compoundGlyphs[StretchyGlyphIndices.Top].Box.Width);
			}

			// use halfFillerCount to prevent compiler optimizations 
			// from removing divide multiply by 2
			int halfFillerCount = GetFillerCount(availSpace) / 2;

			// bump the filler count if we are short of the availible space
			if(halfFillerCount * 2 * (orientation == StretchyOrientation.Vertical ?
				filler.BoundingBox.VerticalExtent : filler.BoundingBox.Width) < availSpace)
			{
				halfFillerCount++;
			}

			result = new Area[2 * halfFillerCount + 3];
			result[0] = compoundGlyphs[StretchyGlyphIndices.Bottom].GetGlyph(fontHandle);
			for(int i = 1; i < halfFillerCount + 1; i++)
			{
				result[i] = filler;
			}
			result[halfFillerCount + 1] = compoundGlyphs[StretchyGlyphIndices.Middle].GetGlyph(fontHandle);
			for(int i = halfFillerCount + 2; i < result.Length - 1; i++)
			{
				result[i] = filler;
			}
			result[result.Length - 1] = compoundGlyphs[StretchyGlyphIndices.Top].GetGlyph(fontHandle);

			return result;
		}
示例#17
0
		private Area[] StretchBottomTop(IFontHandle fontHandle, BoundingBox box)
		{
			float availSpace;
			int fillerCount;
			Area[] result;
			Area filler = compoundGlyphs[StretchyGlyphIndices.Filler].GetGlyph(fontHandle);

			if(orientation == StretchyOrientation.Vertical)
			{
				availSpace = box.VerticalExtent - (compoundGlyphs[StretchyGlyphIndices.Bottom].Box.VerticalExtent +
					compoundGlyphs[StretchyGlyphIndices.Top].Box.VerticalExtent);
			}
			else
			{
				availSpace = box.Width - (compoundGlyphs[StretchyGlyphIndices.Bottom].Box.Width +
					compoundGlyphs[StretchyGlyphIndices.Top].Box.Width);
			}

			fillerCount = GetFillerCount(availSpace);
			result = new Area[fillerCount + 2];
			result[0] = compoundGlyphs[StretchyGlyphIndices.Bottom].GetGlyph(fontHandle);
			for(int i = 1; i < result.Length - 1; i++)
			{
				result[i] = filler;
			}			
			result[result.Length - 1] = compoundGlyphs[StretchyGlyphIndices.Top].GetGlyph(fontHandle);

			Debug.WriteLine(String.Format("found bottom-top compound area, {0} filler areas", fillerCount));
			return result;
		}
示例#18
0
		private Area[] StretchTop(IFontHandle fontHandle, BoundingBox box)
		{
			Area[] result;
			Area filler = compoundGlyphs[StretchyGlyphIndices.Filler].GetGlyph(fontHandle);
			float availSpace = (orientation == StretchyOrientation.Vertical ?
				box.VerticalExtent - compoundGlyphs[StretchyGlyphIndices.Top].Box.VerticalExtent :
				box.Width = compoundGlyphs[StretchyGlyphIndices.Top].Box.Width);
			int fillerCount = GetFillerCount(availSpace);
			result = new Area[fillerCount + 1];
			for(int i = 0; i < result.Length - 1; i++)
			{
				result[i] = filler;
			}	
			result[result.Length - 1] = compoundGlyphs[StretchyGlyphIndices.Top].GetGlyph(fontHandle);	
			return result;
		}
示例#19
0
		/**
		* Sets the given font as the curent active font.
		* @param font a native font resource returned from GetFont
		* @return The previous font. This font MUST BE RESTORED when the new
		* font is no longer used
		*/


		public IFontHandle SetFont(IFontHandle font)
		{
      IFontHandle result = currentFont;
      currentFont = font;
      
      return result;
		}
示例#20
0
		private Area GetCompoundArea(IFontHandle fontHandle, BoundingBox desiredSize)
		{
			Area[] areas = null;
			if(compoundGlyphs[StretchyGlyphIndices.Bottom].Index >= 0)
			{
				if(compoundGlyphs[StretchyGlyphIndices.Top].Index >= 0)
				{
					if(compoundGlyphs[StretchyGlyphIndices.Middle].Index >= 0)
					{
                        areas = StretchBottomMiddleTop(fontHandle, desiredSize);
					}
					else
					{
						areas = StretchBottomTop(fontHandle, desiredSize);
                    }
				}
				else
				{
					areas = StretchBottom(fontHandle, desiredSize);
				}
			}
			else
			{
				if(compoundGlyphs[StretchyGlyphIndices.Top].Index >= 0)
				{
					areas = StretchTop(fontHandle, desiredSize);
				}
				else
				{
					areas = StretchFillerOnly(fontHandle, desiredSize);
				}
			}

            return orientation == StretchyOrientation.Vertical ?
				(Area)(new VerticalCompoundGlyph(null, areas, 0)) : (Area)(new HorizontalCompoundGlyph(areas));
			
		}
示例#21
0
		/**
		 * search through all of the simple glyphs for this character, and 
		 * return the first one that is just larger that the requested 
		 * size. return null if no mathching glyph is found
		 */
		private Area GetSimpleArea(IFontHandle fontHandle, BoundingBox desiredSize)
		{
			if(orientation == StretchyOrientation.Vertical)
			{
				for(int i = 0; i < simpleGlyphs.Length; i++)
				{
					if(simpleGlyphs[i].Box.VerticalExtent >= desiredSize.VerticalExtent)
					{
						return simpleGlyphs[i].GetGlyph(fontHandle);
					}
				}
			}
			else
			{
				for(int i = 0; i < simpleGlyphs.Length; i++)
				{
					if(simpleGlyphs[i].Box.HorizontalExtent >= desiredSize.HorizontalExtent)
					{
						return simpleGlyphs[i].GetGlyph(fontHandle);
					}
				}
			}
			return null;
		}
示例#22
0
		public Area GetGlyph(IFontHandle fontHandle)
		{
			Area result = null;
			if(glyphArea != null && glyphArea.IsAlive)
			{
				result = (Area)glyphArea.Target;
			}
			else
			{
				result = new GlyphArea(fontHandle, ref this);
				glyphArea = new WeakReference(result);
			}
			return result;
		}
示例#23
0
 /**
  * get a glyph area for this glyph.
  * this searches through the glyphs list to see
  * if an area has allready been created for the mathing
  * set of glyph index and font, if none exists, a new
  * glyph area is created and cached via a weak reference.
  */
 public Area GetArea(IFormattingContext context, IFontHandle fontHandle)
 {
     return(new GlyphArea(context, fontHandle, GlyphIndex));
 }
示例#24
0
        /**
         * get the dpi resolution of the current device
         */
        /*
         * public Scaled Dpi
         * {
         * get
         * {// TODO is this right?
         * return 72.0f;
         * }
         * }
         */


        public bool MeasureGlyph(IFontHandle font, ushort index, out BoundingBox box, out Scaled left, out Scaled right)
        {
            return(MeasureGlyph(_graphics, font, index, out box, out left, out right));
        }
示例#25
0
		public GlyphArea(IFormattingContext context, IFontHandle font, ushort index)
		{
			this.font = font;
			this.index = index;
			context.MeasureGlyph(font, index, out box, out leftEdge, out rightEdge);
		}
示例#26
0
		private Area GetLargestSimpleArea(IFontHandle fontHandle)
		{
			Area result = null;
			if(simpleGlyphs.Length > 0)
			{
				result = simpleGlyphs[simpleGlyphs.Length - 1].GetGlyph(fontHandle);
			}
			return result;
		}
示例#27
0
        /**
		 * try to get a stretchy glyph 3 different ways, first try to find a 
		 * simple glyph that is just larger than the desired size. If we can
		 * not find a simple glyph, we try to fit together a compound glyph
		 * by repeating the filler area. If that fails, the last resort is 
		 * to just get the largest simple glyph.
		 * 
		 * once a glyph is found, it is centered in the desiredSize region.
		 */
		public Area GetStretchyArea(IFontHandle fontHandle, BoundingBox desiredSize, out float lineThickness)
		{
			Area result = null;
			if((result = GetSimpleArea(fontHandle, desiredSize)) == null)
			{
				if((result = GetCompoundArea(fontHandle, desiredSize)) == null)
				{
					result = GetLargestSimpleArea(fontHandle);
				}
			}
			
			if(result != null)
			{
				lineThickness = GetLineThickness();
				result = ShiftArea(result, desiredSize);
			}
			else
			{
				lineThickness = 0.0f;
			}

			return result;
		}
示例#28
0
		/**
		* restores a font previously returned from SetFont
		*/
		public void RestoreFont(IFontHandle font)
		{
			// note, font resource are not destroyed here. font
			// resources are cached in the fonts list, and are 
			// destroyed when this object is told to clear them.

      currentFont = font;
     
     
    }
示例#29
0
 public GlyphArea(IFormattingContext context, IFontHandle font, ushort index)
 {
     this.font  = font;
     this.index = index;
     context.MeasureGlyph(font, index, out box, out leftEdge, out rightEdge);
 }
示例#30
0
    /**
		 * get the dpi resolution of the current device
		 */
    /*
    public Scaled Dpi
    {
      get
      {// TODO is this right?
      return 72.0f;
      }
    }
     */


    public  bool MeasureGlyph(IFontHandle font, ushort index, out BoundingBox box, out Scaled left, out Scaled right)
    {
      return MeasureGlyph(_graphics, font, index, out box, out left, out right);
    }