#region MIT License /*Copyright (c) 2012 Robert Rouhani SharpFont based on Tao.FreeType, Copyright (c) 2003-2007 Tao Framework Team Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.*/ #endregion using System; using System.Runtime.InteropServices; using SharpFont.Internal; namespace SharpFont { /// /// FreeType root glyph slot class structure. A glyph slot is a container where individual glyphs can be loaded, be /// they in outline or bitmap format. /// /// /// If is called with default flags (see ) /// the glyph image is loaded in the glyph slot in its native format (e.g., an outline glyph for TrueType and Type /// 1 formats). /// /// This image can later be converted into a bitmap by calling . This function finds the /// current renderer for the native image's format, then invokes it. /// /// The renderer is in charge of transforming the native image through the slot's face transformation fields, then /// converting it into a bitmap that is returned in ‘slot->bitmap’. /// /// Note that ‘slot->bitmap_left’ and ‘slot->bitmap_top’ are also used to specify the position of the bitmap /// relative to the current pen position (e.g., coordinates (0,0) on the baseline). Of course, ‘slot->format’ is /// also changed to . /// /// /// /// FT_Pos origin_x = 0; /// FT_Pos prev_rsb_delta = 0; /// /// /// for all glyphs do /// <compute kern between current and previous glyph and add it to /// `origin_x'> /// /// <load glyph with `FT_Load_Glyph'> /// /// if ( prev_rsb_delta - face->glyph->lsb_delta >= 32 ) /// origin_x -= 64; /// else if ( prev_rsb_delta - face->glyph->lsb_delta < -32 ) /// origin_x += 64; /// /// prev_rsb_delta = face->glyph->rsb_delta; /// /// <save glyph image, or render glyph, or ...> /// /// origin_x += face->glyph->advance.x; /// endfor /// /// public sealed class GlyphSlot { #region Fields private IntPtr reference; private GlyphSlotRec rec; private Face parentFace; private Library parentLibrary; #endregion #region Constructors internal GlyphSlot(IntPtr reference, Face parentFace, Library parentLibrary) { Reference = reference; this.parentFace = parentFace; this.parentLibrary = parentLibrary; } #endregion #region Properties /// /// Gets a handle to the FreeType library instance this slot belongs to. /// public Library Library { get { return parentLibrary; } } /// /// Gets a handle to the parent face object. /// public Face Face { get { return parentFace; } } /// /// Gets the next . In some cases (like some font tools), several glyph slots per face /// object can be a good thing. As this is rare, the glyph slots are listed through a direct, single-linked /// list using its ‘next’ field. /// public GlyphSlot Next { get { return new GlyphSlot(rec.next, parentFace, parentLibrary); } } /// /// Gets a typeless pointer which is unused by the FreeType library or any of its drivers. It can be used by /// client applications to link their own data to each glyph slot object. /// public Generic Generic { get { return new Generic(rec.generic); } } /// /// Gets the metrics of the last loaded glyph in the slot. The returned values depend on the last load flags /// (see the API function) and can be expressed either in 26.6 /// fractional pixels or font units. /// /// Note that even when the glyph image is transformed, the metrics are not. /// public GlyphMetrics Metrics { get { return new GlyphMetrics(rec.metrics); } } /// /// Gets the advance width of the unhinted glyph. Its value is expressed in 16.16 fractional pixels, unless /// is set when loading the glyph. This field can be important to perform /// correct WYSIWYG layout. Only relevant for outline glyphs. /// public int LinearHorizontalAdvance { get { return (int)rec.linearHoriAdvance; } } /// /// Gets the advance height of the unhinted glyph. Its value is expressed in 16.16 fractional pixels, unless /// is set when loading the glyph. This field can be important to perform /// correct WYSIWYG layout. Only relevant for outline glyphs. /// public int LinearVerticalAdvance { get { return (int)rec.linearVertAdvance; } } /// /// Gets the advance. This shorthand is, depending on , the transformed /// advance width for the glyph (in 26.6 fractional pixel format). As specified with /// , it uses either the ‘horiAdvance’ or the ‘vertAdvance’ value of /// ‘metrics’ field. /// public FTVector Advance { get { return rec.advance; } } /// /// Gets the glyph format. This field indicates the format of the image contained in the glyph slot. Typically /// , , or /// , but others are possible. /// [CLSCompliant(false)] public GlyphFormat Format { get { return rec.format; } } /// /// Gets the bitmap. This field is used as a bitmap descriptor when the slot format is /// . Note that the address and content of the bitmap buffer can change between /// calls of and a few other functions. /// public FTBitmap Bitmap { get { return new FTBitmap(rec.bitmap, parentLibrary); } } /// /// Gets the bitmap's left bearing expressed in integer pixels. Of course, this is only valid if the format is /// . /// public int BitmapLeft { get { return rec.bitmap_left; } } /// /// Gets the bitmap's top bearing expressed in integer pixels. Remember that this is the distance from the /// baseline to the top-most glyph scanline, upwards y coordinates being positive. /// public int BitmapTop { get { return rec.bitmap_top; } } /// /// Gets the outline descriptor for the current glyph image if its format is . /// Once a glyph is loaded, ‘outline’ can be transformed, distorted, embolded, etc. However, it must not be /// freed. /// public Outline Outline { get { return new Outline(rec.outline); } } /// /// Gets the number of subglyphs in a composite glyph. This field is only valid for the composite glyph format /// that should normally only be loaded with the flag. For now this is /// internal to FreeType. /// [CLSCompliant(false)] public uint SubglyphsCount { get { return rec.num_subglyphs; } } /// /// Gets an array of subglyph descriptors for composite glyphs. There are ‘num_subglyphs’ elements in there. /// Currently internal to FreeType. /// public SubGlyph[] Subglyphs { get { int count = (int)SubglyphsCount; if (count == 0) return null; SubGlyph[] subglyphs = new SubGlyph[count]; IntPtr array = rec.subglyphs; for (int i = 0; i < count; i++) { subglyphs[i] = new SubGlyph(array, IntPtr.Size * i); } return subglyphs; } } /// /// Gets the control data. Certain font drivers can also return the control data for a given glyph image (e.g. /// TrueType bytecode, Type 1 charstrings, etc.). This field is a pointer to such data. /// public IntPtr ControlData { get { return rec.control_data; } } /// /// Gets the length in bytes of the control data. /// public int ControlLength { get { return (int)rec.control_len; } } /// /// Gets the difference between hinted and unhinted left side bearing while autohinting is active. Zero /// otherwise. /// public int DeltaLsb { get { return (int)rec.lsb_delta; } } /// /// Gets the difference between hinted and unhinted right side bearing while autohinting is active. Zero /// otherwise. /// public int DeltaRsb { get { return (int)rec.rsb_delta; } } /// /// Gets other data. Really wicked formats can use this pointer to present their own glyph image to client /// applications. Note that the application needs to know about the image format. /// public IntPtr Other { get { return rec.other; } } internal IntPtr Reference { get { return reference; } set { reference = value; rec = PInvokeHelper.PtrToStructure(reference); } } #endregion #region Public Methods #region Base Interface /// /// Convert a given glyph image to a bitmap. It does so by inspecting the glyph image format, finding the /// relevant renderer, and invoking it. /// /// This is the render mode used to render the glyph image into a bitmap. public void RenderGlyph(RenderMode mode) { Error err = FT.FT_Render_Glyph(Reference, mode); if (err != Error.Ok) throw new FreeTypeException(err); } /// /// Retrieve a description of a given subglyph. Only use it if is /// ; an error is returned otherwise. /// /// /// The values of ‘*p_arg1’, ‘*p_arg2’, and ‘*p_transform’ must be interpreted depending on the flags returned /// in ‘*p_flags’. See the TrueType specification for details. /// /// /// The index of the subglyph. Must be less than . /// /// The glyph index of the subglyph. /// The subglyph flags, see . /// The subglyph's first argument (if any). /// The subglyph's second argument (if any). /// The subglyph transformation (if any). [CLSCompliant(false)] public void GetSubGlyphInfo(uint subIndex, out int index, out SubGlyphFlags flags, out int arg1, out int arg2, out FTMatrix transform) { Error err = FT.FT_Get_SubGlyph_Info(Reference, subIndex, out index, out flags, out arg1, out arg2, out transform); if (err != Error.Ok) throw new FreeTypeException(err); } #endregion #region Glyph Management /// /// A function used to extract a glyph image from a slot. Note that the created object must /// be released with . /// /// A handle to the glyph object. public Glyph GetGlyph() { IntPtr glyphRef; Error err = FT.FT_Get_Glyph(Reference, out glyphRef); if (err != Error.Ok) throw new FreeTypeException(err); return new Glyph(glyphRef, Library); } #endregion #region Bitmap Handling /// /// Make sure that a glyph slot owns ‘slot->bitmap’. /// /// /// This function is to be used in combination with . /// public void OwnBitmap() { Error err = FT.FT_GlyphSlot_Own_Bitmap(Reference); if (err != Error.Ok) throw new FreeTypeException(err); } #endregion #endregion } }